MOAB: Mesh Oriented datABase  (version 5.3.0)
pcomm_unit.cpp
Go to the documentation of this file.
00001 #include "moab/ParallelComm.hpp"
00002 #include "MBParallelConventions.h"
00003 #include "MBTagConventions.hpp"
00004 #include "moab/Core.hpp"
00005 #include "moab/MeshTopoUtil.hpp"
00006 #include "ReadParallel.hpp"
00007 #include "moab/FileOptions.hpp"
00008 #include "TestUtil.hpp"
00009 #include <algorithm>
00010 #include <vector>
00011 #include <set>
00012 #include <sstream>
00013 
00014 using namespace moab;
00015 
00016 #ifdef MOAB_HAVE_MPI
00017 #include "moab_mpi.h"
00018 #else
00019 #define MPI_COMM_WORLD 0
00020 #endif
00021 
00022 /** Test pack/unpack of vertices */
00023 void test_pack_vertices();
00024 /** Test pack/unpack of elements */
00025 void test_pack_elements();
00026 /** Test pack/unpack of higher-order elements */
00027 void test_pack_higher_order();
00028 /** Test pack/unpack of polygons & polyhedra */
00029 void test_pack_poly();
00030 /** Test pack/unpack of entity sets */
00031 void test_pack_sets_simple();
00032 /** Test pack/unpack of entity sets including implicit packing of set contents */
00033 void test_pack_set_contents();
00034 /** Test pack/unpack of entity sets containing entity sets */
00035 void test_pack_sets_of_sets();
00036 /** Test pack/unpack of set parent/child relations */
00037 void test_pack_set_parent_child();
00038 /** Test pack/unpack tag values*/
00039 void test_pack_tag_data_sparse();
00040 void test_pack_tag_data_dense();
00041 void test_pack_tag_data_default_value();
00042 /** Test pack/unpack tag values*/
00043 void test_pack_bit_tag_data();
00044 /** Test pack/unpack of variable length tag values*/
00045 void test_pack_variable_length_tag();
00046 /** Test pack/unpack tag values*/
00047 void test_pack_tag_handle_data();
00048 /** Test pack/unpack of shared entities in 2d*/
00049 void test_pack_shared_entities_2d();
00050 /** Test pack/unpack of shared entities in 3d*/
00051 void test_pack_shared_entities_3d();
00052 /** Test filter_pstatus function*/
00053 void test_filter_pstatus();
00054 /** Test creating a new ParallelComm instance in addition to an existing one*/
00055 void test_new_pcomm_instance();
00056 
00057 int rank = 0;
00058 
00059 int main( int argc, char* argv[] )
00060 {
00061 #ifdef MOAB_HAVE_MPI
00062     MPI_Init( &argc, &argv );
00063     MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00064 #endif
00065 
00066     int num_err = 0;
00067     num_err += RUN_TEST( test_pack_vertices );
00068     num_err += RUN_TEST( test_pack_elements );
00069     num_err += RUN_TEST( test_pack_higher_order );
00070     num_err += RUN_TEST( test_pack_poly );
00071     num_err += RUN_TEST( test_pack_sets_simple );
00072     num_err += RUN_TEST( test_pack_set_contents );
00073     num_err += RUN_TEST( test_pack_sets_of_sets );
00074     num_err += RUN_TEST( test_pack_set_parent_child );
00075     num_err += RUN_TEST( test_pack_tag_data_sparse );
00076     num_err += RUN_TEST( test_pack_tag_data_dense );
00077     num_err += RUN_TEST( test_pack_tag_data_default_value );
00078     // num_err += RUN_TEST( test_pack_bit_tag_data );
00079     num_err += RUN_TEST( test_pack_variable_length_tag );
00080     num_err += RUN_TEST( test_pack_tag_handle_data );
00081     num_err += RUN_TEST( test_pack_shared_entities_2d );
00082     num_err += RUN_TEST( test_pack_shared_entities_3d );
00083     num_err += RUN_TEST( test_filter_pstatus );
00084     num_err += RUN_TEST( test_new_pcomm_instance );
00085 
00086 #ifdef MOAB_HAVE_MPI
00087     MPI_Finalize();
00088 #endif
00089     return num_err;
00090 }
00091 
00092 /* Utility method: pack mesh data, clear moab instance, and unpack */
00093 void pack_unpack_noremoteh( Core& moab, Range& entities )
00094 {
00095     ErrorCode rval;
00096     if( entities.empty() )
00097     {
00098         rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00099     }
00100 
00101     ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
00102 
00103     // get the necessary vertices too
00104     Range tmp_range = entities.subset_by_type( MBENTITYSET );
00105     entities        = subtract( entities, tmp_range );
00106     rval            = moab.get_adjacencies( entities, 0, false, entities, Interface::UNION );CHECK_ERR( rval );
00107     entities.merge( tmp_range );
00108 
00109     ParallelComm::Buffer buff( ParallelComm::INITIAL_BUFF_SIZE );
00110     buff.reset_ptr( sizeof( int ) );
00111     rval = pcomm->pack_buffer( entities, false, true, false, -1, &buff );CHECK_ERR( rval );
00112     buff.set_stored_size();
00113 
00114     delete pcomm;
00115     moab.~Core();
00116 
00117     new( &moab ) Core();
00118     pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
00119 
00120     entities.clear();
00121     std::vector< std::vector< EntityHandle > > L1hloc, L1hrem;
00122     std::vector< std::vector< int > > L1p;
00123     std::vector< EntityHandle > L2hloc, L2hrem;
00124     std::vector< unsigned int > L2p;
00125     buff.reset_ptr( sizeof( int ) );
00126     std::vector< EntityHandle > entities_vec( entities.size() );
00127     std::copy( entities.begin(), entities.end(), entities_vec.begin() );
00128     rval = pcomm->unpack_buffer( buff.buff_ptr, false, -1, -1, L1hloc, L1hrem, L1p, L2hloc, L2hrem, L2p, entities_vec );CHECK_ERR( rval );
00129     std::copy( entities_vec.begin(), entities_vec.end(), range_inserter( entities ) );
00130 
00131     delete pcomm;
00132 }
00133 void pack_unpack_noremoteh( Core& moab )
00134 {
00135     Range empty;
00136     pack_unpack_noremoteh( moab, empty );
00137 }
00138 
00139 /* Utility method -- check expected sizes */
00140 void check_sizes( Interface& moab, int num_vtx, int num_edge, int num_tri, int num_quad, int num_polygon, int num_tet,
00141                   int num_pyr, int num_wedge, int num_knife, int num_hex, int num_polyhedron )
00142 {
00143     int count;
00144     ErrorCode rval;
00145 
00146     rval = moab.get_number_entities_by_type( 0, MBVERTEX, count );CHECK_ERR( rval );
00147     CHECK_EQUAL( num_vtx, count );
00148 
00149     rval = moab.get_number_entities_by_type( 0, MBEDGE, count );CHECK_ERR( rval );
00150     CHECK_EQUAL( num_edge, count );
00151 
00152     rval = moab.get_number_entities_by_type( 0, MBTRI, count );CHECK_ERR( rval );
00153     CHECK_EQUAL( num_tri, count );
00154 
00155     rval = moab.get_number_entities_by_type( 0, MBQUAD, count );CHECK_ERR( rval );
00156     CHECK_EQUAL( num_quad, count );
00157 
00158     rval = moab.get_number_entities_by_type( 0, MBPOLYGON, count );CHECK_ERR( rval );
00159     CHECK_EQUAL( num_polygon, count );
00160 
00161     rval = moab.get_number_entities_by_type( 0, MBTET, count );CHECK_ERR( rval );
00162     CHECK_EQUAL( num_tet, count );
00163 
00164     rval = moab.get_number_entities_by_type( 0, MBPYRAMID, count );CHECK_ERR( rval );
00165     CHECK_EQUAL( num_pyr, count );
00166 
00167     rval = moab.get_number_entities_by_type( 0, MBPRISM, count );CHECK_ERR( rval );
00168     CHECK_EQUAL( num_wedge, count );
00169 
00170     rval = moab.get_number_entities_by_type( 0, MBKNIFE, count );CHECK_ERR( rval );
00171     CHECK_EQUAL( num_knife, count );
00172 
00173     rval = moab.get_number_entities_by_type( 0, MBHEX, count );CHECK_ERR( rval );
00174     CHECK_EQUAL( num_hex, count );
00175 
00176     rval = moab.get_number_entities_by_type( 0, MBPOLYHEDRON, count );CHECK_ERR( rval );
00177     CHECK_EQUAL( num_polyhedron, count );
00178 }
00179 
00180 /* Create a simple mesh for use in tests */
00181 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z );
00182 void create_simple_grid( Interface& moab, unsigned xyz = 3 )
00183 {
00184     create_simple_grid( moab, xyz, xyz, xyz );
00185 }
00186 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z )
00187 {
00188     ErrorCode rval;
00189     EntityHandle* verts = new EntityHandle[x * y * z];
00190     for( unsigned k = 0; k < z; ++k )
00191         for( unsigned j = 0; j < y; ++j )
00192             for( unsigned i = 0; i < x; ++i )
00193             {
00194                 const double coords[3] = { static_cast< double >( i ), static_cast< double >( j ),
00195                                            static_cast< double >( k ) };
00196                 rval                   = moab.create_vertex( coords, verts[x * y * k + x * j + i] );CHECK_ERR( rval );
00197             }
00198 
00199     EntityHandle* elems = new EntityHandle[( x - 1 ) * ( y - 1 ) * ( z - 1 )];
00200     for( unsigned k = 0; k < ( z - 1 ); ++k )
00201         for( unsigned j = 0; j < ( y - 1 ); ++j )
00202             for( unsigned i = 0; i < ( x - 1 ); ++i )
00203             {
00204                 const size_t idx           = (size_t)i + (size_t)j * x + (size_t)k * x * y;
00205                 const EntityHandle conn[8] = {
00206                     verts[idx],         verts[idx + 1],         verts[idx + x + 1],         verts[idx + x],
00207                     verts[idx + x * y], verts[idx + x * y + 1], verts[idx + x * y + x + 1], verts[idx + x * y + x]
00208                 };
00209                 rval = moab.create_element( MBHEX, conn, 8, elems[( x - 1 ) * ( y - 1 ) * k + ( x - 1 ) * j + i] );CHECK_ERR( rval );
00210             }
00211     delete[] verts;
00212     delete[] elems;
00213 }
00214 
00215 ErrorCode create_patch( Interface* moab, Range& verts, Range& quads, unsigned int n, double* xyz, int* gids )
00216 {
00217     // create vertices/quads in square array
00218     ErrorCode result = moab->create_vertices( xyz, n * n, verts );
00219     if( MB_SUCCESS != result ) return result;
00220     std::vector< EntityHandle > connect;
00221     for( unsigned int j = 0; j < n - 1; j++ )
00222     {
00223         for( unsigned int i = 0; i < n - 1; i++ )
00224         {
00225             connect.push_back( verts[n * j + i] );
00226             connect.push_back( verts[n * j + i + 1] );
00227             connect.push_back( verts[n * ( j + 1 ) + i + 1] );
00228             connect.push_back( verts[n * ( j + 1 ) + i] );
00229         }
00230     }
00231 
00232     unsigned int nquads = ( n - 1 ) * ( n - 1 );
00233     for( unsigned int i = 0; i < nquads; i++ )
00234     {
00235         EntityHandle dum_quad;
00236         result = moab->create_element( MBQUAD, &connect[4 * i], 4, dum_quad );
00237         if( MB_SUCCESS != result ) return result;
00238         quads.insert( dum_quad );
00239     }
00240 
00241     // global ids
00242     Tag gid_tag = moab->globalId_tag();
00243     result      = moab->tag_set_data( gid_tag, verts, gids );
00244     if( MB_SUCCESS != result ) return result;
00245 
00246     return result;
00247 }
00248 
00249 ErrorCode create_shared_grid_2d( ParallelComm** pc, Range* verts, Range* quads )
00250 {
00251     //
00252     //        P2______
00253     //         /__/__/ /|P1
00254     //    y:  /__/__/ /||
00255     //     1  _____   ||/     _____  1
00256     //       |  |  |  |/|-1  |  |  |
00257     //    .5 |__|__|  ||/    |__|__| .5
00258     //       |P0|  |  |/-.5  |P3|  |
00259     //     0 |__|__| z:0     |__|__| 0
00260     //    x:-1 -.5  0       0  .5  1
00261     //
00262     // nodes:   P2
00263     //            18 16 14      P1
00264     //          17 15 13      14
00265     //         6  7  8     13 12
00266     //                   8 11 10
00267     //       6  7  8     5  9      8  23 24 P3
00268     //       3  4  5     2         5  21 22
00269     //   P0  0  1  2               2  19 20
00270 
00271     int gids[] = {
00272         0, 1,  2,  3,  4,  5,  6,  7,  8,   // P0
00273         2, 9,  10, 5,  11, 12, 8,  13, 14,  // P1
00274         6, 7,  8,  17, 15, 13, 18, 16, 14,  // P2
00275         2, 19, 20, 5,  21, 22, 8,  23, 24   // P3
00276     };
00277     double xyz[] = {
00278         -1.0, 0.0, 0.0,  -0.5, 0.0, 0.0,  0.0,  0.0, 0.0,  -1.0, 0.5, 0.0,  -0.5, 0.5, 0.0,  0.0, 0.5, 0.0,
00279         -1.0, 1.0, 0.0,  -0.5, 1.0, 0.0,  0.0,  1.0, 0.0,                                                     // n0-8
00280         0.0,  0.0, -0.5, 0.0,  0.0, -1.0, 0.0,  0.5, -0.5, 0.0,  0.5, -1.0, 0.0,  1.0, -0.5, 0.0, 1.0, -1.0,  // n9-14
00281         -0.5, 1.0, -0.5, -0.5, 1.0, -1.0, -1.0, 1.0, -0.5, -1.0, 1.0, -1.0,                                   // n15-18
00282         0.5,  0.0, 0.0,  1.0,  0.0, 0.0,  0.5,  0.5, 0.0,  1.0,  0.5, 0.0,  0.5,  1.0, 0.0,  1.0, 1.0, 0.0,   // n19-24
00283     };
00284     double xyztmp[27];
00285 
00286     // create the test mesh above
00287     for( unsigned int i = 0; i < 4; i++ )
00288     {
00289         for( unsigned int j = 0; j < 9; j++ )
00290         {
00291             xyztmp[3 * j]     = xyz[3 * gids[9 * i + j]];
00292             xyztmp[3 * j + 1] = xyz[3 * gids[9 * i + j] + 1];
00293             xyztmp[3 * j + 2] = xyz[3 * gids[9 * i + j] + 2];
00294         }
00295 
00296         create_patch( pc[i]->get_moab(), verts[i], quads[i], 3, xyztmp, &gids[9 * i] );
00297     }
00298 
00299     ErrorCode rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 2 );CHECK_ERR( rval );
00300 
00301     return rval;
00302 }
00303 
00304 ErrorCode create_shared_grid_3d( ParallelComm** pc, Range* verts, Range* hexes )
00305 {
00306     //
00307     //   4 _____   _____
00308     //    |  |  | |  |  |
00309     //   3|__|__| |__|__|          GIDS               HANDLES
00310     //    |P1|  | |P2|  |
00311     //    |__|__| |__|__|   20 21 22   22 23 24      7  8  9    7  8  9
00312     //    2 ___________     15 16 17   17 18 19      4  5  6    4  5  6
00313     //     |  |  |  |  |    10 11 12   12 13 14      1  2  3    1  2  3
00314     // /  1|__|__|__|__|
00315     // |   |  |P0|  |  |     10 11 12 13 14           10 11 12 13 14
00316     // J  0|__|__|__|__|      5  6  7  8  9            5  6  7  8  9
00317     // I-> 0  1  2  3  4      0  1  2  3  4            0  1  2  3  4
00318     //
00319     //  P3 - k = 2..4
00320 
00321     // create structured meshes
00322     // ijkmin[p][ijk], ijkmax[p][ijk]
00323 #define P 4
00324     int ijkmin[P][3] = { { 0, 0, 0 }, { 0, 2, 0 }, { 2, 2, 0 }, { 0, 0, 2 } };
00325     int ijkmax[P][3] = { { 4, 2, 2 }, { 2, 4, 2 }, { 4, 4, 2 }, { 4, 4, 4 } };
00326 
00327     int nijk[P][3];
00328     int NIJK[3] = { 0, 0, 0 };
00329 #define INDEXG( i, j, k ) ( (k)*NIJK[1] * NIJK[0] + (j)*NIJK[0] + ( i ) )
00330 #define INDEXL( i, j, k ) \
00331     ( ( (k)-ijkmin[p][2] ) * nijk[p][1] * nijk[p][0] + ( (j)-ijkmin[p][1] ) * nijk[p][0] + ( (i)-ijkmin[p][0] ) )
00332 
00333     int p, i, j, k;
00334     for( p = 0; p < P; p++ )
00335     {
00336         for( i = 0; i < 3; i++ )
00337         {
00338             nijk[p][i] = ijkmax[p][i] - ijkmin[p][i] + 1;
00339             NIJK[i]    = std::max( NIJK[i], nijk[p][i] );
00340         }
00341     }
00342 
00343     std::vector< int > gids;
00344     std::vector< double > xyz;
00345     ErrorCode rval;
00346     Tag gid_tag;
00347 
00348     for( p = 0; p < P; p++ )
00349     {
00350         gid_tag = pc[p]->get_moab()->globalId_tag();
00351 
00352         // make vertices
00353         int nverts = nijk[p][0] * nijk[p][1] * nijk[p][2];
00354         xyz.resize( 3 * nverts );
00355         gids.resize( nverts );
00356 
00357         // set vertex gids
00358         int nv = 0;
00359         for( k = ijkmin[p][2]; k <= ijkmax[p][2]; k++ )
00360             for( j = ijkmin[p][1]; j <= ijkmax[p][1]; j++ )
00361                 for( i = ijkmin[p][0]; i <= ijkmax[p][0]; i++ )
00362                 {
00363                     // xyz
00364                     xyz[3 * nv]     = i;
00365                     xyz[3 * nv + 1] = j;
00366                     xyz[3 * nv + 2] = k;
00367 
00368                     // gid
00369                     gids[nv++] = INDEXG( i, j, k );
00370                 }
00371 
00372         rval = pc[p]->get_moab()->create_vertices( &xyz[0], nverts, verts[p] );CHECK_ERR( rval );
00373 
00374         rval = pc[p]->get_moab()->tag_set_data( gid_tag, verts[p], &gids[0] );
00375         if( MB_SUCCESS != rval ) return rval;
00376 
00377         // make elements
00378         nv = 0;
00379         EntityHandle connect[8], dum_hex;
00380         for( k = ijkmin[p][2]; k < ijkmax[p][2]; k++ )
00381             for( j = ijkmin[p][1]; j < ijkmax[p][1]; j++ )
00382                 for( i = ijkmin[p][0]; i < ijkmax[p][0]; i++ )
00383                 {
00384                     // gid
00385                     connect[0] = verts[p][INDEXL( i, j, k )];
00386                     connect[1] = verts[p][INDEXL( i + 1, j, k )];
00387                     connect[2] = verts[p][INDEXL( i + 1, j + 1, k )];
00388                     connect[3] = verts[p][INDEXL( i, j + 1, k )];
00389                     connect[4] = verts[p][INDEXL( i, j, k + 1 )];
00390                     connect[5] = verts[p][INDEXL( i + 1, j, k + 1 )];
00391                     connect[6] = verts[p][INDEXL( i + 1, j + 1, k + 1 )];
00392                     connect[7] = verts[p][INDEXL( i, j + 1, k + 1 )];
00393                     rval       = pc[p]->get_moab()->create_element( MBHEX, connect, 8, dum_hex );
00394                     hexes[p].insert( dum_hex );
00395                     gids[nv++] = INDEXG( i, j, k );
00396                 }
00397         rval = pc[p]->get_moab()->tag_set_data( gid_tag, hexes[p], &gids[0] );
00398         if( MB_SUCCESS != rval ) return rval;
00399 
00400         std::ostringstream fname;
00401         fname << "tmp" << p << "." << rank << ".h5m";
00402         rval = pc[p]->get_moab()->write_file( fname.str().c_str() );
00403         if( MB_SUCCESS != rval ) return rval;
00404     }
00405     rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 3 );CHECK_ERR( rval );
00406     return rval;
00407 }
00408 
00409 void test_pack_vertices()
00410 {
00411     Core moab;
00412     ErrorCode rval;
00413     Range verts;
00414 
00415     const size_t num_verts             = 4;
00416     const double coords[3 * num_verts] = {
00417         -0.5, -1. / 3, 0.0, 0.5, -1. / 3, 0.0, 0.0, 2. / 3, 0.0, 0.0, 0.0, 0.745356
00418     };
00419 
00420     rval = moab.create_vertices( coords, num_verts, verts );CHECK_ERR( rval );
00421 
00422     pack_unpack_noremoteh( moab, verts );
00423     CHECK_EQUAL( num_verts, verts.size() );
00424 
00425     double coords2[3 * num_verts];
00426     rval = moab.get_coords( verts, coords2 );CHECK_ERR( rval );
00427 
00428     std::vector< bool > seen( num_verts, false );
00429     for( unsigned i = 0; i < num_verts; ++i )
00430     {
00431         unsigned j;
00432         for( j = 0; j < num_verts; ++j )
00433             if( coords[3 * j] == coords2[3 * i] && coords[3 * j + 1] == coords2[3 * i + 1] &&
00434                 coords[3 * j + 2] == coords2[3 * i + 2] )
00435                 break;
00436         CHECK( j < num_verts );
00437         CHECK( !seen[j] );
00438         seen[j] = true;
00439     }
00440 }
00441 
00442 void test_pack_elements()
00443 {
00444     Core moab;
00445     ErrorCode rval;
00446     Range elems;
00447 
00448     // define some vertices
00449     const size_t num_verts = 12;
00450     EntityHandle verts[num_verts];
00451     const double hex_corners[3 * num_verts] = { -1, -1, -1, 1,  -1, -1, 1,  1,  -1, -1, 1,  -1, -1, -1, 0, 1,  -1, 0,
00452                                                 1,  1,  0,  -1, 1,  0,  -1, -1, 1,  1,  -1, 1,  1,  1,  1, -1, 1,  1 };
00453     for( size_t i = 0; i < num_verts; ++i )
00454     {
00455         rval = moab.create_vertex( hex_corners + 3 * i, verts[i] );CHECK_ERR( rval );
00456     }
00457 
00458     // define two adjacent hexes
00459     const size_t num_hex = 2;
00460     EntityHandle hexes[num_hex];
00461     rval = moab.create_element( MBHEX, verts, 8, hexes[0] );CHECK_ERR( rval );
00462     elems.insert( hexes[0] );
00463     rval = moab.create_element( MBHEX, verts + 4, 8, hexes[1] );CHECK_ERR( rval );
00464     elems.insert( hexes[1] );
00465 
00466     // define a single quad on the adjacent sides of the hexes
00467     const size_t num_quad = 1;
00468     EntityHandle quad;
00469     rval = moab.create_element( MBQUAD, verts + 4, 4, quad );CHECK_ERR( rval );
00470     elems.insert( quad );
00471 
00472     // define a decomposition of the first hex into 5 tets
00473     const size_t num_tet = 5;
00474     EntityHandle tets[num_tet];
00475     EntityHandle tet_conn[num_tet][4] = { { verts[0], verts[1], verts[3], verts[4] },
00476                                           { verts[1], verts[2], verts[3], verts[6] },
00477                                           { verts[1], verts[3], verts[4], verts[6] },
00478                                           { verts[4], verts[6], verts[5], verts[1] },
00479                                           { verts[7], verts[6], verts[4], verts[3] } };
00480     rval                              = moab.create_element( MBTET, tet_conn[0], 4, tets[0] );CHECK_ERR( rval );
00481     elems.insert( tets[0] );
00482     rval = moab.create_element( MBTET, tet_conn[1], 4, tets[1] );CHECK_ERR( rval );
00483     elems.insert( tets[1] );
00484     rval = moab.create_element( MBTET, tet_conn[2], 4, tets[2] );CHECK_ERR( rval );
00485     elems.insert( tets[2] );
00486     rval = moab.create_element( MBTET, tet_conn[3], 4, tets[3] );CHECK_ERR( rval );
00487     elems.insert( tets[3] );
00488     rval = moab.create_element( MBTET, tet_conn[4], 4, tets[4] );CHECK_ERR( rval );
00489     elems.insert( tets[4] );
00490 
00491     // define the 4 shared faces of the above tets as tris
00492     // (the faces of the 3rd tet)
00493     const size_t num_tri = 4;
00494     EntityHandle tris[num_tri];
00495     EntityHandle tri_conn[num_tri][3] = { { verts[3], verts[1], verts[4] },
00496                                           { verts[1], verts[6], verts[4] },
00497                                           { verts[1], verts[3], verts[6] },
00498                                           { verts[3], verts[4], verts[6] } };
00499     rval                              = moab.create_element( MBTRI, tri_conn[0], 3, tris[0] );CHECK_ERR( rval );
00500     elems.insert( tris[0] );
00501     rval = moab.create_element( MBTRI, tri_conn[1], 3, tris[1] );CHECK_ERR( rval );
00502     elems.insert( tris[1] );
00503     rval = moab.create_element( MBTRI, tri_conn[2], 3, tris[2] );CHECK_ERR( rval );
00504     elems.insert( tris[2] );
00505     rval = moab.create_element( MBTRI, tri_conn[3], 3, tris[3] );CHECK_ERR( rval );
00506     elems.insert( tris[3] );
00507 
00508     // define a decomposition of the second hex into two wedges
00509     const size_t num_wedge = 2;
00510     EntityHandle wedges[num_wedge];
00511     EntityHandle wedge_conn[num_wedge][6] = { { verts[4], verts[5], verts[7], verts[8], verts[9], verts[11] },
00512                                               { verts[5], verts[6], verts[7], verts[9], verts[10], verts[11] } };
00513     rval                                  = moab.create_element( MBPRISM, wedge_conn[0], 6, wedges[0] );CHECK_ERR( rval );
00514     elems.insert( wedges[0] );
00515     rval = moab.create_element( MBPRISM, wedge_conn[1], 6, wedges[1] );CHECK_ERR( rval );
00516     elems.insert( wedges[1] );
00517 
00518     // define a pyramid
00519     EntityHandle pyr;
00520     rval = moab.create_element( MBPYRAMID, verts, 5, pyr );CHECK_ERR( rval );
00521     elems.insert( pyr );
00522 
00523     // pack and unpack mesh
00524     pack_unpack_noremoteh( moab, elems );
00525 
00526     // check_counts
00527     check_sizes( moab, num_verts, 0, num_tri, num_quad, 0, num_tet, 1, num_wedge, 0, num_hex, 0 );
00528 
00529     // get connectivity for two hexes and a quad
00530     Range range;
00531     const EntityHandle *conn1, *conn2, *conn3;
00532     int len1, len2, len3;
00533     rval = moab.get_entities_by_type( 0, MBHEX, range );CHECK_ERR( rval );
00534     CHECK_EQUAL( num_hex, range.size() );
00535     rval = moab.get_connectivity( range.front(), conn1, len1, true );CHECK_ERR( rval );
00536     CHECK_EQUAL( 8, len1 );
00537     rval = moab.get_connectivity( range.back(), conn2, len2, true );CHECK_ERR( rval );
00538     CHECK_EQUAL( 8, len2 );
00539     range.clear();
00540     rval = moab.get_entities_by_type( 0, MBQUAD, range );CHECK_ERR( rval );
00541     CHECK_EQUAL( num_quad, range.size() );
00542     rval = moab.get_connectivity( range.front(), conn3, len3, true );CHECK_ERR( rval );
00543     CHECK_EQUAL( 4, len3 );
00544 
00545     // Check if hexes are reversed
00546     if( conn1[0] == conn2[4] ) { std::swap( conn1, conn2 ); }
00547 
00548     // Check consistant connectivity between hexes
00549     CHECK_EQUAL( conn1[4], conn2[0] );
00550     CHECK_EQUAL( conn1[5], conn2[1] );
00551     CHECK_EQUAL( conn1[6], conn2[2] );
00552     CHECK_EQUAL( conn1[7], conn2[3] );
00553     // Check connectivity of quad on shared face
00554     CHECK_EQUAL( conn1[4], conn3[0] );
00555     CHECK_EQUAL( conn1[5], conn3[1] );
00556     CHECK_EQUAL( conn1[6], conn3[2] );
00557     CHECK_EQUAL( conn1[7], conn3[3] );
00558     // Check coordinates
00559     const EntityHandle combined[12] = { conn1[0], conn1[1], conn1[2], conn1[3], conn3[0], conn3[1],
00560                                         conn3[2], conn3[3], conn2[4], conn2[5], conn2[6], conn2[7] };
00561     double coords[36];
00562     rval = moab.get_coords( combined, 12, coords );CHECK_ERR( rval );
00563     for( int i = 0; i < 36; ++i )
00564     {
00565         CHECK_REAL_EQUAL( hex_corners[i], coords[i], 1e-12 );
00566     }
00567 }
00568 
00569 void test_pack_higher_order()
00570 {
00571     Core moab;
00572     ErrorCode rval;
00573     Range elems;
00574 
00575     // define coordinates for a pyramid decomposed
00576     // into two 10-node tets
00577     const size_t num_vert             = 14;
00578     const double coords[3 * num_vert] = { -1, -1, 0,   0,   -1, 0,  1,   -1, 0,  1,  0,  0,   1,  1,
00579                                           0,  0,  1,   0,   -1, 1,  0,   -1, 0,  0,  0,  0,   0,  0,
00580                                           0,  1,  -.5, -.5, .5, .5, -.5, .5, .5, .5, .5, -.5, .5, .5 };
00581     EntityHandle verts[num_vert];
00582     for( size_t i = 0; i < num_vert; ++i )
00583     {
00584         rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval );
00585     }
00586 
00587     // define two tets
00588     const size_t num_tet         = 2;
00589     EntityHandle tet_conn[2][10] = {
00590         { verts[0], verts[4], verts[9], verts[2], verts[8], verts[12], verts[10], verts[1], verts[3], verts[11] },
00591         { verts[0], verts[9], verts[4], verts[6], verts[10], verts[12], verts[8], verts[7], verts[13], verts[5] }
00592     };
00593 
00594     EntityHandle tets[num_tet];
00595     rval = moab.create_element( MBTET, tet_conn[0], 10, tets[0] );CHECK_ERR( rval );
00596     elems.insert( tets[0] );
00597     rval = moab.create_element( MBTET, tet_conn[1], 10, tets[1] );CHECK_ERR( rval );
00598     elems.insert( tets[1] );
00599 
00600     // define interior tri face
00601     const size_t num_tri     = 1;
00602     EntityHandle tri_conn[6] = { verts[0], verts[4], verts[9], verts[8], verts[12], verts[10] };
00603     EntityHandle tri;
00604     rval = moab.create_element( MBTRI, tri_conn, 6, tri );CHECK_ERR( rval );
00605     elems.insert( tri );
00606 
00607     // pack and unpack mesh
00608     pack_unpack_noremoteh( moab, elems );
00609 
00610     // check_counts
00611     check_sizes( moab, num_vert, 0, num_tri, 0, 0, num_tet, 0, 0, 0, 0, 0 );
00612 
00613     // get connectivity for two tets and a tri
00614     Range range;
00615     const EntityHandle *conn1, *conn2, *conn3;
00616     int len1, len2, len3;
00617     rval = moab.get_entities_by_type( 0, MBTET, range );CHECK_ERR( rval );
00618     CHECK_EQUAL( num_tet, range.size() );
00619     rval = moab.get_connectivity( range.front(), conn1, len1, false );CHECK_ERR( rval );
00620     CHECK_EQUAL( 10, len1 );
00621     rval = moab.get_connectivity( range.back(), conn2, len2, false );CHECK_ERR( rval );
00622     CHECK_EQUAL( 10, len2 );
00623     range.clear();
00624     rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval );
00625     CHECK_EQUAL( num_tri, range.size() );
00626     rval = moab.get_connectivity( range.front(), conn3, len3, false );CHECK_ERR( rval );
00627     CHECK_EQUAL( 6, len3 );
00628 
00629     // The first face of one of the tets is in the
00630     // same order as the tri.
00631     if( conn3[1] != conn1[1] ) std::swap( conn1, conn2 );
00632 
00633     // check consistant connectivity for face shared by tets
00634     CHECK_EQUAL( conn1[0], conn2[0] );
00635     CHECK_EQUAL( conn1[1], conn2[2] );
00636     CHECK_EQUAL( conn1[2], conn2[1] );
00637     CHECK_EQUAL( conn1[4], conn2[6] );
00638     CHECK_EQUAL( conn1[5], conn2[5] );
00639     CHECK_EQUAL( conn1[6], conn2[4] );
00640     // check connsistant connectivity between tet face and tri
00641     CHECK_EQUAL( conn1[0], conn3[0] );
00642     CHECK_EQUAL( conn1[1], conn3[1] );
00643     CHECK_EQUAL( conn1[2], conn3[2] );
00644     CHECK_EQUAL( conn1[4], conn3[3] );
00645     CHECK_EQUAL( conn1[5], conn3[4] );
00646     CHECK_EQUAL( conn1[6], conn3[5] );
00647 
00648     // order vertex handles corresponding to original coordinate list
00649     const EntityHandle combined[num_vert] = { conn1[0], conn1[7], conn1[3], conn1[8], conn1[1], conn2[9], conn2[3],
00650                                               conn2[7], conn1[4], conn1[2], conn1[6], conn1[9], conn1[5], conn2[8] };
00651     double coords2[3 * num_vert];
00652     rval = moab.get_coords( combined, num_vert, coords2 );CHECK_ERR( rval );
00653 
00654     // check vertex coordinates
00655     for( int i = 0; i < 36; ++i )
00656     {
00657         CHECK_REAL_EQUAL( coords[i], coords2[i], 1e-12 );
00658     }
00659 }
00660 
00661 void test_pack_poly()
00662 {
00663     Core moab;
00664     ErrorCode rval;
00665     Range elems;
00666 
00667     // define a pyramid w/ a octagonal base
00668     const double a                    = 0.5;
00669     const double b                    = 1 + sqrt( 2.0 ) / 2.0;
00670     const size_t num_vert             = 9;
00671     const double coords[3 * num_vert] = { -a, -b, 0, a, -b, 0, b, -a, 0,  b, a, 0, a, b,
00672                                           0,  -a, b, 0, -b, a, 0, -b, -a, 0, 0, 0, 1 };
00673     EntityHandle verts[num_vert];
00674     for( size_t i = 0; i < num_vert; ++i )
00675     {
00676         rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval );
00677     }
00678 
00679     // define octagonal base
00680     const size_t num_polygon = 1;
00681     EntityHandle octagon;
00682     rval = moab.create_element( MBPOLYGON, verts, 8, octagon );CHECK_ERR( rval );
00683 
00684     // define triangular sides
00685     const size_t num_tri = num_vert - 1;
00686     EntityHandle tri[num_tri];
00687     for( size_t i = 0; i < num_tri; ++i )
00688     {
00689         const EntityHandle conn[3] = { verts[i], verts[( i + 1 ) % num_tri], verts[num_tri] };
00690         rval                       = moab.create_element( MBTRI, conn, 3, tri[i] );CHECK_ERR( rval );
00691     }
00692 
00693     // define the octagon-based pyramid
00694     const size_t num_polyhedron = 1;
00695     EntityHandle polyhedron;
00696     EntityHandle all_faces[num_vert];
00697     all_faces[0] = octagon;
00698     std::copy( tri, tri + num_tri, all_faces + 1 );
00699     rval = moab.create_element( MBPOLYHEDRON, all_faces, num_vert, polyhedron );CHECK_ERR( rval );
00700 
00701     // pack and unpack the mesh
00702     elems.clear();
00703     elems.insert( polyhedron );
00704     elems.insert( octagon );
00705     std::copy( tri, tri + num_tri, range_inserter( elems ) );
00706     pack_unpack_noremoteh( moab, elems );
00707 
00708     // check counts
00709     check_sizes( moab, num_vert, 0, num_tri, 0, num_polygon, 0, 0, 0, 0, 0, num_polyhedron );
00710 
00711     // get entities
00712     Range range;
00713     rval = moab.get_entities_by_type( 0, MBPOLYHEDRON, range );CHECK_ERR( rval );
00714     CHECK_EQUAL( num_polyhedron, range.size() );
00715     polyhedron = range.front();
00716 
00717     range.clear();
00718     rval = moab.get_entities_by_type( 0, MBPOLYGON, range );CHECK_ERR( rval );
00719     CHECK_EQUAL( num_polygon, range.size() );
00720     octagon = range.front();
00721 
00722     range.clear();
00723     rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval );
00724     CHECK_EQUAL( num_tri, range.size() );
00725 
00726     // check coords of octagon vertices
00727     const EntityHandle* oct_conn;
00728     int eight = 0;
00729     rval      = moab.get_connectivity( octagon, oct_conn, eight );CHECK_ERR( rval );
00730     CHECK_EQUAL( 8, eight );
00731     double oct_coords[3 * 8];
00732     rval = moab.get_coords( oct_conn, 8, oct_coords );CHECK_ERR( rval );
00733     for( int i = 0; i < 3 * 8; ++i )
00734     {
00735         CHECK_REAL_EQUAL( coords[i], oct_coords[i], 1e-12 );
00736     }
00737 
00738     // check faces of polyhedron
00739     std::vector< EntityHandle > volconn;
00740     rval = moab.get_connectivity( &polyhedron, 1, volconn );CHECK_ERR( rval );
00741     CHECK_EQUAL( num_tri + 1, volconn.size() );
00742     CHECK_EQUAL( volconn[0], octagon );
00743     for( Range::iterator i = range.begin(); i != range.end(); ++i )
00744     {
00745         CHECK( std::find( volconn.begin(), volconn.end(), *i ) != volconn.end() );
00746     }
00747 }
00748 
00749 void test_pack_sets_simple()
00750 {
00751     Core moab;
00752     ErrorCode rval;
00753     create_simple_grid( moab, 3 );
00754 
00755     // delete any existing sets
00756     Range sets;
00757     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00758     if( !sets.empty() )
00759     {
00760         rval = moab.delete_entities( sets );CHECK_ERR( rval );
00761     }
00762 
00763     // get all entities
00764     Range entities;
00765     rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00766     // expect 8 elements and 27 vertices
00767     CHECK_EQUAL( 35, (int)entities.size() );
00768     CHECK_EQUAL( 27u, entities.num_of_type( MBVERTEX ) );
00769     CHECK_EQUAL( 8u, entities.num_of_type( MBHEX ) );
00770 
00771     // create five sets:
00772     // 1) one with all the elements and vertices,
00773     // 2) one with half of the elements,
00774     // 3) one with the other half of the elements,
00775     // 4) one with a single vertex,
00776     // 5) an empty set,
00777     EntityHandle all_set, half1_set, half2_set, vertex_set, empty_set;
00778     const unsigned int all_opt = MESHSET_SET | MESHSET_TRACK_OWNER, half1_opt = MESHSET_SET, half2_opt = MESHSET_SET,
00779                        vertex_opt = MESHSET_ORDERED, empty_opt = MESHSET_ORDERED | MESHSET_TRACK_OWNER;
00780     rval = moab.create_meshset( all_opt, all_set );CHECK_ERR( rval );
00781     entities.insert( all_set );
00782     rval = moab.create_meshset( half1_opt, half1_set );CHECK_ERR( rval );
00783     entities.insert( half1_set );
00784     rval = moab.create_meshset( half2_opt, half2_set );CHECK_ERR( rval );
00785     entities.insert( half2_set );
00786     rval = moab.create_meshset( vertex_opt, vertex_set );CHECK_ERR( rval );
00787     entities.insert( vertex_set );
00788     rval = moab.create_meshset( empty_opt, empty_set );CHECK_ERR( rval );
00789     entities.insert( empty_set );
00790 
00791     Range elems, verts, half;
00792     rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00793     rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
00794 
00795     rval = moab.add_entities( all_set, verts );CHECK_ERR( rval );
00796     rval = moab.add_entities( all_set, elems );CHECK_ERR( rval );
00797     half.merge( elems.begin(), elems.begin() += elems.size() / 2 );
00798     rval = moab.add_entities( half1_set, half );CHECK_ERR( rval );
00799     half.clear();
00800     half.merge( elems.begin() += elems.size() / 2, elems.end() );
00801     rval = moab.add_entities( half2_set, half );CHECK_ERR( rval );
00802     EntityHandle vert = verts.front();
00803     rval              = moab.add_entities( vertex_set, &vert, 1 );CHECK_ERR( rval );
00804 
00805     // do pack and unpack
00806     pack_unpack_noremoteh( moab, entities );
00807 
00808     // get entities by type
00809     verts.clear();
00810     rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00811     elems.clear();
00812     rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
00813     sets.clear();
00814     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00815 
00816     CHECK_EQUAL( 27, (int)verts.size() );
00817     CHECK_EQUAL( 8, (int)elems.size() );
00818     CHECK_EQUAL( 5, (int)sets.size() );
00819 
00820     // guess which is which
00821     empty_set = all_set = vertex_set = half1_set = half2_set = 0;
00822     for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
00823     {
00824         int num_vtx, num_elem;
00825         rval = moab.get_number_entities_by_type( *i, MBVERTEX, num_vtx );CHECK_ERR( rval );
00826         rval = moab.get_number_entities_by_type( *i, MBHEX, num_elem );CHECK_ERR( rval );
00827         if( num_vtx == 0 )
00828         {
00829             if( num_elem == 0 )
00830             {
00831                 CHECK_EQUAL( (EntityHandle)0, empty_set );
00832                 empty_set = *i;
00833             }
00834             else if( !half1_set )
00835             {
00836                 half1_set = *i;
00837             }
00838             else
00839             {
00840                 CHECK_EQUAL( (EntityHandle)0, half2_set );
00841                 half2_set = *i;
00842             }
00843         }
00844         else if( num_vtx == 1 )
00845         {
00846             CHECK_EQUAL( 0, num_elem );
00847             CHECK_EQUAL( (EntityHandle)0, vertex_set );
00848             vertex_set = *i;
00849         }
00850         else
00851         {
00852             CHECK_EQUAL( 8, num_elem );
00853             CHECK_EQUAL( 27, num_vtx );
00854             CHECK_EQUAL( (EntityHandle)0, all_set );
00855             all_set = *i;
00856         }
00857     }
00858 
00859     // check set options
00860     unsigned opt;
00861     rval = moab.get_meshset_options( all_set, opt );CHECK_ERR( rval );
00862     CHECK_EQUAL( all_opt, opt );
00863     rval = moab.get_meshset_options( half1_set, opt );CHECK_ERR( rval );
00864     CHECK_EQUAL( half1_opt, opt );
00865     rval = moab.get_meshset_options( half2_set, opt );CHECK_ERR( rval );
00866     CHECK_EQUAL( half2_opt, opt );
00867     rval = moab.get_meshset_options( vertex_set, opt );CHECK_ERR( rval );
00868     CHECK_EQUAL( vertex_opt, opt );
00869     rval = moab.get_meshset_options( empty_set, opt );CHECK_ERR( rval );
00870     CHECK_EQUAL( empty_opt, opt );
00871 }
00872 
00873 void test_pack_set_contents()
00874 {
00875     Core moab;
00876     ErrorCode rval;
00877     create_simple_grid( moab, 3 );
00878 
00879     // delete any existing sets
00880     Range sets;
00881     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00882     if( !sets.empty() )
00883     {
00884         rval = moab.delete_entities( sets );CHECK_ERR( rval );
00885     }
00886 
00887     // get all vertices
00888     Range vertices;
00889     rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
00890     CHECK_EQUAL( 27, (int)vertices.size() );
00891     // create meshset containing vertices
00892     EntityHandle set;
00893     rval = moab.create_meshset( MESHSET_SET, set );CHECK_ERR( rval );
00894     rval = moab.add_entities( set, vertices );CHECK_ERR( rval );
00895 
00896     // pack and unpack range containing only set handle.
00897     // Will fail unless we also pass in set contents explicitly
00898     Range entities( vertices );
00899     entities.insert( set );
00900     pack_unpack_noremoteh( moab, entities );
00901 
00902     // expect single set in mesh
00903     entities.clear();
00904     rval = moab.get_entities_by_type( 0, MBENTITYSET, entities );CHECK_ERR( rval );
00905     CHECK_EQUAL( 1, (int)entities.size() );
00906     set = entities.front();
00907 
00908     // expect 27 vertices in mesh
00909     vertices.clear();
00910     rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
00911     CHECK_EQUAL( 27, (int)vertices.size() );
00912 
00913     // expect set to contain all 27 vertices
00914     vertices.clear();
00915     rval = moab.get_entities_by_type( set, MBVERTEX, vertices );CHECK_ERR( rval );
00916     CHECK_EQUAL( 27, (int)vertices.size() );
00917 }
00918 
00919 void test_pack_sets_of_sets()
00920 {
00921     Core moab;
00922     ErrorCode rval;
00923 
00924     // delete any existing sets
00925     Range sets;
00926     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00927     if( !sets.empty() )
00928     {
00929         rval = moab.delete_entities( sets );CHECK_ERR( rval );
00930     }
00931 
00932     // create three sets such that set2 contains set1, and set3 contains
00933     // both set1 and set2
00934     EntityHandle set1, set2, set3;
00935     sets.clear();
00936     rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval );
00937     sets.insert( set1 );
00938     rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval );
00939     rval = moab.add_entities( set2, sets );CHECK_ERR( rval );
00940     sets.insert( set2 );
00941     rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval );
00942     rval = moab.add_entities( set3, sets );CHECK_ERR( rval );
00943     sets.insert( set3 );
00944 
00945     // pack and unpack
00946     pack_unpack_noremoteh( moab, sets );
00947 
00948     // get sets
00949     sets.clear();
00950     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00951     CHECK_EQUAL( 3, (int)sets.size() );
00952 
00953     // figure out which is which
00954     set1 = set2 = set3 = 0;
00955     for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
00956     {
00957         int count;
00958         rval = moab.get_number_entities_by_type( *i, MBENTITYSET, count );CHECK_ERR( rval );
00959         CHECK( count >= 0 && count <= 2 );
00960         switch( count )
00961         {
00962             case 0:
00963                 CHECK_EQUAL( (EntityHandle)0, set1 );
00964                 set1 = *i;
00965                 break;
00966             case 1:
00967                 CHECK_EQUAL( (EntityHandle)0, set2 );
00968                 set2 = *i;
00969                 break;
00970             case 2:
00971                 CHECK_EQUAL( (EntityHandle)0, set3 );
00972                 set3 = *i;
00973                 break;
00974         }
00975     }
00976 
00977     // check that set2 contains set1
00978     sets.clear();
00979     rval = moab.get_entities_by_type( set2, MBENTITYSET, sets );CHECK_ERR( rval );
00980     CHECK_EQUAL( 1, (int)sets.size() );
00981     CHECK_EQUAL( set1, sets.front() );
00982 
00983     // check that set3 contains set1 and set2
00984     sets.clear();
00985     rval = moab.get_entities_by_type( set3, MBENTITYSET, sets );CHECK_ERR( rval );
00986     CHECK_EQUAL( 2, (int)sets.size() );
00987     if( sets.front() == set1 ) { CHECK_EQUAL( set2, sets.back() ); }
00988     else
00989     {
00990         CHECK_EQUAL( set2, sets.front() );
00991         CHECK_EQUAL( set1, sets.back() );
00992     }
00993 }
00994 
00995 void test_pack_set_parent_child()
00996 {
00997     Core moab;
00998     ErrorCode rval;
00999 
01000     // delete any existing sets
01001     Range sets;
01002     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
01003     if( !sets.empty() )
01004     {
01005         rval = moab.delete_entities( sets );CHECK_ERR( rval );
01006     }
01007 
01008     // create three sets such that set3 has a child link to
01009     // set1, set2 has a parent link to set1, and such that set3 and
01010     // set2 are parent and child, respectively.
01011     EntityHandle set1, set2, set3;
01012     sets.clear();
01013     rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval );
01014     sets.insert( set1 );
01015     rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval );
01016     sets.insert( set2 );
01017     rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval );
01018     sets.insert( set3 );
01019 
01020     rval = moab.add_child_meshset( set3, set1 );CHECK_ERR( rval );
01021     rval = moab.add_parent_meshset( set2, set1 );CHECK_ERR( rval );
01022     rval = moab.add_parent_child( set3, set2 );CHECK_ERR( rval );
01023 
01024     // make sure everything is valid before doing the pack/unpack
01025     int count;
01026     rval = moab.num_child_meshsets( set1, &count );
01027     CHECK( MB_SUCCESS == rval && 0 == count );
01028     rval = moab.num_child_meshsets( set2, &count );
01029     CHECK( MB_SUCCESS == rval && 0 == count );
01030     rval = moab.num_child_meshsets( set3, &count );
01031     CHECK( MB_SUCCESS == rval && 2 == count );
01032     rval = moab.num_parent_meshsets( set1, &count );
01033     CHECK( MB_SUCCESS == rval && 0 == count );
01034     rval = moab.num_parent_meshsets( set2, &count );
01035     CHECK( MB_SUCCESS == rval && 2 == count );
01036     rval = moab.num_parent_meshsets( set3, &count );
01037     CHECK( MB_SUCCESS == rval && 0 == count );
01038 
01039     // pack and unpack
01040     pack_unpack_noremoteh( moab, sets );
01041 
01042     // get sets
01043     sets.clear();
01044     rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
01045     CHECK_EQUAL( 3, (int)sets.size() );
01046 
01047     // look for a set with two child links (set3)
01048     set1 = set2 = set3 = 0;
01049     for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
01050     {
01051         int mcount;
01052         rval = moab.num_child_meshsets( *i, &mcount );CHECK_ERR( rval );
01053         if( mcount == 2 )
01054         {
01055             set3 = *i;
01056             break;
01057         }
01058     }
01059     CHECK( 0 != set3 );
01060 
01061     // check set relations
01062     std::vector< EntityHandle > parents, children;
01063     rval = moab.get_child_meshsets( set3, children );CHECK_ERR( rval );
01064     CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, children.size() );
01065     set1 = children[0];
01066     set2 = children[1];
01067     rval = moab.get_parent_meshsets( set1, parents );CHECK_ERR( rval );
01068     CHECK( parents.empty() );
01069     children.clear();
01070     rval = moab.get_parent_meshsets( set1, children );CHECK_ERR( rval );
01071     CHECK( children.empty() );
01072     rval = moab.get_parent_meshsets( set2, parents );CHECK_ERR( rval );
01073     CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, parents.size() );
01074     CHECK_EQUAL( set1, parents[0] );
01075     CHECK_EQUAL( set3, parents[1] );
01076 }
01077 
01078 void test_pack_tag_data_sparse()
01079 {
01080     Range::iterator i;
01081     int size;
01082     DataType type;
01083     TagType storage;
01084     Core moab;
01085     Interface& mb = moab;
01086     ErrorCode rval;
01087 
01088     create_simple_grid( mb, 3 );
01089     Range elems;
01090     rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
01091     CHECK( !elems.empty() );
01092 
01093     // Define a sparse tag containing two integers.  For every other element
01094     // in the mesh, set the tag value to the floor of the x and y
01095     // coordinates of the first vertex in the elements connectivity list.
01096     const char sparse_2_int_tag_name[] = "test tag 1";
01097     Tag sparse_2_int_tag;
01098     rval =
01099         mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag, MB_TAG_SPARSE | MB_TAG_CREAT );CHECK_ERR( rval );
01100     bool skip = false;
01101     for( i = elems.begin(); i != elems.end(); ++i, skip = !skip )
01102     {
01103         if( skip ) continue;
01104 
01105         const EntityHandle* conn = 0;
01106         int len;
01107         rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
01108         double coords[3];
01109         rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval );
01110         const int data[2] = { (int)coords[0], (int)coords[1] };
01111         rval              = mb.tag_set_data( sparse_2_int_tag, &*i, 1, data );CHECK_ERR( rval );
01112     }
01113 
01114     // pack and unpack
01115     Range ents;
01116     pack_unpack_noremoteh( moab, ents );
01117     elems.clear();
01118     rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
01119 
01120     // check tag meta for sparse_2_int_tag
01121     rval = mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag );CHECK_ERR( rval );
01122     rval = mb.tag_get_length( sparse_2_int_tag, size );CHECK_ERR( rval );
01123     CHECK_EQUAL( 2, size );
01124     rval = mb.tag_get_type( sparse_2_int_tag, storage );CHECK_ERR( rval );
01125     CHECK_EQUAL( MB_TAG_SPARSE, storage );
01126     rval = mb.tag_get_data_type( sparse_2_int_tag, type );CHECK_ERR( rval );
01127     CHECK_EQUAL( MB_TYPE_INTEGER, type );
01128     int intdata[2];
01129     rval = mb.tag_get_default_value( sparse_2_int_tag, intdata );
01130     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01131 
01132     // check tag data for sparse_2_int_tag
01133     Range tagged;
01134     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &sparse_2_int_tag, 0, 1, tagged );CHECK_ERR( rval );
01135     CHECK_EQUAL( ( elems.size() + 1 ) / 2, tagged.size() );
01136     for( i = tagged.begin(); i != tagged.end(); ++i )
01137     {
01138         rval = mb.tag_get_data( sparse_2_int_tag, &*i, 1, intdata );CHECK_ERR( rval );
01139 
01140         const EntityHandle* conn = 0;
01141         int len;
01142         rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
01143         double coords[3];
01144         rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval );
01145 
01146         CHECK_EQUAL( (int)( coords[0] ), intdata[0] );
01147         CHECK_EQUAL( (int)( coords[1] ), intdata[1] );
01148     }
01149 }
01150 
01151 void test_pack_tag_data_dense()
01152 {
01153     Range::iterator i;
01154     int size;
01155     DataType type;
01156     TagType storage;
01157     Core moab;
01158     Interface& mb = moab;
01159     ErrorCode rval;
01160 
01161     create_simple_grid( mb, 3 );
01162     Range verts;
01163     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01164     CHECK( !verts.empty() );
01165 
01166     // Define a dense tag containing a single double-precision floating
01167     // point value.  For each vertex, store the distance from the origin
01168     // in this tag.
01169     const char dense_1_double_tag_name[] = "test tag 2";
01170     Tag dense_1_double_tag;
01171     rval =
01172         mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
01173     for( i = verts.begin(); i != verts.end(); ++i )
01174     {
01175         double coords[3];
01176         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01177         double val = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] );
01178         rval       = mb.tag_set_data( dense_1_double_tag, &*i, 1, &val );CHECK_ERR( rval );
01179     }
01180 
01181     // pack and unpack
01182     Range ents;
01183     pack_unpack_noremoteh( moab, ents );
01184     verts.clear();
01185     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01186 
01187     // check tag meta for dense_1_double_tag
01188     rval = mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag );CHECK_ERR( rval );
01189     rval = mb.tag_get_length( dense_1_double_tag, size );CHECK_ERR( rval );
01190     CHECK_EQUAL( 1, size );
01191     rval = mb.tag_get_type( dense_1_double_tag, storage );CHECK_ERR( rval );
01192     CHECK_EQUAL( MB_TAG_DENSE, storage );
01193     rval = mb.tag_get_data_type( dense_1_double_tag, type );CHECK_ERR( rval );
01194     CHECK_EQUAL( MB_TYPE_DOUBLE, type );
01195     double dval;
01196     rval = mb.tag_get_default_value( dense_1_double_tag, &dval );
01197     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01198 
01199     // check tag data for dense_1_double_tag
01200     for( i = verts.begin(); i != verts.end(); ++i )
01201     {
01202         double coords[3];
01203         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01204 
01205         const double expected = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] );
01206         rval                  = mb.tag_get_data( dense_1_double_tag, &*i, 1, &dval );CHECK_ERR( rval );
01207         CHECK_REAL_EQUAL( expected, dval, 1e-6 );
01208     }
01209 }
01210 
01211 void test_pack_tag_data_default_value()
01212 {
01213     Range::iterator i;
01214     int size;
01215     DataType type;
01216     TagType storage;
01217     Core moab;
01218     Interface& mb = moab;
01219     ErrorCode rval;
01220 
01221     create_simple_grid( mb, 3 );
01222     Range verts, elems, sets;
01223     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01224     CHECK( !verts.empty() );
01225     rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
01226     CHECK( !elems.empty() );
01227 
01228     // Define a dense, opaque tag with a default value of "DEFLT".
01229     // Set the tag on one element, one vertex,and one set to "TAGGD".
01230     const char dense_5_opaque_tag_name[] =
01231         "This is intentionally a very long tag name in an attempt to test for an arbitrary "
01232         "limitations on tag name length.";
01233     Tag dense_5_opaque_tag;
01234     rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag,
01235                               MB_TAG_DENSE | MB_TAG_EXCL, "DEFLT" );CHECK_ERR( rval );
01236     EntityHandle set;
01237     rval = mb.create_meshset( MESHSET_SET, set );CHECK_ERR( rval );
01238     const EntityHandle handles[3] = { verts.front(), elems.front(), set };
01239     const char data[]             = "TAGGDTAGGDTAGGD";
01240     rval                          = mb.tag_set_data( dense_5_opaque_tag, handles, 3, data );CHECK_ERR( rval );
01241 
01242     // pack and unpack
01243     Range ents;
01244     pack_unpack_noremoteh( moab, ents );
01245     elems.clear();
01246     verts.clear();
01247     sets.clear();
01248     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01249     rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
01250     rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
01251 
01252     // check tag meta for dense_5_opaque_tag
01253     rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag );CHECK_ERR( rval );
01254     rval = mb.tag_get_length( dense_5_opaque_tag, size );CHECK_ERR( rval );
01255     CHECK_EQUAL( 5, size );
01256     rval = mb.tag_get_type( dense_5_opaque_tag, storage );CHECK_ERR( rval );
01257     CHECK_EQUAL( MB_TAG_DENSE, storage );
01258     rval = mb.tag_get_data_type( dense_5_opaque_tag, type );CHECK_ERR( rval );
01259     CHECK_EQUAL( MB_TYPE_OPAQUE, type );
01260     char odata[6];
01261     odata[5] = '\0';
01262     rval     = mb.tag_get_default_value( dense_5_opaque_tag, odata );CHECK_ERR( rval );
01263     CHECK_EQUAL( std::string( "DEFLT" ), std::string( odata ) );
01264 
01265     // count number of each type with tag set to non-default
01266     int vcount = 0, ecount = 0, scount = 0;
01267     for( i = verts.begin(); i != verts.end(); ++i )
01268     {
01269         rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
01270         if( strcmp( odata, "DEFLT" ) != 0 )
01271         {
01272             CHECK_EQUAL( std::string( "TAGGD" ), std::string( odata ) );
01273             ++vcount;
01274         }
01275     }
01276     CHECK_EQUAL( 1, vcount );
01277     for( i = elems.begin(); i != elems.end(); ++i )
01278     {
01279         rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
01280         if( strcmp( odata, "DEFLT" ) != 0 )
01281         {
01282             CHECK_EQUAL( "TAGGD", odata );
01283             ++ecount;
01284         }
01285     }
01286     CHECK_EQUAL( 1, ecount );
01287     for( i = sets.begin(); i != sets.end(); ++i )
01288     {
01289         rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
01290         if( strcmp( odata, "DEFLT" ) != 0 )
01291         {
01292             CHECK_EQUAL( "TAGGD", odata );
01293             ++scount;
01294         }
01295     }
01296     CHECK_EQUAL( 1, scount );
01297 }
01298 
01299 void test_pack_bit_tag_data()
01300 {
01301     Range::iterator i;
01302     Core moab;
01303     Interface& mb = moab;
01304     ErrorCode rval;
01305 
01306     // create some mesh
01307     create_simple_grid( mb, 3 );
01308     Range verts;
01309     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01310     CHECK( !verts.empty() );
01311 
01312     // Create a bit tag
01313     const char tag_name[] = "test bit";
01314     Tag tag;
01315     rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag, MB_TAG_EXCL );CHECK_ERR( rval );
01316 
01317     // Set bits to 1 unless cooresponding coordinate of
01318     // vertex is zero.
01319     for( i = verts.begin(); i != verts.end(); ++i )
01320     {
01321         double coords[3];
01322         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01323 
01324         unsigned char data = 0;
01325         for( int j = 0; j < 3; ++j )
01326             if( fabs( coords[j] ) > 1e-6 ) data |= ( 1 << j );
01327         rval = mb.tag_set_data( tag, &*i, 1, &data );CHECK_ERR( rval );
01328     }
01329 
01330     // pack and unpack
01331     Range ents;
01332     pack_unpack_noremoteh( moab, ents );
01333     verts.clear();
01334     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01335 
01336     // check tag meta
01337     rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag );CHECK_ERR( rval );
01338 
01339     int size;
01340     rval = mb.tag_get_length( tag, size );CHECK_ERR( rval );
01341     CHECK_EQUAL( 3, size );
01342 
01343     TagType storage;
01344     rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
01345     CHECK_EQUAL( MB_TAG_BIT, storage );
01346 
01347     DataType type;
01348     rval = mb.tag_get_data_type( tag, type );
01349     CHECK_EQUAL( MB_TYPE_BIT, type );
01350 
01351     // check tag values
01352     for( i = verts.begin(); i != verts.end(); ++i )
01353     {
01354         double coords[3];
01355         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01356 
01357         unsigned char expected = 0;
01358         for( int j = 0; j < 3; ++j )
01359             if( fabs( coords[j] ) > 1e-6 ) expected |= ( 1 << j );
01360 
01361         unsigned char data = (unsigned char)0xFF;
01362         rval               = mb.tag_get_data( tag, &*i, 1, &data );CHECK_ERR( rval );
01363 
01364         CHECK_EQUAL( (int)expected, (int)data );
01365     }
01366 }
01367 
01368 void test_pack_variable_length_tag()
01369 {
01370     Range::iterator i;
01371     Core moab;
01372     Interface& mb = moab;
01373     ErrorCode rval;
01374 
01375     // create some mesh
01376     create_simple_grid( mb, 3 );
01377     Range verts;
01378     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01379     CHECK( !verts.empty() );
01380 
01381     // create a variable-length tag
01382     const char* tag_name               = "var_int_tag";
01383     const int defval_size              = 5;
01384     const int default_val[defval_size] = { 0xBEEF, 0xFEED, 0xDEAD, 0xBAD, 0xBEAD };
01385     Tag tag;
01386     rval = mb.tag_get_handle( tag_name, defval_size, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL,
01387                               default_val );CHECK_ERR( rval );
01388 
01389     // for each vertex, store in the tag an integer between 1 and 3,
01390     // followed by the floor of the cooresponding number of vertex
01391     // coordinates, beginning with x.
01392     for( i = verts.begin(); i != verts.end(); ++i )
01393     {
01394         double coords[3];
01395         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01396 
01397         const int num_coord      = 1 + *i % 3;
01398         const int data_size      = num_coord + 1;
01399         const int data[4]        = { num_coord, (int)coords[0], (int)coords[1], (int)coords[2] };
01400         const void* data_ptrs[1] = { data };
01401         rval                     = mb.tag_set_by_ptr( tag, &*i, 1, data_ptrs, &data_size );CHECK_ERR( rval );
01402     }
01403 
01404     // pack and unpack
01405     pack_unpack_noremoteh( moab );
01406     verts.clear();
01407     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01408 
01409     // check tag meta
01410     rval = mb.tag_get_handle( tag_name, 0, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
01411 
01412     int size;
01413     rval = mb.tag_get_length( tag, size );
01414     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
01415 
01416     TagType storage;
01417     rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
01418     CHECK_EQUAL( MB_TAG_DENSE, storage );
01419 
01420     DataType type;
01421     rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval );
01422     CHECK_EQUAL( MB_TYPE_INTEGER, type );
01423 
01424     const void* defval_ptr;
01425     rval = mb.tag_get_default_value( tag, defval_ptr, size );CHECK_ERR( rval );
01426     CHECK_EQUAL( defval_size, size );
01427     const int* defval_arr = reinterpret_cast< const int* >( defval_ptr );
01428     for( int j = 0; j < size; ++j )
01429         CHECK_EQUAL( default_val[j], defval_arr[j] );
01430 
01431     // check tag values
01432     for( i = verts.begin(); i != verts.end(); ++i )
01433     {
01434         double coords[3];
01435         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
01436 
01437         int tsize;
01438         const void* valptr;
01439         rval = mb.tag_get_by_ptr( tag, &*i, 1, &valptr, &tsize );CHECK_ERR( rval );
01440         CHECK( tsize > 1 );
01441         CHECK( tsize <= 4 );
01442 
01443         const int* valarr = reinterpret_cast< const int* >( valptr );
01444         CHECK( valarr[0] >= 1 );
01445         CHECK( valarr[0] <= 3 );
01446         for( int j = 0; j < valarr[0]; ++j )
01447         {
01448             CHECK_EQUAL( (int)( coords[j] ), valarr[j + 1] );
01449         }
01450     }
01451 }
01452 
01453 void test_pack_tag_handle_data()
01454 {
01455     Range::iterator i;
01456     Core moab;
01457     Interface& mb = moab;
01458     ErrorCode rval;
01459 
01460     // create some mesh
01461     create_simple_grid( mb, 3 );
01462     Range verts, elems;
01463     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01464     CHECK( !verts.empty() );
01465     rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
01466     CHECK( !elems.empty() );
01467 
01468     // create a tag
01469     const char* tag_name        = "entity tag";
01470     EntityHandle default_val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
01471     Tag tag;
01472     rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag, MB_TAG_SPARSE | MB_TAG_EXCL, &default_val );CHECK_ERR( rval );
01473 
01474     // Store on each vertex the handles of the adjacent hexes, padded
01475     // with NULL handles.
01476     EntityHandle tagdata[8 * 8];
01477     for( i = elems.begin(); i != elems.end(); ++i )
01478     {
01479         const EntityHandle* conn;
01480         int len;
01481         rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
01482         CHECK_EQUAL( 8, len );
01483 
01484         rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval );
01485 
01486         for( int j = 0; j < 8; ++j )
01487         {
01488             EntityHandle* vdata = tagdata + 8 * j;
01489             int idx             = 0;
01490             while( vdata[idx] )
01491             {
01492                 ++idx;
01493                 CHECK( idx < 8 );
01494             }
01495             vdata[idx] = *i;
01496         }
01497 
01498         rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval );
01499     }
01500 
01501     // pack and unpack
01502     pack_unpack_noremoteh( moab );
01503     verts.clear();
01504     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01505 
01506     // check tag meta
01507     rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag );CHECK_ERR( rval );
01508 
01509     int size;
01510     rval = mb.tag_get_length( tag, size );CHECK_ERR( rval );
01511     CHECK_EQUAL( 8, size );
01512 
01513     TagType storage;
01514     rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
01515     CHECK_EQUAL( MB_TAG_SPARSE, storage );
01516 
01517     DataType type;
01518     rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval );
01519     CHECK_EQUAL( MB_TYPE_HANDLE, type );
01520 
01521     rval = mb.tag_get_default_value( tag, tagdata );CHECK_ERR( rval );
01522     for( int j = 0; j < 8; ++j )
01523     {
01524         CHECK_EQUAL( (EntityHandle)0, tagdata[j] );
01525     }
01526 
01527     // check tag values
01528     for( i = elems.begin(); i != elems.end(); ++i )
01529     {
01530         const EntityHandle* conn;
01531         int len;
01532         rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
01533         CHECK_EQUAL( 8, len );
01534 
01535         rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval );
01536 
01537         for( int j = 0; j < 8; ++j )
01538         {
01539             EntityHandle* vdata = tagdata + 8 * j;
01540             int idx             = 0;
01541             while( vdata[idx] != *i )
01542             {
01543                 ++idx;
01544                 CHECK( idx < 8 );
01545             }
01546             vdata[idx] = 0;
01547         }
01548 
01549         rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval );
01550     }
01551 
01552     for( i = verts.begin(); i != verts.end(); ++i )
01553     {
01554         rval = mb.tag_get_data( tag, &*i, 1, tagdata );CHECK_ERR( rval );
01555         for( int j = 0; j < 8; ++j )
01556         {
01557             CHECK_EQUAL( (EntityHandle)0, tagdata[j] );
01558         }
01559     }
01560 }
01561 
01562 ErrorCode get_entities( Interface* mb, std::vector< EntityHandle >& ent_verts, int verts_per_entity, int dim,
01563                         Range& ents )
01564 {
01565     assert( !( ent_verts.size() % verts_per_entity ) );
01566     unsigned int num_ents = ent_verts.size() / verts_per_entity;
01567     Range dum_ents;
01568     ErrorCode result;
01569     for( unsigned int i = 0; i < num_ents; i++ )
01570     {
01571         result = mb->get_adjacencies( &ent_verts[verts_per_entity * i], verts_per_entity, dim, true, dum_ents );CHECK_ERR( result );
01572         assert( dum_ents.size() == 1 );
01573         ents.merge( dum_ents );
01574         dum_ents.clear();
01575     }
01576     return MB_SUCCESS;
01577 }
01578 
01579 void test_pack_shared_entities_2d()
01580 {
01581     Core moab[4];
01582     ParallelComm* pc[4];
01583     for( unsigned int i = 0; i < 4; i++ )
01584     {
01585         pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD );
01586         pc[i]->set_rank( i );
01587     }
01588 
01589     Range verts[4], quads[4];
01590     ErrorCode rval = create_shared_grid_2d( pc, verts, quads );CHECK_ERR( rval );
01591 
01592     // moab[0].list_entities(0,1);
01593 
01594     // exchange interface cells
01595     rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval );
01596 
01597     // now 1 layer of hex ghosts
01598     rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 0, true );CHECK_ERR( rval );
01599 
01600     // now 1 layer of hex ghosts w/ edges
01601     rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 1, true );CHECK_ERR( rval );
01602 
01603     for( unsigned int i = 0; i < 4; i++ )
01604         delete pc[i];
01605 }
01606 
01607 void test_pack_shared_entities_3d()
01608 {
01609     Core moab[4];
01610     ParallelComm* pc[4];
01611     for( unsigned int i = 0; i < 4; i++ )
01612     {
01613         pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD );
01614         pc[i]->set_rank( i );
01615         for( unsigned int j = 0; j < 4; j++ )
01616         {
01617             if( j == i )
01618                 continue;
01619             else
01620                 pc[i]->get_buffers( j );
01621         }
01622     }
01623 
01624     Range verts[4], hexes[4];
01625     ErrorCode rval = create_shared_grid_3d( pc, verts, hexes );CHECK_ERR( rval );
01626 
01627     // exchange interface cells
01628     rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval );
01629 
01630     // now 1 layer of hex ghosts
01631     rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 0, true );CHECK_ERR( rval );
01632 
01633     // now 1 layer of hex ghosts w/ faces, edges
01634     rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 3, true );CHECK_ERR( rval );
01635 
01636     for( unsigned int i = 0; i < 4; i++ )
01637         delete pc[i];
01638 }
01639 
01640 void test_filter_pstatus()
01641 {
01642     Range::iterator i;
01643     Core moab;
01644     Interface& mb = moab;
01645     ErrorCode rval;
01646 
01647     // create some mesh
01648     create_simple_grid( mb, 3 );
01649     std::vector< EntityHandle > verts;
01650     Range dum_vertsr, vertsr;
01651     rval = mb.get_entities_by_type( 0, MBVERTEX, dum_vertsr );CHECK_ERR( rval );
01652     vertsr.insert( dum_vertsr[0], dum_vertsr[8] );
01653     for( int k = 0; k < 9; k++ )
01654         verts.push_back( vertsr[k] );
01655 
01656     CHECK( !verts.empty() );
01657 
01658     ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
01659 
01660     std::vector< int > procs( 70, -1 );
01661     for( int k = 0; k < 6; k++ )
01662         procs[k] = k;
01663 
01664     std::vector< unsigned char > pvals( verts.size(), 0 );
01665     // interface, owned
01666     pvals[0] = ( PSTATUS_INTERFACE | PSTATUS_SHARED );  // p0
01667     rval     = moab.tag_set_data( pcomm->sharedp_tag(), &verts[0], 1, &procs[0] );CHECK_ERR( rval );
01668     // interface, not owned
01669     pvals[1] = ( PSTATUS_NOT_OWNED | PSTATUS_INTERFACE | PSTATUS_SHARED );  // p1
01670     rval     = moab.tag_set_data( pcomm->sharedp_tag(), &verts[1], 1, &procs[1] );CHECK_ERR( rval );
01671     // interface, multi-shared, owned
01672     pvals[2] = ( PSTATUS_INTERFACE | PSTATUS_SHARED | PSTATUS_MULTISHARED );  // p0, p1
01673     rval     = moab.tag_set_data( pcomm->sharedps_tag(), &verts[2], 1, &procs[0] );CHECK_ERR( rval );
01674     // interface, multi-shared, not owned
01675     pvals[3] = ( PSTATUS_INTERFACE | PSTATUS_MULTISHARED | PSTATUS_NOT_OWNED | PSTATUS_SHARED );  // p1, p2
01676     rval     = moab.tag_set_data( pcomm->sharedps_tag(), &verts[3], 1, &procs[1] );CHECK_ERR( rval );
01677     // ghost, shared
01678     pvals[4] = ( PSTATUS_GHOST | PSTATUS_SHARED | PSTATUS_NOT_OWNED );  // p2
01679     rval     = moab.tag_set_data( pcomm->sharedp_tag(), &verts[4], 1, &procs[2] );CHECK_ERR( rval );
01680     // ghost, multi-shared
01681     pvals[5] = ( PSTATUS_GHOST | PSTATUS_MULTISHARED | PSTATUS_NOT_OWNED | PSTATUS_SHARED );  // p2, p3
01682     rval     = moab.tag_set_data( pcomm->sharedps_tag(), &verts[5], 1, &procs[2] );CHECK_ERR( rval );
01683     // owned, shared
01684     pvals[6] = ( PSTATUS_SHARED );  // p4
01685     rval     = moab.tag_set_data( pcomm->sharedp_tag(), &verts[6], 1, &procs[4] );CHECK_ERR( rval );
01686     // owned, multi-shared
01687     pvals[7] = ( PSTATUS_MULTISHARED | PSTATUS_SHARED );  // p4, p5
01688     rval     = moab.tag_set_data( pcomm->sharedps_tag(), &verts[7], 1, &procs[4] );CHECK_ERR( rval );
01689     // not shared, owned
01690     pvals[8] = 0x0;
01691 
01692     rval = moab.tag_set_data( pcomm->pstatus_tag(), &verts[0], 9, &pvals[0] );CHECK_ERR( rval );
01693 
01694     Range tmp_range = vertsr;
01695 
01696     // interface ents
01697     rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_AND );CHECK_ERR( rval );
01698     CHECK( tmp_range.size() == 4 && *tmp_range.begin() == verts[0] && *tmp_range.rbegin() == verts[3] );
01699     // not interface
01700     tmp_range = vertsr;
01701     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_NOT );CHECK_ERR( rval );
01702     CHECK( tmp_range.size() == 5 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[8] );
01703     // interface not owned
01704     tmp_range = vertsr;
01705     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE | PSTATUS_NOT_OWNED, PSTATUS_AND );CHECK_ERR( rval );
01706     CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[1] && *tmp_range.rbegin() == verts[3] );
01707     // ghost
01708     tmp_range = vertsr;
01709     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_GHOST, PSTATUS_AND );CHECK_ERR( rval );
01710     CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[5] );
01711     // shared not multi-shared
01712     tmp_range = vertsr;
01713     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND );CHECK_ERR( rval );
01714     rval = pcomm->filter_pstatus( tmp_range, PSTATUS_MULTISHARED, PSTATUS_NOT );CHECK_ERR( rval );
01715     CHECK( tmp_range.size() == 4 && tmp_range[0] == verts[0] && tmp_range[1] == verts[1] && tmp_range[2] == verts[4] &&
01716            tmp_range[3] == verts[6] );
01717     // shared w/ p0
01718     tmp_range = vertsr;
01719     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND, 0 );CHECK_ERR( rval );
01720     CHECK( tmp_range.size() == 2 && tmp_range[1] == verts[2] );
01721     // shared w/ p2 && not owned
01722     tmp_range = vertsr;
01723     rval      = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED | PSTATUS_NOT_OWNED, PSTATUS_AND, 2 );CHECK_ERR( rval );
01724     CHECK( tmp_range.size() == 3 && tmp_range[0] == verts[3] && tmp_range[1] == verts[4] && tmp_range[2] == verts[5] );
01725 
01726     delete pcomm;
01727 }
01728 
01729 void test_new_pcomm_instance()
01730 {
01731 #if defined( MOAB_HAVE_MPI ) && defined( MOAB_HAVE_HDF5 )
01732     Core moab;
01733     Interface& mb = moab;
01734 
01735     // This parallel read will create a ParallelComm instance implicitly
01736     std::string example      = TestDir + "/64bricks_1khex.h5m";
01737     std::string read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS";
01738     ErrorCode rval           = mb.load_file( example.c_str(), 0, read_options.c_str() );CHECK_ERR( rval );
01739 
01740     // It is highly recommended to reuse existing ParallelComm instance with
01741     // ParallelComm::get_pcomm() Creating a new ParallelComm instance should still be allowed,
01742     // anyway
01743     ParallelComm* pcomm = new moab::ParallelComm( &moab, MPI_COMM_WORLD );
01744 
01745     // Do something with pcomm
01746     // ...
01747 
01748     delete pcomm;
01749 #endif
01750 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines