MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 #include <cstdio> 00017 #include <cmath> 00018 00019 #include "moab/Core.hpp" 00020 #include "moab/Range.hpp" 00021 #include "MBTagConventions.hpp" 00022 #include "moab/CN.hpp" 00023 00024 #define filename "h5test.h5m" 00025 00026 #include <iostream> 00027 #include <sstream> 00028 00029 using namespace moab; 00030 00031 // Dense tag name 00032 // Pick an ugly name to check special-char escaping in HDF5 file 00033 #define tagname "foo/\\/\\" 00034 #define bitname "bar\n" 00035 #define intname "int tag" 00036 #define dblname " dbl " 00037 #define handlename "hanlde" 00038 00039 const int FACE_SET_ID = 1101; 00040 const int VERTEX_SET_ID = 1102; 00041 const int REGION_SET_ID = 1103; 00042 const int EMPTY_SET_ID = 1100; 00043 const int SET_SET_ID = 1105; 00044 00045 Interface* iface; 00046 00047 void create(); 00048 00049 bool compare(); 00050 00051 void moab_error( const char* function ); 00052 00053 int main( int argc, char* argv[] ) 00054 { 00055 ErrorCode rval; 00056 std::string msg; 00057 00058 std::string read_opt; 00059 std::string write_opt( "DEBUG_BINIO" ); 00060 00061 for( int i = 1; i < argc; ++i ) 00062 { 00063 long val; 00064 char* endptr; 00065 if( argv[i][0] == '-' && ( argv[i][1] == 'r' || argv[i][1] == 'w' ) && i + 1 < argc && 00066 ( val = strtol( argv[i + 1], &endptr, 0 ) ) >= 0 && !*endptr ) 00067 { 00068 std::string& s = argv[i][1] == 'r' ? read_opt : write_opt; 00069 std::ostringstream str; 00070 str << "DEBUG_IO=" << val; 00071 if( s.empty() ) 00072 s = str.str(); 00073 else 00074 { 00075 s += ';'; 00076 s += str.str(); 00077 } 00078 ++i; 00079 } 00080 else 00081 { 00082 std::cerr << "Usage: " << argv[0] << " [-r <n>] [-w <n>]" << std::endl; 00083 return 1; 00084 } 00085 } 00086 00087 iface = new Core(); 00088 00089 // create a dodecahedron and inscribed hex 00090 fprintf( stderr, "creating... " ); 00091 create(); 00092 00093 // write out the dodecahedron 00094 fprintf( stderr, "writing... " ); 00095 rval = iface->write_file( filename, 0, write_opt.c_str() ); 00096 if( MB_SUCCESS != rval ) 00097 { 00098 fprintf( stderr, "Failed to write \"%s\"\n", filename ); 00099 if( MB_SUCCESS == iface->get_last_error( msg ) ) fprintf( stderr, "%s\n", msg.c_str() ); 00100 delete iface; 00101 return 1; 00102 } 00103 00104 // Read back in as a copy of the original 00105 fprintf( stderr, "reading... " ); 00106 rval = iface->load_file( filename, 0, read_opt.c_str() ); 00107 if( MB_SUCCESS != rval ) 00108 { 00109 fprintf( stderr, "Failed to read \"%s\"\n", filename ); 00110 if( MB_SUCCESS == iface->get_last_error( msg ) ) fprintf( stderr, "%s\n", msg.c_str() ); 00111 delete iface; 00112 return 1; 00113 } 00114 00115 // Compare the two. 00116 fprintf( stderr, "comparing... " ); 00117 if( !compare() ) 00118 { 00119 fprintf( stderr, "Comparison failed.\n" ); 00120 delete iface; 00121 return 1; 00122 } 00123 fprintf( stderr, "success!\n" ); 00124 00125 // Write both the original and copy to a file 00126 fprintf( stderr, "writing... " ); 00127 rval = iface->write_file( filename, 0, write_opt.c_str() ); 00128 if( MB_SUCCESS != rval ) 00129 { 00130 fprintf( stderr, "Failed to write \"%s\"\n", filename ); 00131 if( MB_SUCCESS == iface->get_last_error( msg ) ) fprintf( stderr, "%s\n", msg.c_str() ); 00132 delete iface; 00133 return 1; 00134 } 00135 00136 // Delete the mesh 00137 fprintf( stderr, "clearing db... " ); 00138 rval = iface->delete_mesh(); 00139 if( MB_SUCCESS != rval ) moab_error( "delete_mesh" ); 00140 00141 // Read the two dodecahedrons from the file 00142 fprintf( stderr, "reading... " ); 00143 rval = iface->load_file( filename, 0, read_opt.c_str() ); 00144 if( MB_SUCCESS != rval ) 00145 { 00146 fprintf( stderr, "Failed to read \"%s\"\n", filename ); 00147 if( MB_SUCCESS == iface->get_last_error( msg ) ) fprintf( stderr, "%s\n", msg.c_str() ); 00148 delete iface; 00149 return 1; 00150 } 00151 00152 // Compare them 00153 fprintf( stderr, "comparing... " ); 00154 if( !compare() ) 00155 { 00156 fprintf( stderr, "Comparison failed.\n" ); 00157 delete iface; 00158 return 1; 00159 } 00160 fprintf( stderr, "success!\n" ); 00161 00162 // Delete the mesh 00163 fprintf( stderr, "cleaning up... " ); 00164 rval = iface->delete_mesh(); 00165 if( MB_SUCCESS != rval ) moab_error( "delete_mesh" ); 00166 00167 // Clean up the file. 00168 remove( filename ); 00169 fprintf( stderr, "done.\n" ); 00170 delete iface; 00171 return 0; 00172 } 00173 00174 EntityHandle vtx( double x, double y, double z ) 00175 { 00176 const double p[3] = { x, y, z }; 00177 EntityHandle result; 00178 if( MB_SUCCESS != iface->create_vertex( p, result ) ) moab_error( "create_vertex" ); 00179 return result; 00180 } 00181 00182 EntityHandle pent( EntityHandle* vtx_list, int i1, int i2, int i3, int i4, int i5 ) 00183 { 00184 const EntityHandle conn[5] = { vtx_list[i1], vtx_list[i2], vtx_list[i3], vtx_list[i4], vtx_list[i5] }; 00185 EntityHandle result; 00186 if( MB_SUCCESS != iface->create_element( MBPOLYGON, conn, 5, result ) ) moab_error( "create_element" ); 00187 return result; 00188 } 00189 00190 // Create an entity set containing the passed entities. 00191 // options - set options to pass to create_meshset 00192 // entities - array of entities to put in set 00193 // num_entities - length of 'entities' 00194 // reverse - if true, add entities in reverse order 00195 // id - value for global id on set 00196 EntityHandle make_set( unsigned int options, EntityHandle* entities, size_t num_entities, bool reverse, int id ) 00197 { 00198 EntityHandle handle; 00199 if( MB_SUCCESS != iface->create_meshset( options, handle ) ) moab_error( "create_meshset" ); 00200 00201 if( reverse ) 00202 { 00203 for( int i = (int)num_entities - 1; i >= 0; --i ) 00204 if( MB_SUCCESS != iface->add_entities( handle, entities + i, 1 ) ) moab_error( "add_entities" ); 00205 } 00206 else 00207 { 00208 if( MB_SUCCESS != iface->add_entities( handle, entities, num_entities ) ) moab_error( "add_entities" ); 00209 } 00210 00211 Tag id_tag = iface->globalId_tag(); 00212 if( MB_SUCCESS != iface->tag_set_data( id_tag, &handle, 1, &id ) ) moab_error( "tag_set_data" ); 00213 00214 return handle; 00215 } 00216 00217 void create() 00218 { 00219 // Create dodecahedron 00220 00221 // radius 00222 const double r = 50.; 00223 // center 00224 const double x = 0., y = 0., z = 0.; 00225 // length of edge of inscribed cube 00226 const double cube = r * ( 2.0 / sqrt( 3.0 ) ); 00227 // length of dodecahedron edge 00228 const double edge = cube * ( 2.0 / ( 1.0 + sqrt( 5.0 ) ) ); 00229 // distance of projection of a dodecahedron vertex to 00230 // closest edge of inscribed cube 00231 const double p = ( cube - edge ) / 2.0; 00232 // distance of projection of a dodecahedron vertex to 00233 // closest face of inscribed cube 00234 const double d = sqrt( edge * edge - cube * cube / 4 - p ); 00235 // coordinate values 00236 const double c = cube / 2.0; 00237 const double a = c + d; 00238 const double b = edge / 2.0; 00239 00240 // list of vertex handles 00241 EntityHandle vertices[20]; 00242 // list of pentagon handles 00243 EntityHandle faces[12]; 00244 // Dodecahedron handle 00245 EntityHandle dodec; 00246 // Inscribed Hex handle 00247 EntityHandle hex; 00248 00249 // Create vertices if inscribed cube 00250 vertices[0] = vtx( x - c, y + c, z + c ); 00251 vertices[1] = vtx( x + c, y + c, z + c ); 00252 vertices[2] = vtx( x + c, y - c, z + c ); 00253 vertices[3] = vtx( x - c, y - c, z + c ); 00254 vertices[4] = vtx( x - c, y + c, z - c ); 00255 vertices[5] = vtx( x + c, y + c, z - c ); 00256 vertices[6] = vtx( x + c, y - c, z - c ); 00257 vertices[7] = vtx( x - c, y - c, z - c ); 00258 00259 // Create inscribed hex 00260 if( MB_SUCCESS != iface->create_element( MBHEX, vertices, 8, hex ) ) moab_error( "create_element" ); 00261 00262 // Create vertices, 2 "above" each face of inscribed cube 00263 // +z face 00264 vertices[8] = vtx( x - b, y, z + a ); 00265 vertices[9] = vtx( x + b, y, z + a ); 00266 // +x face 00267 vertices[10] = vtx( x + a, y + b, z ); 00268 vertices[11] = vtx( x + a, y - b, z ); 00269 // -z face 00270 vertices[12] = vtx( x - b, y, z - a ); 00271 vertices[13] = vtx( x + b, y, z - a ); 00272 // -x face 00273 vertices[14] = vtx( x - a, y + b, z ); 00274 vertices[15] = vtx( x - a, y - b, z ); 00275 // +y face 00276 vertices[16] = vtx( x, y + a, z + b ); 00277 vertices[17] = vtx( x, y + a, z - b ); 00278 // -y face 00279 vertices[18] = vtx( x, y - a, z + b ); 00280 vertices[19] = vtx( x, y - a, z - b ); 00281 00282 // Create petagons 00283 faces[0] = pent( vertices, 0, 8, 9, 1, 16 ); 00284 faces[1] = pent( vertices, 3, 18, 2, 9, 8 ); 00285 faces[2] = pent( vertices, 2, 11, 10, 1, 9 ); 00286 faces[3] = pent( vertices, 2, 18, 19, 6, 11 ); 00287 faces[4] = pent( vertices, 1, 10, 5, 17, 16 ); 00288 faces[5] = pent( vertices, 5, 10, 11, 6, 13 ); 00289 faces[6] = pent( vertices, 4, 17, 5, 13, 12 ); 00290 faces[7] = pent( vertices, 7, 12, 13, 6, 19 ); 00291 faces[8] = pent( vertices, 4, 12, 7, 15, 14 ); 00292 faces[9] = pent( vertices, 0, 16, 17, 4, 14 ); 00293 faces[10] = pent( vertices, 3, 15, 7, 19, 18 ); 00294 faces[11] = pent( vertices, 0, 14, 15, 3, 8 ); 00295 00296 // Create dodecahedron 00297 if( MB_SUCCESS != iface->create_element( MBPOLYHEDRON, faces, 12, dodec ) ) moab_error( "create_element" ); 00298 00299 // Create a dense tag 00300 int zero = 0; 00301 Tag tag; 00302 if( MB_SUCCESS != iface->tag_get_handle( tagname, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_EXCL, &zero ) ) 00303 moab_error( "tag_get_handle" ); 00304 00305 // Put dense tag on all vertices. 00306 for( int i = 0; i < 20; ++i ) 00307 if( MB_SUCCESS != iface->tag_set_data( tag, vertices + i, 1, &i ) ) moab_error( "tag_set_data" ); 00308 00309 // Create bit tag 00310 Tag tag2; 00311 if( MB_SUCCESS != iface->tag_get_handle( bitname, 2, MB_TYPE_BIT, tag2, MB_TAG_EXCL ) ) 00312 moab_error( "tag_get_handle" ); 00313 00314 // Set tag to 0 on Hex 00315 char two = '\002'; 00316 if( MB_SUCCESS != iface->tag_set_data( tag2, &hex, 1, &two ) ) moab_error( "tag_set_data" ); 00317 00318 // set tag to 1 on dodecahedron 00319 char one = '\001'; 00320 if( MB_SUCCESS != iface->tag_set_data( tag2, &dodec, 1, &one ) ) moab_error( "tag_set_data" ); 00321 00322 // Create an integer array tag and set some values on the dodecahedron 00323 Tag itag; 00324 if( MB_SUCCESS != iface->tag_get_handle( intname, 2, MB_TYPE_INTEGER, itag, MB_TAG_SPARSE | MB_TAG_EXCL ) ) 00325 moab_error( "tag_get_handle(MB_TYPE_INT)" ); 00326 int idata[] = { static_cast< int >( 0xDEADBEEF ), static_cast< int >( 0xDEFACED ) }; 00327 if( MB_SUCCESS != iface->tag_set_data( itag, &dodec, 1, idata ) ) moab_error( "tag_set_data(itag)" ); 00328 00329 // Create a double tag with a non-zero default value, and set on dodecahedron 00330 Tag dtag; 00331 double ddef = 3.14159; 00332 if( MB_SUCCESS != iface->tag_get_handle( dblname, 1, MB_TYPE_DOUBLE, dtag, MB_TAG_DENSE | MB_TAG_EXCL, &ddef ) ) 00333 moab_error( "tag_get_handle(dtag)" ); 00334 double dval = 0.333; 00335 if( MB_SUCCESS != iface->tag_set_data( dtag, &dodec, 1, &dval ) ) moab_error( "tag_set_data(dtag)" ); 00336 00337 // Create a tag containing entity handles, with default values 00338 Tag htag; 00339 EntityHandle hdef[] = { hex, dodec, 0 }; 00340 if( MB_SUCCESS != iface->tag_get_handle( handlename, 3, MB_TYPE_HANDLE, htag, MB_TAG_SPARSE | MB_TAG_EXCL, hdef ) ) 00341 moab_error( "tag_get_handle(htag)" ); 00342 // Set global (mesh) value for tag 00343 EntityHandle hgbl[] = { 0, hex, dodec }; 00344 const EntityHandle root = 0; 00345 if( MB_SUCCESS != iface->tag_set_data( htag, &root, 1, hgbl ) ) moab_error( "tag_set_data(hgbl)" ); 00346 // Store first three entiries of dodec connectivity on dodec 00347 EntityHandle hval[] = { faces[0], faces[1], faces[2] }; 00348 if( MB_SUCCESS != iface->tag_set_data( htag, &dodec, 1, hval ) ) moab_error( "tag_set_data(hgbl)" ); 00349 00350 // create some sets 00351 EntityHandle face_set, vertex_set, region_set, empty_set; 00352 EntityHandle regions[] = { dodec, hex }; 00353 const unsigned empty_flags = MESHSET_ORDERED | MESHSET_TRACK_OWNER; 00354 face_set = make_set( MESHSET_SET, faces, 12, false, FACE_SET_ID ); 00355 vertex_set = make_set( MESHSET_ORDERED, vertices, 20, true, VERTEX_SET_ID ); 00356 region_set = make_set( MESHSET_SET, regions, 2, false, REGION_SET_ID ); 00357 empty_set = make_set( empty_flags, 0, 0, true, EMPTY_SET_ID ); 00358 EntityHandle sets[] = { face_set, vertex_set, region_set, empty_set }; 00359 make_set( MESHSET_ORDERED, sets, 4, false, SET_SET_ID ); 00360 00361 // create some set parent-child links 00362 if( MB_SUCCESS != iface->add_parent_child( face_set, vertex_set ) ) moab_error( "add_parent_child" ); 00363 if( MB_SUCCESS != iface->add_child_meshset( region_set, face_set ) ) moab_error( "add_child_meshset" ); 00364 if( MB_SUCCESS != iface->add_parent_meshset( vertex_set, region_set ) ) moab_error( "add_parent_meshet" ); 00365 } 00366 00367 bool compare_conn( std::vector< EntityHandle >& conn1, std::vector< EntityHandle >& conn2 ) 00368 { 00369 unsigned i; 00370 00371 if( conn1.size() != conn2.size() || conn1.size() == 0 ) 00372 { 00373 fprintf( stderr, "Error comparing connectivity: sizes %lu and %lu\n", (unsigned long)conn1.size(), 00374 (unsigned long)conn2.size() ); 00375 return false; 00376 } 00377 00378 std::vector< double > coords[2]; 00379 coords[0].resize( 3 * conn1.size() ); 00380 coords[1].resize( 3 * conn2.size() ); 00381 if( MB_SUCCESS != iface->get_coords( &conn1[0], conn1.size(), &coords[0][0] ) || 00382 MB_SUCCESS != iface->get_coords( &conn2[0], conn2.size(), &coords[1][0] ) || 00383 coords[0].size() != coords[1].size() ) 00384 moab_error( "get_coords" ); 00385 00386 std::vector< double >::iterator citer1 = coords[0].begin(), citer2 = coords[1].begin(); 00387 for( i = 0; i < conn1.size(); i++ ) 00388 { 00389 double x1 = *( citer1++ ), y1 = *( citer1++ ), z1 = *( citer1++ ); 00390 double x2 = *( citer2++ ), y2 = *( citer2++ ), z2 = *( citer2++ ); 00391 if( x1 != x2 || y1 != y2 || z1 != z2 ) 00392 { 00393 fprintf( stderr, "Vertex coords don't match: ( %f, %f, %f ) and ( %f, %f, %f )\n", x1, y1, z1, x2, y2, z2 ); 00394 return false; 00395 } 00396 } 00397 00398 std::vector< int > tags[2]; 00399 tags[0].resize( conn1.size() ); 00400 tags[1].resize( conn2.size() ); 00401 Tag tag; 00402 if( MB_SUCCESS != iface->tag_get_handle( tagname, 1, MB_TYPE_INTEGER, tag ) ) moab_error( "tag_get_handle" ); 00403 if( MB_SUCCESS != iface->tag_get_data( tag, &conn1[0], conn1.size(), &tags[0][0] ) || 00404 MB_SUCCESS != iface->tag_get_data( tag, &conn2[0], conn2.size(), &tags[1][0] ) ) 00405 moab_error( "tag_get_data" ); 00406 00407 std::vector< int >::iterator titer1 = tags[0].begin(), titer2 = tags[1].begin(); 00408 for( i = 0; i < conn1.size(); i++ ) 00409 { 00410 int t1 = *( titer1++ ); 00411 int t2 = *( titer2++ ); 00412 if( t1 != t2 ) 00413 { 00414 fprintf( stderr, "Vertex tags don't match: %d != %d\n", t1, t2 ); 00415 return false; 00416 } 00417 } 00418 00419 return true; 00420 } 00421 00422 /* Compare the two sets with the specified global id. 00423 If tag_name is not null, compare all entities in the 00424 sets using the value of the tag to match entities. 00425 Tag must be an integer type. 00426 */ 00427 bool compare_sets( int id, const char* tag_name = 0 ) 00428 { 00429 bool ok; 00430 ErrorCode rval; 00431 00432 // get sets 00433 00434 Tag id_tag = iface->globalId_tag(); 00435 00436 Range range; 00437 const void* tag_data[] = { &id }; 00438 rval = iface->get_entities_by_type_and_tag( 0, MBENTITYSET, &id_tag, tag_data, 1, range ); 00439 if( MB_ENTITY_NOT_FOUND == rval || range.size() != 2 ) 00440 { 00441 fprintf( stderr, "Could not find set with id %d pair in file\n", id ); 00442 return false; 00443 } 00444 else if( MB_SUCCESS != rval ) 00445 moab_error( "get_entities_by_type_and_tag" ); 00446 00447 EntityHandle set1 = *range.begin(); 00448 EntityHandle set2 = *++range.begin(); 00449 00450 // Compare set descriptions 00451 unsigned opt1 = 0, opt2 = 0; 00452 rval = iface->get_meshset_options( set1, opt1 ); 00453 if( MB_SUCCESS != rval ) moab_error( "get_meshset_options for set1 failed" ); 00454 rval = iface->get_meshset_options( set2, opt2 ); 00455 if( MB_SUCCESS != rval ) moab_error( "get_meshset_options for set2 failed" ); 00456 00457 if( opt1 != opt2 ) 00458 { 00459 fprintf( stderr, 00460 "Sets with id %d do not have matching options.\n" 00461 "Set 1: track_owner=%s set=%s ordered=%s\n" 00462 "Set 2: track_owner=%s set=%s ordered=%s\n", 00463 id, opt1 & MESHSET_TRACK_OWNER ? "yes" : "no", opt1 & MESHSET_SET ? "yes" : "no", 00464 opt1 & MESHSET_ORDERED ? "yes" : "no", opt2 & MESHSET_TRACK_OWNER ? "yes" : "no", 00465 opt2 & MESHSET_SET ? "yes" : "no", opt2 & MESHSET_ORDERED ? "yes" : "no" ); 00466 return false; 00467 } 00468 00469 // Compare set contents 00470 // First check if same number of entities. 00471 // Then select from three possible methods to compare set contents 00472 // o If caller gave us a tag to use, compare entities by tag value 00473 // o If set is ordered, compare entity types in order 00474 // o Otherwise compare counts of entity types in sets 00475 std::vector< EntityHandle > list1, list2; 00476 rval = iface->get_entities_by_handle( set1, list1 ); 00477 if( MB_SUCCESS != rval ) moab_error( "get_entities_by_handle for set1 failed" ); 00478 rval = iface->get_entities_by_handle( set2, list2 ); 00479 if( MB_SUCCESS != rval ) moab_error( "get_entities_by_handle for set2 failed" ); 00480 00481 if( list1.size() != list2.size() ) 00482 { 00483 fprintf( stderr, 00484 "Sets with id %d do not have the same number of entities.\n" 00485 "Set 1 : %u Set 2 : %u\n", 00486 id, (unsigned)list1.size(), (unsigned)list2.size() ); 00487 return false; 00488 } 00489 00490 if( tag_name ) // compare contents using tag value 00491 { 00492 Tag tag; 00493 if( MB_SUCCESS != iface->tag_get_handle( tag_name, 0, MB_TYPE_OPAQUE, tag, MB_TAG_ANY ) ) 00494 { 00495 fprintf( stderr, "Could not find tag \"%s\" in file.\n", tag_name ); 00496 return false; 00497 } 00498 00499 // Make sure tag is integer type 00500 DataType type; 00501 if( MB_SUCCESS != iface->tag_get_data_type( tag, type ) ) moab_error( "tag_get_data_type" ); 00502 if( MB_TYPE_INTEGER != type && MB_TYPE_OPAQUE != type ) moab_error( "compare_sets" ); 00503 00504 std::vector< int > data1( list1.size() ), data2( list2.size() ); 00505 if( MB_SUCCESS != iface->tag_get_data( tag, &list1[0], list1.size(), &data1[0] ) || 00506 MB_SUCCESS != iface->tag_get_data( tag, &list2[0], list2.size(), &data2[0] ) ) 00507 moab_error( "tag_get_data" ); 00508 00509 if( !( opt1 & MESHSET_ORDERED ) ) 00510 { 00511 std::sort( data1.begin(), data1.end() ); 00512 std::sort( data2.begin(), data2.end() ); 00513 } 00514 00515 for( unsigned i = 0; i < data1.size(); ++i ) 00516 if( data1[i] != data2[i] ) 00517 { 00518 fprintf( stderr, "Entities in sets with id %d do not have matching tag values.\n", id ); 00519 return false; 00520 } 00521 } 00522 else if( opt1 & MESHSET_ORDERED ) // compare types of each entity in set 00523 { 00524 ok = true; 00525 for( unsigned i = 0; i < list1.size(); ++i ) 00526 if( iface->type_from_handle( list1[i] ) != iface->type_from_handle( list2[i] ) ) 00527 { 00528 fprintf( stderr, 00529 "Entities at position %u in ordered sets with id %d\n" 00530 "have different types.\n", 00531 i, id ); 00532 ok = false; 00533 } 00534 if( !ok ) return false; 00535 } 00536 else // compare count of entity types in each set 00537 { 00538 unsigned counts1[MBMAXTYPE], counts2[MBMAXTYPE]; 00539 memset( counts1, 0, MBMAXTYPE * sizeof( unsigned ) ); 00540 memset( counts2, 0, MBMAXTYPE * sizeof( unsigned ) ); 00541 for( unsigned i = 0; i < list1.size(); ++i ) 00542 { 00543 counts1[iface->type_from_handle( list1[i] )]++; 00544 counts2[iface->type_from_handle( list2[i] )]++; 00545 } 00546 00547 ok = true; 00548 for( int j = 0; j < MBMAXTYPE; ++j ) 00549 if( counts1[j] != counts2[j] ) 00550 { 00551 fprintf( stderr, "Sets with id %d have differing numbers of %s: %u and %u\n", id, 00552 CN::EntityTypeName( (EntityType)j ), counts1[j], counts2[j] ); 00553 ok = false; 00554 } 00555 if( !ok ) return false; 00556 } 00557 00558 // Compare set parent/child links using global id 00559 00560 ok = true; 00561 const char* words[] = { "children", "parents" }; 00562 std::vector< EntityHandle > adj1, adj2; 00563 for( unsigned two = 0; two < 2; ++two ) 00564 { 00565 adj1.clear(); 00566 adj2.clear(); 00567 if( two ) 00568 { 00569 if( MB_SUCCESS != iface->get_parent_meshsets( set1, adj1 ) || 00570 MB_SUCCESS != iface->get_parent_meshsets( set2, adj2 ) ) 00571 moab_error( "get_parent_meshsets" ); 00572 } 00573 else 00574 { 00575 if( MB_SUCCESS != iface->get_child_meshsets( set1, adj1 ) || 00576 MB_SUCCESS != iface->get_child_meshsets( set2, adj2 ) ) 00577 moab_error( "get_child_meshsets" ); 00578 } 00579 00580 if( adj1.size() != adj2.size() ) 00581 { 00582 fprintf( stderr, "Sets with id %d have different number of %s: %u and %u\n", id, words[two], 00583 (unsigned)adj1.size(), (unsigned)adj2.size() ); 00584 ok = false; 00585 continue; 00586 } 00587 00588 std::vector< int > ids1( adj1.size() ), ids2( adj2.size() ); 00589 unsigned i; 00590 for( i = 0; i < adj1.size(); ++i ) 00591 { 00592 rval = iface->tag_get_data( id_tag, &adj1[i], 1, &ids1[i] ); 00593 if( MB_TAG_NOT_FOUND == rval ) 00594 ids1[i] = 0; 00595 else if( MB_SUCCESS != rval ) 00596 moab_error( "tag_get_data" ); 00597 00598 rval = iface->tag_get_data( id_tag, &adj2[i], 1, &ids2[i] ); 00599 if( MB_TAG_NOT_FOUND == rval ) 00600 ids2[i] = 0; 00601 else if( MB_SUCCESS != rval ) 00602 moab_error( "tag_get_data" ); 00603 } 00604 00605 std::sort( ids1.begin(), ids1.end() ); 00606 std::sort( ids2.begin(), ids2.end() ); 00607 for( i = 0; i < ids1.size(); ++i ) 00608 { 00609 if( ids1[i] != ids2[i] ) 00610 { 00611 fprintf( stderr, "Sets with id %d have non-matching %s\n", id, words[two] ); 00612 ok = false; 00613 break; 00614 } 00615 } 00616 } 00617 return ok; 00618 } 00619 00620 bool compare_tags( EntityHandle dod[] ) 00621 { 00622 Tag tag; 00623 00624 // Get integer tag handle and characterstics 00625 if( MB_SUCCESS != iface->tag_get_handle( intname, 2, MB_TYPE_INTEGER, tag, MB_TAG_SPARSE | MB_TAG_STORE ) ) 00626 moab_error( "tag_get_handle(intname)" ); 00627 00628 // integer tag should not have a default value 00629 int idata[4]; 00630 if( MB_ENTITY_NOT_FOUND != iface->tag_get_default_value( tag, idata ) ) 00631 { 00632 fprintf( stderr, "tag_get_default_value() for nonexistant default integer tag value did " 00633 "not fail correctly.\n" ); 00634 return false; 00635 } 00636 00637 // check data for integer tag on both dodecahedrons 00638 if( MB_SUCCESS != iface->tag_get_data( tag, dod, 2, idata ) ) moab_error( "tag_get_data(itag)" ); 00639 if( idata[0] != (int)0xDEADBEEF || idata[1] != (int)0xDEFACED || idata[2] != idata[0] || idata[3] != idata[1] ) 00640 { 00641 fprintf( stderr, "Incorrect values for integer tag data.\n" ); 00642 return false; 00643 } 00644 00645 // Get double tag handle and characterstics 00646 if( MB_SUCCESS != iface->tag_get_handle( dblname, 1, MB_TYPE_DOUBLE, tag, MB_TAG_DENSE | MB_TAG_STORE ) ) 00647 moab_error( "tag_get_handle(dblname)" ); 00648 00649 // check default value of double tag 00650 double ddata[2]; 00651 if( MB_SUCCESS != iface->tag_get_default_value( tag, ddata ) ) moab_error( "tag_get_default_value" ); 00652 if( ddata[0] != 3.14159 ) 00653 { 00654 fprintf( stderr, "incorrect default value for double tag.\n" ); 00655 return false; 00656 } 00657 00658 // check data for double tag on both dodecahedrons 00659 if( MB_SUCCESS != iface->tag_get_data( tag, dod, 2, ddata ) ) moab_error( "tag_get_data()" ); 00660 if( ddata[0] != .333 || ddata[0] != ddata[1] ) 00661 { 00662 fprintf( stderr, "Incorrect values for double tag data.\n" ); 00663 return false; 00664 } 00665 00666 // Get handle tag handle and characterstics 00667 if( MB_SUCCESS != iface->tag_get_handle( handlename, 3, MB_TYPE_HANDLE, tag, MB_TAG_SPARSE | MB_TAG_STORE ) ) 00668 moab_error( "tag_get_handle(handlename)" ); 00669 00670 // check default value of handle tag 00671 // default value will not change after tag is created. As we 00672 // do multiple iterations of save/restore, we shouldn't expect 00673 // the dodecahedron handles to point to the most recent two. 00674 EntityHandle hdata[6]; 00675 if( MB_SUCCESS != iface->tag_get_default_value( tag, hdata ) ) moab_error( "tag_get_default_value" ); 00676 if( iface->type_from_handle( hdata[0] ) != MBHEX || hdata[2] != 0 || 00677 iface->type_from_handle( hdata[1] ) != MBPOLYHEDRON ) 00678 { 00679 fprintf( stderr, "incorrect default value for handle tag '%s'\n", handlename ); 00680 return false; 00681 } 00682 00683 // check global value for handle tag 00684 // global value should be changed each time a new global is read, 00685 // so expect one of the two dodecahedrons in the last slot. 00686 const EntityHandle root = 0; 00687 if( MB_SUCCESS != iface->tag_get_data( tag, &root, 1, hdata ) ) moab_error( "tag_get_data(mesh)" ); 00688 if( iface->type_from_handle( hdata[1] ) != MBHEX || hdata[0] != 0 || ( hdata[2] != dod[0] && hdata[2] != dod[1] ) ) 00689 { 00690 fprintf( stderr, "incorrect global/mesh value for handle tag.\n" ); 00691 return false; 00692 } 00693 00694 // check data on each dodecahedron 00695 const EntityHandle* conn; 00696 int len; 00697 if( MB_SUCCESS != iface->tag_get_data( tag, dod, 2, hdata ) ) moab_error( "tag_get_data()" ); 00698 if( MB_SUCCESS != iface->get_connectivity( dod[0], conn, len ) ) moab_error( "get_connectivity" ); 00699 if( memcmp( conn, hdata, 3 * sizeof( EntityHandle ) ) ) 00700 { 00701 fprintf( stderr, "Incorrect values for handle tag data.\n" ); 00702 return false; 00703 } 00704 if( MB_SUCCESS != iface->get_connectivity( dod[1], conn, len ) ) moab_error( "get_connectivity" ); 00705 if( memcmp( conn, hdata + 3, 3 * sizeof( EntityHandle ) ) ) 00706 { 00707 fprintf( stderr, "Incorrect values for handle tag data.\n" ); 00708 return false; 00709 } 00710 00711 return true; 00712 } 00713 00714 bool compare() 00715 { 00716 Range range; 00717 EntityHandle hex[2]; 00718 EntityHandle dod[2]; 00719 Tag elemtag; 00720 Range::iterator iter; 00721 00722 // get tag 00723 if( MB_SUCCESS != iface->tag_get_handle( bitname, 2, MB_TYPE_BIT, elemtag ) ) moab_error( "tag_get_handle" ); 00724 00725 // get two hexes 00726 char two = '\002'; 00727 const void* tarray[] = { &two }; 00728 if( MB_SUCCESS != iface->get_entities_by_type_and_tag( 0, MBHEX, &elemtag, tarray, 1, range ) ) 00729 moab_error( "get_entities_by_type_and_tag" ); 00730 if( range.size() != 2 ) 00731 { 00732 fprintf( stderr, "Expected 2 Hexes. Got %lu\n", (unsigned long)range.size() ); 00733 exit( 1 ); 00734 } 00735 iter = range.begin(); 00736 hex[0] = *iter; 00737 hex[1] = *++iter; 00738 00739 // get two polyhedra 00740 range.clear(); 00741 char one = '\001'; 00742 const void* oarray[] = { &one }; 00743 if( MB_SUCCESS != iface->get_entities_by_type_and_tag( 0, MBPOLYHEDRON, &elemtag, oarray, 1, range ) ) 00744 moab_error( "get_entities_by_type_and_tag" ); 00745 if( range.size() != 2 ) 00746 { 00747 fprintf( stderr, "Expected 2 Polyhedra. Got %lu\n", (unsigned long)range.size() ); 00748 exit( 1 ); 00749 } 00750 iter = range.begin(); 00751 dod[0] = *iter; 00752 dod[1] = *++iter; 00753 00754 // compare hexes 00755 std::vector< EntityHandle > conn[2]; 00756 if( MB_SUCCESS != iface->get_connectivity( hex, 1, conn[0] ) || 00757 MB_SUCCESS != iface->get_connectivity( hex + 1, 1, conn[1] ) ) 00758 moab_error( "get_connectivity" ); 00759 if( !compare_conn( conn[0], conn[1] ) ) return false; 00760 00761 // compare polyhedra 00762 00763 std::vector< EntityHandle > face[2]; 00764 conn[0].clear(); 00765 conn[1].clear(); 00766 if( MB_SUCCESS != iface->get_connectivity( dod, 1, conn[0], false ) || 00767 MB_SUCCESS != iface->get_connectivity( dod + 1, 1, conn[1], false ) ) 00768 moab_error( "get_connectivity" ); 00769 if( conn[0].size() != 12 || conn[1].size() != 12 ) 00770 { 00771 fprintf( stderr, 00772 "Expected two dodecahedrons. Got polyhedrons with " 00773 "%lu and %lu faces respectively.\n", 00774 (unsigned long)conn[0].size(), (unsigned long)conn[1].size() ); 00775 return false; 00776 } 00777 00778 for( int i = 0; i < 12; ++i ) 00779 { 00780 face[0].clear(); 00781 face[1].clear(); 00782 if( MB_SUCCESS != iface->get_connectivity( &conn[0][i], 1, face[0], false ) || 00783 MB_SUCCESS != iface->get_connectivity( &conn[1][i], 1, face[1], false ) ) 00784 moab_error( "get_connectivity" ); 00785 if( !compare_conn( face[0], face[1] ) ) return false; 00786 } 00787 00788 // compare sets 00789 00790 if( !compare_sets( VERTEX_SET_ID, tagname ) || !compare_sets( FACE_SET_ID ) || !compare_sets( REGION_SET_ID ) || 00791 !compare_sets( EMPTY_SET_ID ) || !compare_sets( SET_SET_ID, GLOBAL_ID_TAG_NAME ) ) 00792 return false; 00793 00794 // check tags 00795 if( !compare_tags( dod ) ) return false; 00796 00797 return true; 00798 } 00799 00800 void moab_error( const char* str ) 00801 { 00802 std::string msg; 00803 fprintf( stderr, "%s() failed.\n", str ); 00804 if( MB_SUCCESS == iface->get_last_error( msg ) ) fprintf( stderr, "%s\n", msg.c_str() ); 00805 delete iface; 00806 exit( 1 ); 00807 }