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