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