MOAB: Mesh Oriented datABase  (version 5.3.0)
h5partial.cpp
Go to the documentation of this file.
00001 #include "moab/Core.hpp"
00002 #include "moab/Range.hpp"
00003 #include "TestRunner.hpp"
00004 #include "ReadHDF5.hpp"
00005 #include "MBTagConventions.hpp"
00006 #include "moab/FileOptions.hpp"
00007 
00008 #ifdef MOAB_HAVE_MPI
00009 #include "moab_mpi.h"
00010 #endif
00011 
00012 #include <vector>
00013 #include <cstdlib>
00014 #include <iostream>
00015 #include <algorithm>
00016 #include <limits>
00017 
00018 using namespace moab;
00019 
00020 const char TEST_FILE[] = "partial.h5m";
00021 #define READ_OPTS "BUFFER_SIZE=256"
00022 const char ID_TAG_NAME[] = "test_id_tag";
00023 
00024 static void test_read_nothing_common( bool non_existant );
00025 static void test_read_nodes_common( int num_read_sets, bool blocked_coordinate_io );
00026 static void test_read_handle_tag_common( bool var_len );
00027 
00028 const int MBQUAD_INT       = 20;
00029 const int NUM_SETS         = 10;
00030 const int SET_WIDTH        = ( MBQUAD_INT + NUM_SETS - 1 ) / NUM_SETS;  // ceil(MBQUAD_INT/NUM_SETS)
00031 const char LOGICAL_NAME[]  = "logical";                                 // tag storing logical (i,j) coordinates
00032 const char CENTROID_NAME[] = "centroid";                                // tag storing position of centroid (x,y,0)
00033 //! Create a regular MBQUAD_INT^2 element quad mesh with regularly
00034 //! spaced coordinates in the range [1,100].  Group elements
00035 //! into 10 vertical strips MBQUAD_INT/10 elements wide.  Tag elements,
00036 //! vertices and/or sets with ID in [1,10] stored in ID_TAG_NAME
00037 //! tag.  Write new mesh to TEST_FILE.
00038 void create_mesh( bool create_element_sets, bool create_vertex_sets, bool tag_elements_with_id,
00039                   bool tag_vertices_with_id, const char* adj_elem_tag_name = 0, bool var_len_adj_elems = false );
00040 // Given a list of vertices adjacent to a quad strip, identify it as one of the
00041 // NUM_SETS strips of quads written by create_mesh.
00042 int identify_set( Interface& mb, const Range& verts );
00043 int identify_set( Interface& mb, EntityHandle set );
00044 
00045 static Tag check_tag( Interface& mb, const char* name, TagType storage, DataType type, int size );
00046 
00047 enum GatherTestMode
00048 {
00049     GATHER_SETS,
00050     GATHER_CONTENTS,
00051     GATHER_NONE
00052 };
00053 void test_gather_sets_common( bool contained_sets, GatherTestMode mode, bool no_parent_containing_sets = false );
00054 void test_gather_sets_ranged( bool contained_sets, GatherTestMode mode, bool no_parent_containing_sets = false );
00055 
00056 //! Read a set containing no entities
00057 void test_read_empty_set()
00058 {
00059     test_read_nothing_common( false );
00060 }
00061 
00062 //! Specify ID that doesn't exist in file
00063 void test_read_non_existant_set()
00064 {
00065     test_read_nothing_common( true );
00066 }
00067 
00068 //! Read in the nodes contained in a set.
00069 void test_read_one_set_nodes()
00070 {
00071     test_read_nodes_common( 1, false );
00072 }
00073 
00074 //! Read in the nodes contained in a set.
00075 void test_read_one_set_nodes_blocked()
00076 {
00077     test_read_nodes_common( 1, true );
00078 }
00079 
00080 //! Read in the elems contained in a set
00081 void test_read_one_set_elems();
00082 
00083 //! Read in the polyhedra contained in a set
00084 void test_read_one_set_polyhedra();
00085 
00086 //! Read in the sets contained in a set.
00087 //! Should read all sets containing read elements or nodes
00088 //! and all sets that are contained the the specified "read"
00089 //! set.  Test the later here.
00090 void test_read_set_sets();
00091 
00092 //! Read in the nodes contained in a sets.
00093 void test_read_two_sets_nodes()
00094 {
00095     test_read_nodes_common( 2, false );
00096 }
00097 
00098 //! Read in the elems contained in a sets
00099 void test_read_two_sets_elems();
00100 
00101 //! For any set selected to be read by either explicit designation,
00102 //! containing read entities, or contained in an explcitly designated
00103 //! set, any child sets are also read.  Check that here.
00104 void test_read_child_sets_only()
00105 {
00106     test_gather_sets_common( false, GATHER_SETS );
00107     test_gather_sets_ranged( false, GATHER_SETS );
00108 }
00109 void test_read_child_set_contents()
00110 {
00111     test_gather_sets_common( false, GATHER_CONTENTS );
00112     test_gather_sets_ranged( false, GATHER_CONTENTS );
00113 }
00114 void test_read_no_child_sets()
00115 {
00116     test_gather_sets_common( false, GATHER_NONE );
00117     test_gather_sets_ranged( false, GATHER_NONE );
00118 }
00119 
00120 //! For any set selected to be read by either explicit designation,
00121 //! containing read entities, or contained in an explcitly designated
00122 //! set, any contained sets are also read.  Check that here.
00123 void test_read_contained_sets_only()
00124 {
00125     test_gather_sets_common( true, GATHER_SETS, true );
00126     test_gather_sets_ranged( true, GATHER_SETS );
00127 }
00128 void test_read_contained_set_contents()
00129 {
00130     test_gather_sets_common( true, GATHER_CONTENTS, true );
00131     test_gather_sets_ranged( true, GATHER_CONTENTS );
00132 }
00133 void test_read_no_contained_sets()
00134 {
00135     test_gather_sets_common( true, GATHER_NONE, true );
00136     test_gather_sets_ranged( true, GATHER_NONE );
00137 }
00138 
00139 //! Read in the sets contained in a set.
00140 //! Should read all sets containing read elements or nodes
00141 //! and all sets that are contained the the specified "read"
00142 //! set.  Test the former here.
00143 void test_read_containing_sets();
00144 
00145 //! Test reading of explicit adjacencies
00146 void test_read_adjacencies();
00147 
00148 //! Test reading of sparse double tag data
00149 void test_read_double_tag();
00150 
00151 //! Test reading of sparse opaque tag data
00152 void test_read_opaque_tag();
00153 
00154 //! Test reading of sparse handle tag data
00155 void test_read_handle_tag()
00156 {
00157     test_read_handle_tag_common( false );
00158 }
00159 
00160 //! Test reading of variable-length tag data
00161 void test_var_len_tag()
00162 {
00163     test_read_handle_tag_common( true );
00164 }
00165 
00166 void test_read_tagged_elems();
00167 
00168 void test_read_tagged_nodes();
00169 
00170 void test_read_sides();
00171 
00172 void test_read_ids();
00173 
00174 void test_read_partial_ids();
00175 
00176 int main( int argc, char* argv[] )
00177 {
00178 #ifdef MOAB_HAVE_MPI
00179     int fail = MPI_Init( &argc, &argv );
00180     if( fail ) return fail;
00181 #endif
00182 
00183     REGISTER_TEST( test_read_empty_set );
00184     REGISTER_TEST( test_read_non_existant_set );
00185     REGISTER_TEST( test_read_one_set_nodes );
00186     REGISTER_TEST( test_read_one_set_nodes_blocked );
00187     REGISTER_TEST( test_read_one_set_elems );
00188     REGISTER_TEST( test_read_one_set_polyhedra );
00189     REGISTER_TEST( test_read_set_sets );
00190     REGISTER_TEST( test_read_two_sets_nodes );
00191     REGISTER_TEST( test_read_two_sets_elems );
00192     REGISTER_TEST( test_read_child_sets_only );
00193     REGISTER_TEST( test_read_child_set_contents );
00194     REGISTER_TEST( test_read_no_child_sets );
00195     REGISTER_TEST( test_read_contained_sets_only );
00196     REGISTER_TEST( test_read_contained_set_contents );
00197     REGISTER_TEST( test_read_no_contained_sets );
00198     REGISTER_TEST( test_read_containing_sets );
00199     REGISTER_TEST( test_read_double_tag );
00200     REGISTER_TEST( test_read_opaque_tag );
00201     REGISTER_TEST( test_read_handle_tag );
00202     REGISTER_TEST( test_var_len_tag );
00203     REGISTER_TEST( test_read_adjacencies );
00204     REGISTER_TEST( test_read_tagged_elems );
00205     REGISTER_TEST( test_read_tagged_nodes );
00206     REGISTER_TEST( test_read_sides );
00207     REGISTER_TEST( test_read_ids );
00208     REGISTER_TEST( test_read_partial_ids );
00209     int result = RUN_TESTS( argc, argv );
00210 
00211 #ifdef MOAB_HAVE_MPI
00212     fail = MPI_Finalize();
00213     if( fail ) return fail;
00214 #endif
00215 
00216     return result;
00217 }
00218 
00219 void test_read_nothing_common( bool non_existant )
00220 {
00221     ErrorCode rval;
00222     Core moab;
00223     Interface& mb = moab;
00224 
00225     // create a few nodes to write to file
00226     std::vector< double > coords( 3000 );
00227     Range verts;
00228     rval = mb.create_vertices( &coords[0], coords.size() / 3, verts );CHECK_ERR( rval );
00229 
00230     // create three entity sets
00231     EntityHandle sets[3];
00232     rval = mb.create_meshset( MESHSET_SET, sets[0] );CHECK_ERR( rval );
00233     rval = mb.create_meshset( MESHSET_SET, sets[1] );CHECK_ERR( rval );
00234     rval = mb.create_meshset( MESHSET_ORDERED, sets[2] );CHECK_ERR( rval );
00235 
00236     // put all vertices into two of the sets
00237     rval = mb.add_entities( sets[0], verts );CHECK_ERR( rval );
00238     rval = mb.add_entities( sets[2], verts );CHECK_ERR( rval );
00239 
00240     // tag all three sets
00241     Tag id_tag;
00242     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00243     int ids[3] = { 5, 7, 9 };
00244     rval       = mb.tag_set_data( id_tag, sets, 3, ids );CHECK_ERR( rval );
00245 
00246     // write mesh
00247     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
00248     rval = mb.delete_mesh();CHECK_ERR( rval );
00249 
00250     // now read back in only the empty set
00251     EntityHandle file_set;
00252     int id = non_existant ? 8 : 7;
00253     rval   = mb.create_meshset( MESHSET_SET, file_set );CHECK_ERR( rval );
00254     rval = mb.load_file( TEST_FILE, &file_set, READ_OPTS, ID_TAG_NAME, &id, 1 );
00255     if( non_existant )
00256     {
00257         CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
00258         return;
00259     }
00260     else
00261         CHECK_ERR( rval );
00262 
00263     // the file should contain exactly two sets (the specified one and the new
00264     // file set, and nothing else.)
00265     for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
00266     {
00267         int count = -1;
00268         rval      = mb.get_number_entities_by_type( 0, t, count );CHECK_ERR( rval );
00269         CHECK_EQUAL( 0, count );
00270     }
00271     Range setrange;
00272     rval = mb.get_entities_by_type( 0, MBENTITYSET, setrange );CHECK_ERR( rval );
00273     CHECK_EQUAL( ( non_existant ? 1 : 2 ), (int)setrange.size() );
00274     CHECK( setrange.find( file_set ) != setrange.end() );
00275 }
00276 
00277 static void vtx_coords( int set_id, int j, int num_sets, double coords[3] )
00278 {
00279     int i     = num_sets * j + set_id;
00280     coords[0] = i;
00281     coords[1] = i + 0.25;
00282     coords[2] = i + 0.5;
00283 }
00284 
00285 void test_read_nodes_common( int num_read_sets, bool blocked )
00286 {
00287     ErrorCode rval;
00288     Core moab;
00289     Interface& mb = moab;
00290 
00291     // create 1000 nodes
00292     const int num_sets = 2 * num_read_sets;
00293     std::vector< EntityHandle > verts( 1000 );
00294     std::vector< std::vector< EntityHandle > > set_verts( num_sets );
00295     for( size_t i = 0; i < verts.size(); ++i )
00296     {
00297         double coords[3];
00298         int j = i % num_sets;
00299         vtx_coords( j + 1, set_verts[j].size(), num_sets, coords );
00300         rval = mb.create_vertex( coords, verts[i] );
00301         set_verts[j].push_back( verts[i] );CHECK_ERR( rval );
00302     }
00303 
00304     // create two sets, each containing half of the nodes
00305     std::vector< EntityHandle > sets( num_sets );
00306     for( int i = 0; i < num_sets; ++i )
00307     {
00308         rval = mb.create_meshset( MESHSET_ORDERED, sets[i] );CHECK_ERR( rval );
00309         rval = mb.add_entities( sets[i], &set_verts[i][0], set_verts[i].size() );CHECK_ERR( rval );
00310     }
00311 
00312     // tag both sets
00313     Tag id_tag;
00314     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00315     std::vector< int > values( num_sets );
00316     for( int i = 0; i < num_sets; ++i )
00317         values[i] = i + 1;
00318     rval = mb.tag_set_data( id_tag, &sets[0], num_sets, &values[0] );CHECK_ERR( rval );
00319 
00320     // write file
00321     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
00322     rval = mb.delete_mesh();CHECK_ERR( rval );
00323 
00324     // now read back in only the specified number of sets
00325     std::string opts( READ_OPTS );
00326     if( !opts.empty() ) opts += ';';
00327     if( blocked )
00328         opts += "BLOCKED_COORDINATE_IO=yes";
00329     else
00330         opts += "BLOCKED_COORDINATE_IO=no";
00331 
00332     values.resize( num_read_sets );
00333     for( int i = 0; i < num_read_sets; ++i )
00334         values[i] = 2 * ( i + 1 );
00335     EntityHandle file_set;
00336     rval = mb.create_meshset( MESHSET_SET, file_set );CHECK_ERR( rval );
00337     rval = mb.load_file( TEST_FILE, &file_set, opts.c_str(), ID_TAG_NAME, &values[0], num_read_sets );CHECK_ERR( rval );
00338 
00339     int count, expected = 0;
00340     rval = mb.get_number_entities_by_dimension( 0, 0, count );CHECK_ERR( rval );
00341     for( int i = 0; i < num_sets; ++i )
00342         if( i % 2 ) expected += set_verts[i].size();
00343     CHECK_EQUAL( expected, count );
00344 
00345     Range sets2;
00346     rval = mb.get_entities_by_type( 0, MBENTITYSET, sets2 );CHECK_ERR( rval );
00347     CHECK_EQUAL( 1 + num_read_sets, (int)sets2.size() );
00348     Range::iterator it = sets2.find( file_set );
00349     CHECK( it != sets2.end() );
00350     sets2.erase( it );
00351 
00352     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );CHECK_ERR( rval );
00353     while( !sets2.empty() )
00354     {
00355         EntityHandle set = sets2.pop_front();
00356         int id;
00357         rval = mb.tag_get_data( id_tag, &set, 1, &id );CHECK_ERR( rval );
00358         CHECK( std::find( values.begin(), values.end(), id ) != values.end() );
00359         CHECK( id > 0 );
00360         CHECK( (unsigned)id <= set_verts.size() );
00361 
00362         std::vector< EntityHandle > verts2;
00363         rval = mb.get_entities_by_handle( set, verts2 );CHECK_ERR( rval );
00364         CHECK_EQUAL( set_verts[id - 1].size(), verts2.size() );
00365 
00366         for( size_t i = 0; i < verts2.size(); ++i )
00367         {
00368             double exp_coords[3], coords[3];
00369             vtx_coords( id, i, num_sets, exp_coords );
00370             rval = mb.get_coords( &verts2[i], 1, coords );CHECK_ERR( rval );
00371             CHECK_REAL_EQUAL( exp_coords[0], coords[0], 1e-12 );
00372             CHECK_REAL_EQUAL( exp_coords[1], coords[1], 1e-12 );
00373             CHECK_REAL_EQUAL( exp_coords[2], coords[2], 1e-12 );
00374         }
00375     }
00376 }
00377 
00378 //! Create a regular MBQUAD_INT^2 element quad mesh with regularly
00379 //! spaced coordinates in the range [1,100].  Group elements
00380 //! into 10 vertical strips MBQUAD_INT/10 elements wide.  Tag elements,
00381 //! vertices and/or sets with ID in [1,10] stored in ID_TAG_NAME
00382 //! tag.  Write new mesh to TEST_FILE.
00383 void create_mesh( bool create_element_sets, bool create_vertex_sets, bool tag_elements_with_id,
00384                   bool tag_vertices_with_id, const char* adj_elem_tag_name, bool var_len_adj_elems )
00385 {
00386     Core moab;
00387     Interface& mb = moab;
00388     ErrorCode rval;
00389 
00390     // create tags
00391     Tag logical_tag, centroid_tag, id_tag;
00392     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00393     rval =
00394         mb.tag_get_handle( LOGICAL_NAME, 2 * sizeof( int ), MB_TYPE_OPAQUE, logical_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
00395     rval = mb.tag_get_handle( CENTROID_NAME, 3, MB_TYPE_DOUBLE, centroid_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
00396 
00397     EntityHandle sets[NUM_SETS];
00398     if( create_element_sets || create_vertex_sets )
00399     {
00400         for( int i = 0; i < NUM_SETS; ++i )
00401         {
00402             rval = mb.create_meshset( MESHSET_ORDERED, sets[i] );CHECK_ERR( rval );
00403             int id = i + 1;
00404             rval   = mb.tag_set_data( id_tag, &sets[i], 1, &id );CHECK_ERR( rval );
00405         }
00406     }
00407 
00408     // create elements
00409     EntityHandle verts[MBQUAD_INT + 1][MBQUAD_INT + 1], quads[MBQUAD_INT][MBQUAD_INT];
00410     for( int i = 0; i <= MBQUAD_INT; ++i )
00411         for( int j = 0; j <= MBQUAD_INT; ++j )
00412         {
00413             double coords[3] = { static_cast< double >( i ), static_cast< double >( j ), 0 };
00414             rval             = mb.create_vertex( coords, verts[j][i] );CHECK_ERR( rval );
00415             int logical[2] = { i, j };
00416             rval           = mb.tag_set_data( logical_tag, &verts[j][i], 1, logical );CHECK_ERR( rval );
00417             rval = mb.tag_set_data( centroid_tag, &verts[j][i], 1, coords );CHECK_ERR( rval );
00418             int id = ( i - 1 ) / SET_WIDTH + 1;  // Note: assumes SET_WIDTH > 1
00419             if( tag_vertices_with_id )
00420             {
00421                 rval = mb.tag_set_data( id_tag, &verts[j][i], 1, &id );CHECK_ERR( rval );
00422             }
00423             if( create_vertex_sets )
00424             {
00425                 rval = mb.add_entities( sets[id - 1], &verts[j][i], 1 );CHECK_ERR( rval );
00426                 // Some vertices are shared by quads in different sets.
00427                 // put such vertices in both sets.
00428                 int id2 = i / SET_WIDTH + 1;
00429                 if( id2 != id && id2 <= NUM_SETS )
00430                 {
00431                     rval = mb.add_entities( sets[id2 - 1], &verts[j][i], 1 );CHECK_ERR( rval );
00432                 }
00433             }
00434         }
00435     for( int i = 0; i < MBQUAD_INT; ++i )
00436         for( int j = 0; j < MBQUAD_INT; ++j )
00437         {
00438             EntityHandle conn[4] = { verts[j][i], verts[j][i + 1], verts[j + 1][i + 1], verts[j + 1][i] };
00439             rval                 = mb.create_element( MBQUAD, conn, 4, quads[j][i] );CHECK_ERR( rval );
00440             int logical[2] = { i, j };
00441             rval           = mb.tag_set_data( logical_tag, &quads[j][i], 1, logical );CHECK_ERR( rval );
00442             double centroid[3] = { i + 0.5, j + 0.5, 0 };
00443             rval               = mb.tag_set_data( centroid_tag, &quads[j][i], 1, centroid );CHECK_ERR( rval );
00444             int id = i / SET_WIDTH + 1;
00445             if( tag_elements_with_id )
00446             {
00447                 rval = mb.tag_set_data( id_tag, &quads[j][i], 1, &id );CHECK_ERR( rval );
00448             }
00449             if( create_element_sets )
00450             {
00451                 rval = mb.add_entities( sets[id - 1], &quads[j][i], 1 );CHECK_ERR( rval );
00452             }
00453         }
00454 
00455     if( adj_elem_tag_name && !var_len_adj_elems )
00456     {
00457         Tag handle_tag;
00458         rval = mb.tag_get_handle( adj_elem_tag_name, 4, MB_TYPE_HANDLE, handle_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
00459         for( int i = 0; i <= MBQUAD_INT; ++i )
00460             for( int j = 0; j <= MBQUAD_INT; ++j )
00461             {
00462                 EntityHandle val[4] = { ( i > 0 && j > 0 ) ? quads[j - 1][i - 1] : 0,
00463                                         ( i > 0 && j < MBQUAD_INT ) ? quads[j][i - 1] : 0,
00464                                         ( i < MBQUAD_INT && j < MBQUAD_INT ) ? quads[j][i] : 0,
00465                                         ( i < MBQUAD_INT && j > 0 ) ? quads[j - 1][i] : 0 };
00466                 rval = mb.tag_set_data( handle_tag, &verts[j][i], 1, val );CHECK_ERR( rval );
00467             }
00468     }
00469     else if( adj_elem_tag_name && var_len_adj_elems )
00470     {
00471         Tag handle_tag;
00472         rval = mb.tag_get_handle( adj_elem_tag_name, 0, MB_TYPE_HANDLE, handle_tag,
00473                                   MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL );CHECK_ERR( rval );
00474         for( int i = 0; i <= MBQUAD_INT; ++i )
00475             for( int j = 0; j <= MBQUAD_INT; ++j )
00476             {
00477                 EntityHandle val[4];
00478                 int num = 0;
00479                 if( i > 0 && j > 0 ) val[num++] = quads[j - 1][i - 1];
00480                 if( i > 0 && j < MBQUAD_INT ) val[num++] = quads[j][i - 1];
00481                 if( i < MBQUAD_INT && j < MBQUAD_INT ) val[num++] = quads[j][i];
00482                 if( i < MBQUAD_INT && j > 0 ) val[num++] = quads[j - 1][i];
00483                 const void* ptr = val;
00484                 rval            = mb.tag_set_by_ptr( handle_tag, &verts[j][i], 1, &ptr, &num );CHECK_ERR( rval );
00485             }
00486     }
00487 
00488     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
00489 }
00490 
00491 // Given a list of vertices adjacent to a quad strip, identify it as one of the
00492 // NUM_SETS strips of quads written by create_mesh.
00493 int identify_set( Interface& mb, const Range& verts )
00494 {
00495     const int COL = SET_WIDTH + 1;
00496     CHECK_EQUAL( ( 1 + MBQUAD_INT ) * COL, (int)verts.size() );
00497 
00498     // Get X range of vertices
00499     int min_x = std::numeric_limits< int >::max();
00500     int max_x = std::numeric_limits< int >::min();
00501     for( Range::const_iterator i = verts.begin(); i != verts.end(); ++i )
00502     {
00503         double coords[3];
00504         ErrorCode rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
00505         // Expect whole-valued coorindates
00506         int int_x = (int)coords[0];
00507         CHECK( fabs( coords[0] - (double)int_x ) < 1e-12 );
00508 
00509         if( int_x < min_x ) min_x = int_x;
00510         if( int_x > max_x ) max_x = int_x;
00511     }
00512     CHECK( max_x - min_x < COL );
00513 
00514     // Calculate ID (return value) from coordinate range)
00515     const int ID = min_x / SET_WIDTH + 1;
00516 
00517     // Now verify that all vertices correctly form a grid
00518     EntityHandle grid[MBQUAD_INT + 1][COL];
00519     memset( grid, 0, sizeof( grid ) );
00520     for( Range::const_iterator i = verts.begin(); i != verts.end(); ++i )
00521     {
00522         double coords[3];
00523         ErrorCode rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
00524         // Expect whole-valued coorindates
00525         int x = (int)coords[0] - ( ID - 1 ) * SET_WIDTH, y = (int)coords[1];
00526         CHECK( fabs( coords[1] - (double)y ) < 1e-12 );
00527         CHECK( fabs( coords[2] ) < 1e-12 );
00528         CHECK( y >= 0 && y <= MBQUAD_INT );
00529         CHECK_EQUAL( (EntityHandle)0, grid[y][x] );
00530         grid[y][x] = *i;
00531     }
00532 
00533     return ID;
00534 }
00535 int identify_set( Interface& mb, EntityHandle set )
00536 {
00537     ErrorCode rval;
00538     Range verts, elems;
00539     rval = mb.get_entities_by_handle( set, elems );CHECK_ERR( rval );
00540     Range::iterator it = elems.upper_bound( MBVERTEX );
00541     verts.merge( elems.begin(), it );
00542     elems.erase( elems.begin(), it );
00543     it = elems.lower_bound( MBENTITYSET );
00544     elems.erase( it, elems.end() );
00545     rval = mb.get_adjacencies( elems, 0, false, verts, Interface::UNION );CHECK_ERR( rval );
00546     return identify_set( mb, verts );
00547 }
00548 
00549 //! Read in the elems contained in a set
00550 void test_read_one_set_elems()
00551 {
00552     ErrorCode rval;
00553     Core moab;
00554     Interface& mb = moab;
00555 
00556     create_mesh( true, false, false, false );
00557 
00558     for( int id = 1; id <= NUM_SETS; ++id )
00559     {
00560         rval = mb.delete_mesh();CHECK_ERR( rval );
00561         rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );CHECK_ERR( rval );
00562         Range verts;
00563         rval       = mb.get_entities_by_type( 0, MBVERTEX, verts );
00564         int act_id = identify_set( mb, verts );
00565         CHECK_EQUAL( id, act_id );
00566     }
00567 }
00568 
00569 //! Read in the elems contained in a sets
00570 void test_read_two_sets_elems()
00571 {
00572     ErrorCode rval;
00573     Core moab;
00574     Interface& mb = moab;
00575 
00576     create_mesh( true, false, false, false );
00577     int ids[2] = { 2, 8 };
00578     EntityHandle file_set;
00579     rval = mb.create_meshset( MESHSET_SET, file_set );CHECK_ERR( rval );
00580     rval = mb.load_file( TEST_FILE, &file_set, READ_OPTS, ID_TAG_NAME, ids, 2 );CHECK_ERR( rval );
00581 
00582     Range sets;
00583     rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00584     CHECK_EQUAL( 3, (int)sets.size() );
00585     Range::iterator it = sets.find( file_set );
00586     CHECK( it != sets.end() );
00587     sets.erase( it );
00588 
00589     int id1 = identify_set( mb, sets.front() );
00590     int id2 = identify_set( mb, sets.back() );
00591     if( id1 == ids[0] ) { CHECK_EQUAL( ids[1], id2 ); }
00592     else
00593     {
00594         CHECK_EQUAL( ids[1], id1 );
00595         CHECK_EQUAL( ids[0], id2 );
00596     }
00597 }
00598 
00599 Tag check_tag( Interface& mb, const char* name, TagType storage, DataType type, int size )
00600 {
00601 
00602     Tag tag;
00603     ErrorCode rval = mb.tag_get_handle( name, size, type, tag );CHECK_ERR( rval );
00604 
00605     TagType storage1;
00606     rval = mb.tag_get_type( tag, storage1 );CHECK_ERR( rval );
00607     CHECK_EQUAL( storage, storage1 );
00608 
00609     DataType type1;
00610     rval = mb.tag_get_data_type( tag, type1 );CHECK_ERR( rval );
00611     CHECK_EQUAL( type, type1 );
00612 
00613     int size1;
00614     rval = mb.tag_get_length( tag, size1 );
00615     if( size <= 0 )
00616     {  // variable-length tag
00617         CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
00618     }
00619     else
00620     {
00621         CHECK_ERR( rval );
00622         CHECK_EQUAL( size, size1 );
00623     }
00624 
00625     return tag;
00626 }
00627 
00628 //! Test reading of sparse double tag data
00629 void test_read_double_tag()
00630 {
00631     ErrorCode rval;
00632     Core moab;
00633     Interface& mb = moab;
00634 
00635     create_mesh( true, false, false, false );
00636     int ids[2] = { 1, 4 };
00637     rval       = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );CHECK_ERR( rval );
00638 
00639     Tag tag = check_tag( mb, CENTROID_NAME, MB_TAG_DENSE, MB_TYPE_DOUBLE, 3 );
00640     Range verts;
00641     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00642     CHECK( !verts.empty() );
00643     for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
00644     {
00645         double coords[3], data[3];
00646         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
00647         rval = mb.tag_get_data( tag, &*i, 1, data );CHECK_ERR( rval );
00648         CHECK_REAL_EQUAL( coords[0], data[0], 1e-12 );
00649         CHECK_REAL_EQUAL( coords[1], data[1], 1e-12 );
00650         CHECK_REAL_EQUAL( coords[2], data[2], 1e-12 );
00651     }
00652 }
00653 
00654 //! Test reading of sparse opaque tag data
00655 void test_read_opaque_tag()
00656 {
00657     ErrorCode rval;
00658     Core moab;
00659     Interface& mb = moab;
00660 
00661     create_mesh( true, false, false, false );
00662     int ids[2] = { 1, 4 };
00663     rval       = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );CHECK_ERR( rval );
00664 
00665     Tag tag = check_tag( mb, LOGICAL_NAME, MB_TAG_DENSE, MB_TYPE_OPAQUE, 2 * sizeof( int ) );
00666     Range verts;
00667     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00668     CHECK( !verts.empty() );
00669     for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
00670     {
00671         double coords[3];
00672         int data[2];
00673         rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
00674         rval = mb.tag_get_data( tag, &*i, 1, data );CHECK_ERR( rval );
00675         CHECK_REAL_EQUAL( coords[0], (double)data[0], 1e-12 );
00676         CHECK_REAL_EQUAL( coords[1], (double)data[1], 1e-12 );
00677     }
00678 }
00679 
00680 static void test_read_handle_tag_common( bool var_len )
00681 {
00682     ErrorCode rval;
00683     Core moab;
00684     Interface& mb = moab;
00685 
00686     const char tag_name[] = "VTX_ADJ";
00687     create_mesh( true, false, false, false, tag_name, var_len );
00688     int ids[2] = { 7, 10 };
00689     rval       = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );CHECK_ERR( rval );
00690 
00691     Tag tag = check_tag( mb, tag_name, MB_TAG_DENSE, MB_TYPE_HANDLE, var_len ? 0 : 4 );
00692     Range verts;
00693     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00694     CHECK( !verts.empty() );
00695     for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
00696     {
00697         std::vector< EntityHandle > adj, val;
00698         rval = mb.get_adjacencies( &*i, 1, 2, false, adj, Interface::UNION );CHECK_ERR( rval );
00699         CHECK( !adj.empty() );
00700 
00701         int num;
00702         const void* ptr;
00703         rval = mb.tag_get_by_ptr( tag, &*i, 1, &ptr, &num );CHECK_ERR( rval );
00704 
00705         if( var_len )
00706         {
00707             CHECK( num > 0 );
00708             CHECK( num < 5 );
00709         }
00710         else
00711         {
00712             CHECK_EQUAL( 4, num );
00713         }
00714 
00715         val.clear();
00716         const EntityHandle* dat = (const EntityHandle*)ptr;
00717         for( const EntityHandle* end = dat + num; dat != end; ++dat )
00718             if( *dat ) val.push_back( *dat );
00719 
00720         CHECK_EQUAL( adj.size(), val.size() );
00721         std::sort( adj.begin(), adj.end() );
00722         std::sort( val.begin(), val.end() );
00723         CHECK( adj == val );
00724     }
00725 }
00726 
00727 void test_read_tagged_elems()
00728 {
00729     ErrorCode rval;
00730     Core moab;
00731     Interface& mb = moab;
00732 
00733     create_mesh( false, false, true, false );
00734     int id = 5;
00735     rval   = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );CHECK_ERR( rval );
00736 
00737     Range verts;
00738     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00739     int id2 = identify_set( mb, verts );
00740     CHECK_EQUAL( id, id2 );
00741 
00742     int elems;
00743     rval = mb.get_number_entities_by_type( 0, MBQUAD, elems );CHECK_ERR( rval );
00744     CHECK_EQUAL( MBQUAD_INT * MBQUAD_INT / NUM_SETS, elems );
00745 }
00746 
00747 void test_read_tagged_nodes()
00748 {
00749     ErrorCode rval;
00750     Core moab;
00751     Interface& mb = moab;
00752 
00753     create_mesh( false, false, false, true );
00754     int id = 1;  // NOTE: this test will only succeed for ID == 1
00755     rval   = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );CHECK_ERR( rval );
00756 
00757     Range verts;
00758     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
00759     int id2 = identify_set( mb, verts );
00760     CHECK_EQUAL( id, id2 );
00761 
00762     int elems;
00763     rval = mb.get_number_entities_by_type( 0, MBQUAD, elems );CHECK_ERR( rval );
00764     CHECK_EQUAL( MBQUAD_INT * MBQUAD_INT / NUM_SETS, elems );
00765 }
00766 
00767 //! Read in the polyhedra contained in a set
00768 void test_read_one_set_polyhedra()
00769 {
00770     ErrorCode rval;
00771     Core instance;
00772     Interface& mb = instance;
00773 
00774     // create a 2x2x1 block of hexes, splitting each hex face
00775     // into two triangles to form an 12-sided polyhedron
00776     EntityHandle verts[18], hexes[4];
00777     double coords[18][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 2, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 }, { 2, 1, 0 },
00778                              { 0, 0, 1 }, { 1, 0, 1 }, { 2, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }, { 2, 1, 1 },
00779                              { 0, 0, 2 }, { 1, 0, 2 }, { 2, 0, 2 }, { 0, 1, 2 }, { 1, 1, 2 }, { 2, 1, 2 } };
00780     int hexconn[4][8]    = { { 0, 1, 4, 3, 6, 7, 10, 9 },
00781                           { 1, 2, 5, 4, 7, 8, 11, 10 },
00782                           { 6, 7, 10, 9, 12, 13, 16, 15 },
00783                           { 7, 8, 11, 10, 13, 14, 17, 16 } };
00784     for( int i = 0; i < 18; ++i )
00785     {
00786         rval = mb.create_vertex( coords[i], verts[i] );CHECK_ERR( rval );
00787     }
00788     for( int i = 0; i < 4; ++i )
00789     {
00790         EntityHandle conn[8];
00791         for( int j = 0; j < 8; ++j )
00792             conn[j] = verts[hexconn[i][j]];
00793         rval = mb.create_element( MBHEX, conn, 8, hexes[i] );CHECK_ERR( rval );
00794     }
00795 
00796     Tag tri_tag;
00797     rval = mb.tag_get_handle( "tris", 2, MB_TYPE_HANDLE, tri_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00798 
00799     std::vector< EntityHandle > quads;
00800     EntityHandle tris[12], poly[4];
00801     for( int i = 0; i < 4; ++i )
00802     {
00803         quads.clear();
00804         rval = mb.get_adjacencies( &hexes[i], 1, 2, true, quads );CHECK_ERR( rval );
00805         CHECK_EQUAL( 6, (int)quads.size() );
00806 
00807         for( int j = 0; j < 6; ++j )
00808         {
00809             rval = mb.tag_get_data( tri_tag, &quads[j], 1, tris + 2 * j );
00810             if( MB_SUCCESS == rval ) continue;
00811             CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
00812             const EntityHandle* conn;
00813             int len;
00814             rval = mb.get_connectivity( quads[j], conn, len );CHECK_ERR( rval );
00815             CHECK_EQUAL( 4, len );
00816             EntityHandle tri_conn[2][3] = { { conn[0], conn[1], conn[2] }, { conn[2], conn[3], conn[0] } };
00817             rval                        = mb.create_element( MBTRI, tri_conn[0], 3, tris[2 * j] );CHECK_ERR( rval );
00818             rval = mb.create_element( MBTRI, tri_conn[1], 3, tris[2 * j + 1] );CHECK_ERR( rval );
00819             rval = mb.tag_set_data( tri_tag, &quads[j], 1, tris + 2 * j );CHECK_ERR( rval );
00820         }
00821 
00822         rval = mb.create_element( MBPOLYHEDRON, tris, 12, poly[i] );CHECK_ERR( rval );
00823     }
00824 
00825     Range all_tri;
00826     rval = mb.get_entities_by_type( 0, MBTRI, all_tri );CHECK_ERR( rval );
00827     CHECK_EQUAL( 40, (int)all_tri.size() );
00828 
00829     rval = mb.delete_entities( hexes, 4 );CHECK_ERR( rval );
00830     rval = mb.delete_entities( &quads[0], quads.size() );CHECK_ERR( rval );
00831 
00832     EntityHandle sets[2];
00833     rval = mb.create_meshset( 0, sets[0] );CHECK_ERR( rval );
00834     rval = mb.add_entities( sets[0], poly, 2 );CHECK_ERR( rval );
00835     rval = mb.create_meshset( 0, sets[1] );CHECK_ERR( rval );
00836     rval = mb.add_entities( sets[1], poly + 2, 2 );CHECK_ERR( rval );
00837 
00838     Tag id_tag;
00839     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00840     int ids[2] = { 2, 3 };
00841     rval       = mb.tag_set_data( id_tag, sets, 2, ids );CHECK_ERR( rval );
00842 
00843     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
00844     rval = mb.delete_mesh();CHECK_ERR( rval );
00845 
00846     rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );CHECK_ERR( rval );
00847 
00848     Range rpoly;
00849     rval = mb.get_entities_by_type( 0, MBPOLYHEDRON, rpoly );CHECK_ERR( rval );
00850     CHECK_EQUAL( 2, (int)rpoly.size() );
00851 
00852     Range polyverts;
00853     rval = mb.get_adjacencies( rpoly, 0, false, polyverts, Interface::UNION );CHECK_ERR( rval );
00854     CHECK_EQUAL( 12, (int)polyverts.size() );
00855 
00856     for( Range::iterator it = polyverts.begin(); it != polyverts.end(); ++it )
00857     {
00858         double coords2[3];
00859         rval = mb.get_coords( &*it, 1, coords2 );CHECK_ERR( rval );
00860         CHECK( coords2[0] > -1e-12 && coords2[0] - 2 < 1e-12 );
00861         CHECK( coords2[1] > -1e-12 && coords2[1] - 1 < 1e-12 );
00862         CHECK( coords2[2] > -1e-12 && coords2[2] - 1 < 1e-12 );
00863     }
00864 }
00865 
00866 //! Read in the sets contained in a set.
00867 //! Should read all sets containing read elements or nodes
00868 //! and all sets that are contained the the specified "read"
00869 //! set.  Test the later here.
00870 void test_read_set_sets()
00871 {
00872     ErrorCode rval;
00873     Core instance;
00874     Interface& mb = instance;
00875 
00876     Tag id_tag;
00877     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
00878 
00879     // create sets and assign an ID to each
00880     const int len = 5;
00881     EntityHandle set[2 * len + 2];
00882     for( int i = 0; i < 2 * len + 2; ++i )
00883     {
00884         rval = mb.create_meshset( MESHSET_SET, set[i] );CHECK_ERR( rval );
00885         int id = i + 1;
00886         rval   = mb.tag_set_data( id_tag, set + i, 1, &id );CHECK_ERR( rval );
00887     }
00888 
00889     // make set containment as follows (values are assigned IDs):
00890     int cont_ids[2][len] = { { 3, 4, 5, 9, 10 }, { 6, 7, 8, 11, 12 } };
00891     for( int i = 0; i < 2; ++i )
00892     {
00893         EntityHandle contents[len] = { set[cont_ids[i][0] - 1], set[cont_ids[i][1] - 1], set[cont_ids[i][2] - 1],
00894                                        set[cont_ids[i][3] - 1], set[cont_ids[i][4] - 1] };
00895         rval                       = mb.add_entities( set[i], contents, len );CHECK_ERR( rval );
00896     }
00897 
00898     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
00899 
00900     for( int i = 0; i < 2; ++i )
00901     {
00902         rval = mb.delete_mesh();CHECK_ERR( rval );
00903 
00904         EntityHandle file;
00905         rval = mb.create_meshset( MESHSET_SET, file );CHECK_ERR( rval );
00906         int id = i + 1;
00907         rval   = mb.load_file( TEST_FILE, &file, READ_OPTS ";SETS=NONE", ID_TAG_NAME, &id, 1 );CHECK_ERR( rval );
00908 
00909         // check that the total number of sets read is as expected
00910         Range sets;
00911         rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
00912         Range::iterator it = sets.find( file );
00913         if( it != sets.end() ) sets.erase( it );
00914         CHECK_EQUAL( len + 1, (int)sets.size() );
00915 
00916         // check that we read in the set specified by ID to the reader
00917         rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );CHECK_ERR( rval );
00918         sets.clear();
00919         const void* data[] = { &id };
00920         rval               = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &id_tag, data, 1, sets );CHECK_ERR( rval );
00921         CHECK_EQUAL( 1, (int)sets.size() );
00922 
00923         // check that it contains the expected sets
00924         EntityHandle owner = sets.front();
00925         sets.clear();
00926         rval = mb.get_entities_by_type( owner, MBENTITYSET, sets );CHECK_ERR( rval );
00927         CHECK_EQUAL( len, (int)sets.size() );
00928 
00929         std::vector< int > expected( cont_ids[i], cont_ids[i] + len );
00930         std::vector< int > actual( len );
00931         rval = mb.tag_get_data( id_tag, sets, &actual[0] );CHECK_ERR( rval );
00932         std::sort( expected.begin(), expected.end() );
00933         std::sort( actual.begin(), actual.end() );
00934         CHECK( expected == actual );
00935     }
00936 }
00937 
00938 static void check_children( bool contents, GatherTestMode mode, Interface& mb, int id, Tag id_tag, EntityHandle file )
00939 {
00940     // Increase number of expected sets by one if contents is true because
00941     // we always read immediately contained (depth 1) sets.
00942     const int exp_num_sets  = ( mode == GATHER_NONE ) ? 1 + contents : id;
00943     const int exp_num_edges = ( mode == GATHER_CONTENTS ) ? id : 1;
00944 
00945     ErrorCode rval;
00946     Range range;
00947     rval = mb.get_entities_by_type( 0, MBEDGE, range );CHECK_ERR( rval );
00948     CHECK_EQUAL( exp_num_edges, (int)range.size() );
00949     range.clear();
00950     rval = mb.get_entities_by_type( 0, MBENTITYSET, range );CHECK_ERR( rval );
00951     Range::iterator it = range.find( file );
00952     CHECK( it != range.end() );
00953     range.erase( it );
00954     CHECK_EQUAL( exp_num_sets, (int)range.size() );
00955 
00956     EntityHandle set;
00957     const void* val[] = { &id };
00958     range.clear();
00959     rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &id_tag, val, 1, range );CHECK_ERR( rval );
00960     CHECK_EQUAL( 1, (int)range.size() );
00961     set = range.front();
00962 
00963     if( mode == GATHER_NONE )
00964     {
00965         range.clear();
00966         rval = mb.get_entities_by_type( set, MBEDGE, range );CHECK_ERR( rval );
00967         CHECK_EQUAL( 1, (int)range.size() );
00968         return;
00969     }
00970 
00971     for( int i = id; i > 0; --i )
00972     {
00973         int act_id;
00974         rval = mb.tag_get_data( id_tag, &set, 1, &act_id );CHECK_ERR( rval );
00975         CHECK_EQUAL( i, act_id );
00976 
00977         range.clear();
00978         rval = mb.get_entities_by_type( set, MBEDGE, range );CHECK_ERR( rval );
00979         if( mode == GATHER_CONTENTS || i == id )
00980         {
00981             CHECK_EQUAL( 1, (int)range.size() );
00982             const EntityHandle* conn;
00983             int len;
00984             rval = mb.get_connectivity( range.front(), conn, len );CHECK_ERR( rval );
00985             CHECK_EQUAL( 2, len );
00986             double coords[3];
00987             rval = mb.get_coords( conn + 1, 1, coords );CHECK_ERR( rval );
00988             CHECK_EQUAL( i, (int)coords[0] );
00989         }
00990         else
00991         {
00992             CHECK( range.empty() );
00993         }
00994 
00995         std::vector< EntityHandle > children;
00996         if( contents )
00997             rval = mb.get_entities_by_type( set, MBENTITYSET, children );
00998         else
00999             rval = mb.get_child_meshsets( set, children );CHECK_ERR( rval );
01000         if( i == 1 ) { CHECK( children.empty() ); }
01001         else
01002         {
01003             CHECK_EQUAL( 1, (int)children.size() );
01004             set = children[0];
01005         }
01006     }
01007 }
01008 
01009 const char* set_read_opts[] = { "SETS", "CONTENTS", "NONE" };
01010 void test_gather_sets_common( bool contents, GatherTestMode mode, bool no_parent_containing_sets )
01011 {
01012     ErrorCode rval;
01013     Core instance;
01014     Interface& mb = instance;
01015 
01016     Tag id_tag;
01017     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01018 
01019     // Create a string of edges from [0,INT] along the X axis each 1 unit in length.
01020     // Create a set for edge edge containing the edge and make it the parent of the
01021     // set containing the previous (closer to origin) edge.  Assign each set an
01022     // ID that is the X coordinate of the larger of the two vertices of the edge
01023     // contained in the set.
01024     const int INT = 64;
01025     EntityHandle verts[INT + 1], edges[INT], sets[INT];
01026     double coords[] = { 0, 0, 0 };
01027     rval            = mb.create_vertex( coords, verts[0] );CHECK_ERR( rval );
01028     for( int i = 0; i < INT; ++i )
01029     {
01030         const int id = i + 1;
01031         coords[0]    = id;
01032         rval         = mb.create_vertex( coords, verts[id] );CHECK_ERR( rval );
01033         rval = mb.create_element( MBEDGE, verts + i, 2, edges[i] );CHECK_ERR( rval );
01034         rval = mb.create_meshset( MESHSET_SET, sets[i] );CHECK_ERR( rval );
01035         rval = mb.add_entities( sets[i], edges + i, 1 );CHECK_ERR( rval );
01036         rval = mb.tag_set_data( id_tag, sets + i, 1, &id );CHECK_ERR( rval );
01037         if( i > 0 )
01038         {
01039             if( contents )
01040                 rval = mb.add_entities( sets[i], sets + ( i - 1 ), 1 );
01041             else
01042                 rval = mb.add_child_meshset( sets[i], sets[i - 1] );CHECK_ERR( rval );
01043         }
01044     }
01045 
01046     // Write the data
01047     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
01048 
01049     EntityHandle file;
01050     std::string opt( READ_OPTS );
01051     if( contents )
01052         opt += ";CHILDREN=NONE;SETS=";
01053     else
01054         opt += ";SETS=NONE;CHILDREN=";
01055     opt += set_read_opts[mode];
01056 
01057     if( no_parent_containing_sets ) opt += ";NO_SET_CONTAINING_PARENTS";
01058 
01059     const int test_ids[]   = { 2, 7, INT / 3 - 1, INT / 2 + 1, INT - 3 };
01060     const int num_test_ids = sizeof( test_ids ) / sizeof( int );
01061     for( int i = 0; i < num_test_ids; ++i )
01062     {
01063         CHECK( test_ids[i] <= INT );
01064 
01065         rval = mb.delete_mesh();CHECK_ERR( rval );
01066 
01067         rval = mb.create_meshset( MESHSET_SET, file );CHECK_ERR( rval );
01068 
01069         rval = mb.load_file( TEST_FILE, 0, opt.c_str(), ID_TAG_NAME, test_ids + i, 1 );CHECK_ERR( rval );
01070         rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );CHECK_ERR( rval );
01071 
01072         check_children( contents, mode, mb, test_ids[i], id_tag, file );
01073     }
01074 }
01075 
01076 void test_gather_sets_ranged( bool contents, GatherTestMode mode, bool no_parent_containing_sets )
01077 {
01078     ErrorCode rval;
01079     Core instance;
01080     Interface& mb = instance;
01081 
01082     Range verts;
01083     Tag id_tag;
01084     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01085 
01086     // create four groups of vertices, where all vertices in the same group
01087     // have the same x-coordinate
01088     const int NUM_GRP_VTX = 20;
01089     const int NUM_GRP     = 4;
01090     EntityHandle sets[NUM_GRP];
01091     for( int i = 0; i < NUM_GRP; ++i )
01092     {
01093         double coords[3 * NUM_GRP_VTX];
01094         for( int j = 0; j < NUM_GRP_VTX; ++j )
01095         {
01096             coords[3 * j]     = i;
01097             coords[3 * j + 1] = j;
01098             coords[3 * j + 2] = 0;
01099         }
01100         rval = mb.create_vertices( coords, NUM_GRP_VTX, verts );CHECK_ERR( rval );
01101 
01102         rval = mb.create_meshset( MESHSET_SET, sets[i] );CHECK_ERR( rval );
01103         rval = mb.add_entities( sets[i], verts );CHECK_ERR( rval );
01104         int id = i + 1;
01105         rval   = mb.tag_set_data( id_tag, sets + i, 1, &id );CHECK_ERR( rval );
01106     }
01107 
01108     // place two of the sets inside the others
01109     if( contents )
01110     {
01111         rval = mb.add_entities( sets[0], &sets[1], 1 );CHECK_ERR( rval );
01112         rval = mb.add_entities( sets[2], &sets[3], 1 );CHECK_ERR( rval );
01113     }
01114     else
01115     {
01116         rval = mb.add_child_meshset( sets[0], sets[1] );CHECK_ERR( rval );
01117         rval = mb.add_child_meshset( sets[2], sets[3] );CHECK_ERR( rval );
01118     }
01119 
01120     // Write the data
01121     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
01122 
01123     // Read the data
01124     std::string opt( READ_OPTS );
01125     if( contents )
01126         opt += ";CHILDREN=NONE;SETS=";
01127     else
01128         opt += ";SETS=NONE;CHILDREN=";
01129     opt += set_read_opts[mode];
01130 
01131     if( no_parent_containing_sets ) opt += ";NO_PARENT_CONTAINING_SETS";
01132 
01133     EntityHandle file;
01134     const int read_id = 3;
01135     rval              = mb.delete_mesh();CHECK_ERR( rval );
01136     rval = mb.create_meshset( MESHSET_SET, file );CHECK_ERR( rval );
01137     rval = mb.load_file( TEST_FILE, &file, opt.c_str(), ID_TAG_NAME, &read_id, 1 );CHECK_ERR( rval );
01138 
01139     // get any sets that were read it
01140     Range read_sets;
01141     rval = mb.get_entities_by_type( file, MBENTITYSET, read_sets );CHECK_ERR( rval );
01142 
01143     // count number of vertices in each group
01144     int counts[NUM_GRP];
01145     memset( counts, 0, sizeof( counts ) );
01146     verts.clear();
01147     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01148     for( Range::iterator it = verts.begin(); it != verts.end(); ++it )
01149     {
01150         double coords[3];
01151         rval = mb.get_coords( &*it, 1, coords );CHECK_ERR( rval );
01152         int i = (int)( coords[0] + 1e-12 );
01153         CHECK( i >= 0 && i < NUM_GRP );
01154         counts[i]++;
01155     }
01156 
01157     // check expected counts
01158     CHECK_EQUAL( 0, counts[0] );
01159     CHECK_EQUAL( 0, counts[1] );
01160     CHECK_EQUAL( NUM_GRP_VTX, counts[2] );
01161     switch( mode )
01162     {
01163         case GATHER_NONE:
01164             CHECK_EQUAL( 0, counts[3] );
01165             CHECK_EQUAL( 1 + contents, (int)read_sets.size() );
01166             break;
01167         case GATHER_SETS:
01168             CHECK_EQUAL( 0, counts[3] );
01169             CHECK_EQUAL( 2, (int)read_sets.size() );
01170             break;
01171         case GATHER_CONTENTS:
01172             CHECK_EQUAL( NUM_GRP_VTX, counts[3] );
01173             CHECK_EQUAL( 2, (int)read_sets.size() );
01174             break;
01175     }
01176 }
01177 
01178 static void check_num_verts( Interface& mb, Tag tag, int id, int num_vtx )
01179 {
01180     ErrorCode rval;
01181     const void* val[] = { &id };
01182     Range range;
01183     rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, val, 1, range );CHECK_ERR( rval );
01184     CHECK_EQUAL( 1, (int)range.size() );
01185 
01186     EntityHandle set = range.front();
01187     range.clear();
01188     rval = mb.get_entities_by_type( set, MBVERTEX, range );CHECK_ERR( rval );
01189     CHECK_EQUAL( num_vtx, (int)range.size() );
01190 }
01191 
01192 //! Read in the sets contained in a set.
01193 //! Should read all sets containing read elements or nodes
01194 //! and all sets that are contained the the specified "read"
01195 //! set.  Test the former here.
01196 void test_read_containing_sets()
01197 {
01198     // create mesh decomposed by elements but create
01199     // sets containing all vertices of decomposed elements
01200     // such that adjacent sets share vertices.
01201     create_mesh( false, true, false, false );
01202 
01203     ErrorCode rval;
01204     Core instance;
01205     Interface& mb = instance;
01206 
01207     // read some sets
01208     const int ids[]    = { 1, 5, 9 };
01209     const int num_sets = sizeof( ids ) / sizeof( int );
01210     rval               = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, num_sets );CHECK_ERR( rval );
01211 
01212     Tag id_tag;
01213     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );CHECK_ERR( rval );
01214 
01215     // expect all sets adjacent to the specified sets because
01216     // they share vertices.
01217     Range verts;
01218     for( int i = 0; i < num_sets; ++i )
01219     {
01220         if( ids[i] > 1 ) check_num_verts( mb, id_tag, ids[i] - 1, MBQUAD_INT + 1 );
01221         check_num_verts( mb, id_tag, ids[i], ( MBQUAD_INT + 1 ) * ( SET_WIDTH + 1 ) );
01222         if( ids[i] < NUM_SETS ) check_num_verts( mb, id_tag, ids[i] + 1, MBQUAD_INT + 1 );
01223     }
01224 }
01225 
01226 //! Test reading of explicit adjacencies
01227 void test_read_adjacencies()
01228 {
01229     ErrorCode rval;
01230     Core instance;
01231     Interface& mb = instance;
01232 
01233     // create four hexes sharing an edge
01234     EntityHandle verts[3][3][2], hexes[2][2];
01235     for( int k = 0; k < 2; ++k )
01236     {
01237         for( int j = 0; j < 3; ++j )
01238         {
01239             for( int i = 0; i < 3; ++i )
01240             {
01241                 double coords[] = { static_cast< double >( i ), static_cast< double >( j ),
01242                                     static_cast< double >( k ) };
01243                 rval            = mb.create_vertex( coords, verts[i][j][k] );CHECK_ERR( rval );
01244             }
01245         }
01246     }
01247     for( int j = 0; j < 2; ++j )
01248     {
01249         for( int i = 0; i < 2; ++i )
01250         {
01251             EntityHandle conn[] = { verts[i][j][0], verts[i + 1][j][0], verts[i + 1][j + 1][0], verts[i][j + 1][0],
01252                                     verts[i][j][1], verts[i + 1][j][1], verts[i + 1][j + 1][1], verts[i][j + 1][1] };
01253             rval                = mb.create_element( MBHEX, conn, 8, hexes[i][j] );CHECK_ERR( rval );
01254         }
01255     }
01256 
01257     // create two duplicate edges that connect the vertices common to all four hexes
01258     EntityHandle edge_conn[2] = { verts[1][1][0], verts[1][1][1] };
01259     EntityHandle edges[2];
01260     rval = mb.create_element( MBEDGE, edge_conn, 2, edges[0] );CHECK_ERR( rval );
01261     rval = mb.create_element( MBEDGE, edge_conn, 2, edges[1] );CHECK_ERR( rval );
01262     // mark one edge as adjacent to the left two hexes and the
01263     // other as adjacent to the right two
01264     rval = mb.add_adjacencies( edges[0], hexes[0], 2, true );CHECK_ERR( rval );
01265     rval = mb.add_adjacencies( edges[1], hexes[1], 2, true );CHECK_ERR( rval );
01266     // create two sets containing the front two and the rear two
01267     // hexes, respectively.
01268     EntityHandle sets[2];
01269     rval = mb.create_meshset( MESHSET_SET, sets[0] );CHECK_ERR( rval );
01270     rval = mb.create_meshset( MESHSET_SET, sets[1] );CHECK_ERR( rval );
01271     EntityHandle set1[4] = { hexes[0][0], hexes[1][0], edges[0], edges[1] };
01272     EntityHandle set2[4] = { hexes[0][1], hexes[1][1], edges[0], edges[1] };
01273     rval                 = mb.add_entities( sets[0], set1, 4 );CHECK_ERR( rval );
01274     rval = mb.add_entities( sets[1], set2, 4 );CHECK_ERR( rval );
01275 
01276     // assign IDs to sets
01277     Tag id_tag;
01278     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01279     int ids[2] = { 1, 2 };
01280     rval       = mb.tag_set_data( id_tag, sets, 2, ids );CHECK_ERR( rval );
01281 
01282     // write mesh
01283     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
01284 
01285     // read mesh
01286     rval = mb.delete_mesh();CHECK_ERR( rval );
01287     rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );CHECK_ERR( rval );
01288 
01289     // expect two hexes and two edges
01290     Range range;
01291     rval = mb.get_entities_by_type( 0, MBHEX, range );CHECK_ERR( rval );
01292     CHECK_EQUAL( 2, (int)range.size() );
01293     EntityHandle h1 = range.front(), h2 = range.back();
01294     range.clear();
01295     rval = mb.get_entities_by_type( 0, MBEDGE, range );CHECK_ERR( rval );
01296     CHECK_EQUAL( 2, (int)range.size() );
01297 
01298     // expecte each edge to have one of the hexes
01299     range.clear();
01300     rval = mb.get_adjacencies( &h1, 1, 1, false, range );CHECK_ERR( rval );
01301     CHECK_EQUAL( 1, (int)range.size() );
01302     EntityHandle e1 = range.front();
01303     range.clear();
01304     rval = mb.get_adjacencies( &h2, 1, 1, false, range );CHECK_ERR( rval );
01305     CHECK_EQUAL( 1, (int)range.size() );
01306     EntityHandle e2 = range.front();
01307 
01308     CHECK( e1 != e2 );
01309 }
01310 
01311 void test_read_sides()
01312 {
01313     ErrorCode rval;
01314     Core instance;
01315     Interface& mb = instance;
01316 
01317     // create 4x4 grid of quads with edges
01318     const int INT = 4;
01319     EntityHandle verts[INT + 1][INT + 1];
01320     for( int j = 0; j <= INT; ++j )
01321     {
01322         for( int i = 0; i <= INT; ++i )
01323         {
01324             double coords[3] = { static_cast< double >( i ), static_cast< double >( j ), 0 };
01325             rval             = mb.create_vertex( coords, verts[INT - j][i] );CHECK_ERR( rval );
01326         }
01327     }
01328     EntityHandle quads[INT][INT];
01329     for( int j = 0; j < INT; ++j )
01330     {
01331         for( int i = 0; i < INT; ++i )
01332         {
01333             EntityHandle conn[4] = { verts[INT - j][i], verts[INT - j][i + 1], verts[INT - j - 1][i + 1],
01334                                      verts[INT - j - 1][i] };
01335             rval                 = mb.create_element( MBQUAD, conn, 4, quads[INT - j - 1][i] );CHECK_ERR( rval );
01336         }
01337     }
01338     Range edges;
01339     rval = mb.get_adjacencies( &quads[0][0], INT * INT, 1, true, edges, Interface::UNION );CHECK_ERR( rval );
01340     CHECK_EQUAL( 40, (int)edges.size() );
01341 
01342     // group quads into two sets
01343     EntityHandle sets[2];
01344     rval = mb.create_meshset( MESHSET_SET, sets[0] );CHECK_ERR( rval );
01345     rval = mb.create_meshset( MESHSET_SET, sets[1] );CHECK_ERR( rval );
01346     rval = mb.add_entities( sets[0], quads[0], INT );CHECK_ERR( rval );
01347     rval = mb.add_entities( sets[1], quads[1], INT );CHECK_ERR( rval );
01348     rval = mb.add_entities( sets[0], quads[2], INT );CHECK_ERR( rval );
01349     rval = mb.add_entities( sets[1], quads[3], INT );CHECK_ERR( rval );
01350 
01351     // assign IDS
01352     Tag id_tag;
01353     rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01354     int ids[2] = { 4, 5 };
01355     rval       = mb.tag_set_data( id_tag, sets, 2, ids );CHECK_ERR( rval );
01356 
01357     // write mesh
01358     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
01359 
01360     // read first set back in
01361     rval = mb.delete_mesh();CHECK_ERR( rval );
01362     rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );CHECK_ERR( rval );
01363 
01364     // check expected counts
01365     int count;
01366     rval = mb.get_number_entities_by_type( 0, MBVERTEX, count );CHECK_ERR( rval );
01367     CHECK_EQUAL( ( INT + 1 ) * INT, count );
01368     rval = mb.get_number_entities_by_type( 0, MBQUAD, count );CHECK_ERR( rval );
01369     CHECK_EQUAL( INT * INT / 2, count );
01370     rval = mb.get_number_entities_by_type( 0, MBEDGE, count );CHECK_ERR( rval );
01371     CHECK_EQUAL( 2 * ( INT + 1 ) + INT * INT, count );
01372 
01373     // check edges adjacent to each quad
01374     Range elems;
01375     rval = mb.get_entities_by_type( 0, MBQUAD, elems );CHECK_ERR( rval );
01376     for( Range::iterator it = elems.begin(); it != elems.end(); ++it )
01377     {
01378         edges.clear();
01379         rval = mb.get_adjacencies( &*it, 1, 1, false, edges );CHECK_ERR( rval );
01380         CHECK_EQUAL( 4, (int)edges.size() );
01381     }
01382 }
01383 
01384 const int expected_ids[]  = { 2, 4, 6, 8, 10, 12, 14, 16, 18 };
01385 const int expected_vols[] = { 3, 7, 10 };
01386 
01387 void write_id_test_file()
01388 {
01389     Core moab;
01390     Interface& mb = moab;
01391     ErrorCode rval;
01392 
01393     // create 12 entity sets
01394     EntityHandle sets[12];
01395     for( int i = 0; i < 12; ++i )
01396     {
01397         rval = mb.create_meshset( MESHSET_SET, sets[i] );CHECK_ERR( rval );
01398     }
01399 
01400     // create tag handles
01401     Tag id = 0, gid = 0, dim = 0;
01402     mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id, MB_TAG_SPARSE | MB_TAG_EXCL );
01403     mb.tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, dim, MB_TAG_SPARSE | MB_TAG_EXCL );
01404     gid = mb.globalId_tag();
01405 
01406     // set ID tag on first 10 sets
01407     rval = mb.tag_set_data( id, sets, sizeof( expected_ids ) / sizeof( int ), expected_ids );CHECK_ERR( rval );
01408     // set geom dim on all sets, only three of them have dim == 3
01409     int num_vol = sizeof( expected_vols ) / sizeof( int );
01410     int dims[12], ids[12];
01411     int v = 0;
01412     for( int i = 0; i < 12; ++i )
01413     {
01414         dims[i] = i % 3 + 1;
01415         if( dims[i] == 3 )
01416         {
01417             if( v < num_vol )
01418                 ids[i] = expected_vols[v++];
01419             else
01420                 ids[i] = expected_vols[0];
01421         }
01422         else
01423             ids[i] = 100;
01424     }
01425     rval = mb.tag_set_data( gid, sets, 12, ids );CHECK_ERR( rval );
01426     rval = mb.tag_set_data( dim, sets, 12, dims );CHECK_ERR( rval );
01427 
01428     rval = mb.write_file( TEST_FILE, "MOAB" );CHECK_ERR( rval );
01429 }
01430 
01431 void test_read_ids()
01432 {
01433     write_id_test_file();
01434 
01435     Core moab;
01436     ReadHDF5 reader( &moab );
01437     FileOptions opts( "" );
01438     ErrorCode rval;
01439     std::vector< int > values;
01440     rval = reader.read_tag_values( TEST_FILE, ID_TAG_NAME, opts, values );
01441     remove( TEST_FILE );CHECK_ERR( rval );
01442 
01443     std::sort( values.begin(), values.end() );
01444     std::vector< int > expected( expected_ids, expected_ids + sizeof( expected_ids ) / sizeof( int ) );
01445     CHECK_EQUAL( expected, values );
01446 }
01447 
01448 void test_read_partial_ids()
01449 {
01450     write_id_test_file();
01451 
01452     const int three                = 3;
01453     ReaderIface::IDTag vols        = { GEOM_DIMENSION_TAG_NAME, &three, 1 };
01454     ReaderIface::SubsetList subset = { &vols, 1, 0, 0 };
01455 
01456     Core moab;
01457     ReadHDF5 reader( &moab );
01458     FileOptions opts( "" );
01459     ErrorCode rval;
01460     std::vector< int > values;
01461     rval = reader.read_tag_values( TEST_FILE, GLOBAL_ID_TAG_NAME, opts, values, &subset );
01462     remove( TEST_FILE );CHECK_ERR( rval );
01463 
01464     std::sort( values.begin(), values.end() );
01465     std::vector< int > expected( expected_ids, expected_ids + sizeof( expected_ids ) / sizeof( int ) );
01466 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines