MOAB: Mesh Oriented datABase  (version 5.3.1)
h5file_test.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines