MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 }