MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include <iostream> 00002 #include <cstdlib> 00003 #include <vector> 00004 #include <set> 00005 #include <string> 00006 #include <cstdio> 00007 #include <iomanip> 00008 #include "moab/MOABConfig.h" 00009 #ifndef WIN32 00010 #include <sys/times.h> 00011 #include <climits> 00012 #include <unistd.h> 00013 #endif 00014 #include <ctime> 00015 #ifdef MOAB_HAVE_MPI 00016 #include "moab_mpi.h" 00017 #endif 00018 #if !defined( _MSC_VER ) && !defined( __MINGW32__ ) 00019 #include <termios.h> 00020 #include <sys/ioctl.h> 00021 #endif 00022 #include <cmath> 00023 #include <cassert> 00024 #include <cfloat> 00025 00026 #include "moab/Core.hpp" 00027 #include "moab/Range.hpp" 00028 #include "MBTagConventions.hpp" 00029 #include "moab/Interface.hpp" 00030 #include "moab/ReaderWriterSet.hpp" 00031 00032 /* Exit values */ 00033 #define USAGE_ERROR 1 00034 #define READ_ERROR 2 00035 #define WRITE_ERROR 3 00036 #define OTHER_ERROR 4 00037 #define ENT_NOT_FOUND 5 00038 00039 using namespace moab; 00040 00041 #include "measure.hpp" 00042 00043 static void print_usage( const char* name, std::ostream& stream ) 00044 { 00045 stream << "Usage: " << name << " <options> <input_file> [<input_file2> ...]" << std::endl 00046 << "Options: " << std::endl 00047 << "\t-f - List available file formats and exit." << std::endl 00048 << "\t-g - print counts by geometric owner" << std::endl 00049 << "\t-h - Print this help text and exit." << std::endl 00050 << "\t-l - Print counts of mesh" << std::endl 00051 << "\t-ll - Verbose listing of every entity" << std::endl 00052 << "\t-m - Print counts per block/boundary" << std::endl 00053 << "\t-O option - Specify read option." << std::endl 00054 #ifdef MOAB_HAVE_MPI 00055 << "\t-p[0|1|2] - Read in parallel[0], optionally also doing resolve_shared_ents " 00056 "(1) and exchange_ghosts (2)" 00057 << std::endl 00058 #endif 00059 << "\t-t - Print counts by tag" << std::endl 00060 << "\t-T - Time read of files." << std::endl 00061 << "\t-- - treat all subsequent options as file names" << std::endl 00062 << "\t (allows file names beginning with '-')" << std::endl; 00063 } 00064 00065 Core mb; 00066 00067 struct stat_set 00068 { 00069 double sum; 00070 double sqr; 00071 double min; 00072 double max; 00073 long count; 00074 00075 inline stat_set() : sum( 0 ), sqr( 0 ), min( HUGE_VAL ), max( 0 ), count( 0 ) {} 00076 00077 inline void add( double val ) 00078 { 00079 if( val < min ) min = val; 00080 if( val > max ) max = val; 00081 sum += val; 00082 sqr += val * val; 00083 ++count; 00084 } 00085 00086 inline void add( const stat_set& stats ) 00087 { 00088 if( stats.min < min ) min = stats.min; 00089 if( stats.max > max ) max = stats.max; 00090 sum += stats.sum; 00091 sqr += stats.sqr; 00092 count += stats.count; 00093 } 00094 00095 inline void clear() 00096 { 00097 sum = sqr = 0.0; 00098 max = count = 0; 00099 min = HUGE_VAL; 00100 } 00101 }; 00102 00103 struct set_stats 00104 { 00105 stat_set stats[MBMAXTYPE]; 00106 stat_set edge_uses; 00107 size_t nodes; 00108 00109 void add( const set_stats& other ) 00110 { 00111 for( int i = 0; i < MBMAXTYPE; ++i ) 00112 stats[i].add( other.stats[i] ); 00113 edge_uses.add( other.edge_uses ); 00114 } 00115 00116 void clear() 00117 { 00118 for( int i = 0; i < MBMAXTYPE; ++i ) 00119 stats[i].clear(); 00120 edge_uses.clear(); 00121 } 00122 }; 00123 00124 static ErrorCode gather_set_stats( EntityHandle set, set_stats& stats ) 00125 { 00126 int count; 00127 ErrorCode rval = mb.get_number_entities_by_type( set, MBVERTEX, count ); 00128 if( MB_SUCCESS != rval ) return rval; 00129 stats.nodes = count; 00130 00131 int edge_vtx_idx[2]; 00132 std::vector< EntityHandle > conn; 00133 std::vector< double > coords; 00134 for( EntityType type = MBEDGE; type < MBENTITYSET; ++type ) 00135 { 00136 int num_edges = CN::NumSubEntities( type, 1 ); 00137 00138 Range range; 00139 rval = mb.get_entities_by_type( set, type, range, true ); 00140 if( MB_SUCCESS != rval ) return rval; 00141 for( Range::iterator i = range.begin(); i != range.end(); ++i ) 00142 { 00143 rval = mb.get_connectivity( &*i, 1, conn, true ); 00144 if( MB_SUCCESS != rval ) return rval; 00145 if( type == MBPOLYHEDRON ) 00146 { 00147 std::vector< EntityHandle > dum_conn( conn ); 00148 conn.clear(); 00149 rval = mb.get_adjacencies( &dum_conn[0], dum_conn.size(), 0, false, conn, Interface::UNION ); 00150 if( MB_SUCCESS != rval ) return rval; 00151 } 00152 coords.resize( 3 * conn.size() ); 00153 rval = mb.get_coords( &conn[0], conn.size(), &coords[0] ); 00154 if( MB_SUCCESS != rval ) return rval; 00155 stats.stats[type].add( measure( type, conn.size(), &coords[0] ) ); 00156 00157 if( type != MBEDGE ) 00158 { 00159 if( type == MBPOLYGON ) num_edges = conn.size(); 00160 00161 for( int e = 0; e < num_edges; ++e ) 00162 { 00163 if( type == MBPOLYGON ) 00164 { 00165 edge_vtx_idx[0] = e; 00166 edge_vtx_idx[1] = ( e + 1 ) % num_edges; 00167 } 00168 else 00169 CN::SubEntityVertexIndices( type, 1, e, edge_vtx_idx ); 00170 stats.edge_uses.add( edge_length( &coords[3 * edge_vtx_idx[0]], &coords[3 * edge_vtx_idx[1]] ) ); 00171 } 00172 } 00173 } 00174 } 00175 return MB_SUCCESS; 00176 } 00177 00178 struct TagCounts 00179 { 00180 TagCounts( std::string n ) : name( n ) 00181 { 00182 std::fill( counts, counts + MBMAXTYPE, 0 ); 00183 } 00184 std::string name; 00185 int counts[MBMAXTYPE]; 00186 }; 00187 00188 static ErrorCode gather_tag_counts( EntityHandle set, std::vector< TagCounts >& counts ) 00189 { 00190 std::vector< Tag > tags; 00191 mb.tag_get_tags( tags ); 00192 for( size_t i = 0; i < tags.size(); ++i ) 00193 { 00194 std::string name; 00195 ErrorCode rval = mb.tag_get_name( tags[i], name ); 00196 if( MB_SUCCESS != rval || name.empty() ) continue; 00197 00198 counts.push_back( name ); 00199 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00200 mb.get_number_entities_by_type_and_tag( set, t, &tags[i], 0, 1, counts.back().counts[t] ); 00201 } 00202 00203 return MB_SUCCESS; 00204 } 00205 00206 void add_tag_counts( std::vector< TagCounts >& counts, const std::vector< TagCounts >& add ) 00207 { 00208 for( size_t i = 0; i < add.size(); ++i ) 00209 { 00210 size_t j; 00211 for( j = 0; j < counts.size(); ++j ) 00212 if( add[i].name == counts[j].name ) break; 00213 if( j == counts.size() ) 00214 { 00215 counts.push_back( add[i] ); 00216 continue; 00217 } 00218 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00219 counts[j].counts[t] += add[i].counts[t]; 00220 } 00221 } 00222 00223 static const char* dashes( unsigned count ) 00224 { 00225 static std::vector< char > dashes; 00226 dashes.clear(); 00227 dashes.resize( count + 1, '-' ); 00228 dashes[count] = '\0'; 00229 return &dashes[0]; 00230 } 00231 00232 static void print_tag_counts( const std::vector< TagCounts >& counts ) 00233 { 00234 if( counts.empty() ) 00235 { 00236 printf( "<No tags>\n" ); 00237 return; 00238 } 00239 00240 int widths[MBMAXTYPE] = { 0 }; 00241 int name_width = 0; 00242 for( size_t i = 0; i < counts.size(); ++i ) 00243 { 00244 if( counts[i].name.length() > (unsigned)name_width ) name_width = counts[i].name.length(); 00245 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00246 if( counts[i].counts[t] != 0 ) widths[t] = std::max( 8, (int)strlen( CN::EntityTypeName( t ) ) ); 00247 } 00248 00249 if( 0 == std::min_element( widths, widths + MBMAXTYPE ) ) 00250 { 00251 printf( "<No Tagged Entities>\n" ); 00252 return; 00253 } 00254 00255 // Print header line 00256 const char* name_title = "Tag Name"; 00257 if( (unsigned)name_width < strlen( name_title ) ) name_width = strlen( name_title ); 00258 printf( "%*s", name_width, name_title ); 00259 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00260 if( widths[t] ) printf( " %*s", widths[t], CN::EntityTypeName( t ) ); 00261 printf( "\n%s", dashes( name_width ) ); 00262 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00263 if( widths[t] ) printf( " %s", dashes( widths[t] ) ); 00264 printf( "\n" ); 00265 00266 // print data 00267 for( size_t i = 0; i < counts.size(); ++i ) 00268 { 00269 printf( "%*s", name_width, counts[i].name.c_str() ); 00270 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00271 if( widths[t] ) printf( " %*d", widths[t], counts[i].counts[t] ); 00272 printf( "\n" ); 00273 } 00274 } 00275 00276 static void print_stats( set_stats& stats ) 00277 { 00278 const char* edge_use_name = "1D Side"; 00279 const char* vertex_name = "Vertex"; 00280 00281 bool have_some = stats.edge_uses.count > 0 || stats.nodes > 0; 00282 for( int i = 0; i < MBMAXTYPE; ++i ) 00283 if( stats.stats[i].count > 0 ) have_some = true; 00284 00285 if( !have_some ) 00286 { 00287 std::cout << "NO MESH" << std::endl; 00288 return; 00289 } 00290 00291 // get field widths 00292 unsigned type_width = std::max( strlen( vertex_name ), strlen( edge_use_name ) ); 00293 unsigned count_width = 5; 00294 unsigned total_width = 5; 00295 unsigned total_prec = 2; 00296 unsigned precision = 5; 00297 int total_log = -10000; 00298 00299 unsigned node_count_width = (unsigned)( ceil( log10( (double)stats.nodes ) ) ) + 1; 00300 if( count_width < node_count_width ) count_width = node_count_width; 00301 00302 for( EntityType i = MBEDGE; i < MBMAXTYPE; ++i ) 00303 { 00304 stat_set& s = stats.stats[i]; 00305 00306 if( s.count == 0 ) continue; 00307 00308 unsigned len = strlen( CN::EntityTypeName( i ) ); 00309 if( len > type_width ) type_width = len; 00310 00311 unsigned cw = (unsigned)( ceil( log10( (double)s.count ) ) ) + 1; 00312 if( cw > count_width ) count_width = cw; 00313 00314 int tl = (unsigned)( ceil( log10( fabs( s.sum ) ) ) ) + 1; 00315 if( tl > total_log ) total_log = tl; 00316 } 00317 00318 if( total_log > (int)total_width || total_log == -10000 ) 00319 { 00320 total_width = 8; 00321 total_prec = 2; 00322 } 00323 else if( total_log <= -(int)total_width ) 00324 { 00325 total_width = -total_log + 5; 00326 total_prec = 2; 00327 } 00328 else if( total_log < 1 ) 00329 { 00330 total_width = -total_log + 4; 00331 total_prec = -total_log + 1; 00332 } 00333 else 00334 { 00335 total_width += 2; 00336 } 00337 00338 // get terminal width 00339 unsigned term_width = 80; 00340 #if !defined( _MSC_VER ) && !defined( __MINGW32__ ) 00341 struct winsize size; 00342 if( ioctl( fileno( stdout ), TIOCGWINSZ, (char*)&size ) == 0 ) term_width = size.ws_col; 00343 if( !term_width ) term_width = 80; 00344 #endif 00345 assert( term_width > 7 + type_width + count_width + total_width ); 00346 00347 term_width -= 7; // spaces 00348 term_width -= type_width; 00349 term_width -= count_width; 00350 term_width -= total_width; 00351 unsigned val_width = term_width / 5; 00352 if( val_width < 8 ) val_width = 8; 00353 00354 printf( "%*s %*s %*s %*s %*s %*s %*s %*s\n", type_width, "type", count_width, "count", total_width, "total", 00355 val_width, "minimum", val_width, "average", val_width, "rms", val_width, "maximum", val_width, "std.dev." ); 00356 00357 printf( "%*s ", type_width, dashes( type_width ) ); 00358 printf( "%*s ", count_width, dashes( count_width ) ); 00359 printf( "%*s ", total_width, dashes( total_width ) ); 00360 printf( "%*s ", val_width, dashes( val_width ) ); 00361 printf( "%*s ", val_width, dashes( val_width ) ); 00362 printf( "%*s ", val_width, dashes( val_width ) ); 00363 printf( "%*s ", val_width, dashes( val_width ) ); 00364 printf( "%*s\n", val_width, dashes( val_width ) ); 00365 00366 for( EntityType i = MBEDGE; i <= MBMAXTYPE; ++i ) 00367 { 00368 stat_set& s = ( i == MBMAXTYPE ) ? stats.edge_uses : stats.stats[i]; 00369 00370 if( s.count == 0 ) continue; 00371 00372 double tmp_dbl = s.sqr / s.count - s.sum * s.sum / (double)s.count / (double)s.count; 00373 if( tmp_dbl < 0.0 ) 00374 { 00375 if( tmp_dbl < -100.0 * DBL_EPSILON ) 00376 std::cout << "WARNING: stat values dubious, s^2 - sig_s = " << tmp_dbl << std::endl; 00377 tmp_dbl = 0.0; 00378 } 00379 00380 printf( "%*s %*ld %*.*g %*.*g %*.*g %*.*g %*.*g %*.*g\n", type_width, 00381 i == MBMAXTYPE ? edge_use_name : CN::EntityTypeName( i ), count_width, s.count, total_width, total_prec, 00382 s.sum, val_width, precision, s.min, val_width, precision, s.sum / s.count, val_width, precision, 00383 sqrt( s.sqr / s.count ), val_width, precision, s.max, val_width, precision, sqrt( tmp_dbl ) ); 00384 } 00385 printf( "%*s %*lu\n", type_width, vertex_name, count_width, (unsigned long)stats.nodes ); 00386 00387 puts( "" ); 00388 } 00389 00390 bool parse_id_list( const char* string, std::set< int >& results ) 00391 { 00392 bool okay = true; 00393 char* mystr = strdup( string ); 00394 for( const char* ptr = strtok( mystr, "," ); ptr; ptr = strtok( 0, "," ) ) 00395 { 00396 char* endptr; 00397 long val = strtol( ptr, &endptr, 0 ); 00398 if( endptr == ptr || val <= 0 ) 00399 { 00400 std::cerr << "Not a valid id: " << ptr << std::endl; 00401 okay = false; 00402 break; 00403 } 00404 00405 long val2 = val; 00406 if( *endptr == '-' ) 00407 { 00408 const char* sptr = endptr + 1; 00409 val2 = strtol( sptr, &endptr, 0 ); 00410 if( endptr == sptr || val2 <= 0 ) 00411 { 00412 std::cerr << "Not a valid id: " << sptr << std::endl; 00413 okay = false; 00414 break; 00415 } 00416 if( val2 < val ) 00417 { 00418 std::cerr << "Invalid id range: " << ptr << std::endl; 00419 okay = false; 00420 break; 00421 } 00422 } 00423 00424 if( *endptr ) 00425 { 00426 std::cerr << "Unexpected character: " << *endptr << std::endl; 00427 okay = false; 00428 break; 00429 } 00430 00431 for( ; val <= val2; ++val ) 00432 if( !results.insert( (int)val ).second ) std::cerr << "Warning: duplicate Id: " << val << std::endl; 00433 } 00434 00435 free( mystr ); 00436 return okay; 00437 } 00438 00439 bool make_opts_string( std::vector< std::string > options, std::string& opts ) 00440 { 00441 opts.clear(); 00442 if( options.empty() ) return true; 00443 00444 // choose a separator character 00445 std::vector< std::string >::const_iterator i; 00446 char separator = '\0'; 00447 const char* alt_separators = ";+,:\t\n"; 00448 for( const char* sep_ptr = alt_separators; *sep_ptr; ++sep_ptr ) 00449 { 00450 bool seen = false; 00451 for( i = options.begin(); i != options.end(); ++i ) 00452 if( i->find( *sep_ptr, 0 ) != std::string::npos ) 00453 { 00454 seen = true; 00455 break; 00456 } 00457 if( !seen ) 00458 { 00459 separator = *sep_ptr; 00460 break; 00461 } 00462 } 00463 if( !separator ) 00464 { 00465 std::cerr << "Error: cannot find separator character for options string" << std::endl; 00466 return false; 00467 } 00468 if( separator != ';' ) 00469 { 00470 opts = ";"; 00471 opts += separator; 00472 } 00473 00474 // concatenate options 00475 i = options.begin(); 00476 opts += *i; 00477 for( ++i; i != options.end(); ++i ) 00478 { 00479 opts += separator; 00480 opts += *i; 00481 } 00482 00483 return true; 00484 } 00485 00486 void list_formats( Interface* gMB ) 00487 { 00488 const char iface_name[] = "ReaderWriterSet"; 00489 ErrorCode err; 00490 ReaderWriterSet* set = 0; 00491 ReaderWriterSet::iterator i; 00492 std::ostream& str = std::cout; 00493 00494 // get ReaderWriterSet 00495 err = gMB->query_interface( set ); 00496 if( err != MB_SUCCESS || !set ) 00497 { 00498 std::cerr << "Internal error: Interface \"" << iface_name << "\" not available.\n"; 00499 exit( OTHER_ERROR ); 00500 } 00501 00502 // get field width for format description 00503 size_t w = 0; 00504 for( i = set->begin(); i != set->end(); ++i ) 00505 if( i->description().length() > w ) w = i->description().length(); 00506 00507 // write table header 00508 str << "Format " << std::setw( w ) << std::left << "Description" 00509 << " Read Write File Name Suffixes\n" 00510 << "------ " << std::setw( w ) << std::setfill( '-' ) << "" << std::setfill( ' ' ) 00511 << " ---- ----- ------------------\n"; 00512 00513 // write table data 00514 for( i = set->begin(); i != set->end(); ++i ) 00515 { 00516 std::vector< std::string > ext; 00517 i->get_extensions( ext ); 00518 str << std::setw( 6 ) << i->name() << " " << std::setw( w ) << std::left << i->description() << " " 00519 << ( i->have_reader() ? " yes" : " no" ) << " " << ( i->have_writer() ? " yes" : " no" ) << " "; 00520 for( std::vector< std::string >::iterator j = ext.begin(); j != ext.end(); ++j ) 00521 str << " " << *j; 00522 str << std::endl; 00523 } 00524 str << std::endl; 00525 00526 gMB->release_interface( set ); 00527 exit( 0 ); 00528 } 00529 00530 static void usage_error( const char* name ) 00531 { 00532 print_usage( name, std::cerr ); 00533 #ifdef MOAB_HAVE_MPI 00534 MPI_Finalize(); 00535 #endif 00536 exit( USAGE_ERROR ); 00537 } 00538 00539 static void print_time( int clk_per_sec, const char* prefix, clock_t ticks, std::ostream& stream ) 00540 { 00541 ticks *= clk_per_sec / 100; 00542 clock_t centi = ticks % 100; 00543 clock_t seconds = ticks / 100; 00544 stream << prefix; 00545 if( seconds < 120 ) 00546 { 00547 stream << ( ticks / 100 ) << "." << centi << "s" << std::endl; 00548 } 00549 else 00550 { 00551 clock_t minutes = ( seconds / 60 ) % 60; 00552 clock_t hours = ( seconds / 3600 ); 00553 seconds %= 60; 00554 if( hours ) stream << hours << "h"; 00555 if( minutes ) stream << minutes << "m"; 00556 if( seconds || centi ) stream << seconds << "." << centi << "s"; 00557 stream << " (" << ( ticks / 100 ) << "." << centi << "s)" << std::endl; 00558 } 00559 } 00560 00561 clock_t usr_time, sys_time, abs_time; 00562 00563 #ifdef WIN32 00564 00565 void reset_times() 00566 { 00567 abs_time = clock(); 00568 } 00569 00570 void write_times( std::ostream& stream ) 00571 { 00572 clock_t abs_tm = clock(); 00573 print_time( CLOCKS_PER_SEC, " ", abs_tm - abs_time, stream ); 00574 abs_time = abs_tm; 00575 } 00576 00577 #else 00578 00579 void reset_times() 00580 { 00581 tms timebuf; 00582 abs_time = times( &timebuf ); 00583 usr_time = timebuf.tms_utime; 00584 sys_time = timebuf.tms_stime; 00585 } 00586 00587 void write_times( std::ostream& stream ) 00588 { 00589 clock_t usr_tm, sys_tm, abs_tm; 00590 tms timebuf; 00591 abs_tm = times( &timebuf ); 00592 usr_tm = timebuf.tms_utime; 00593 sys_tm = timebuf.tms_stime; 00594 print_time( sysconf( _SC_CLK_TCK ), " real: ", abs_tm - abs_time, stream ); 00595 print_time( sysconf( _SC_CLK_TCK ), " user: ", usr_tm - usr_time, stream ); 00596 print_time( sysconf( _SC_CLK_TCK ), " system: ", sys_tm - sys_time, stream ); 00597 abs_time = abs_tm; 00598 usr_time = usr_tm; 00599 sys_time = sys_tm; 00600 } 00601 00602 #endif 00603 00604 const char* geom_type_names[] = { "Vertex", "Curve", "Surface", "Volume" }; 00605 const char* mesh_type_names[] = { "Dirichlet Set", "Neumann Set", "Material Set" }; 00606 const char* mesh_type_tags[] = { DIRICHLET_SET_TAG_NAME, NEUMANN_SET_TAG_NAME, MATERIAL_SET_TAG_NAME }; 00607 00608 int main( int argc, char* argv[] ) 00609 { 00610 bool geom_owners = false; 00611 bool mesh_owners = false; 00612 bool just_list = false; 00613 bool just_list_basic = false; 00614 bool tag_count = false; 00615 std::vector< std::string > file_list; 00616 set_stats total_stats, file_stats; 00617 std::vector< TagCounts > total_counts, file_counts; 00618 ErrorCode rval; 00619 00620 Range range; 00621 00622 int i; 00623 std::vector< std::string > read_opts; 00624 00625 int proc_id = 0; 00626 #ifdef MOAB_HAVE_MPI 00627 MPI_Init( &argc, &argv ); 00628 MPI_Comm_rank( MPI_COMM_WORLD, &proc_id ); 00629 #endif 00630 00631 // scan arguments 00632 bool do_flag = true; 00633 bool print_times = false; 00634 bool parallel = false, resolve_shared = false, exchange_ghosts = false; 00635 bool printed_usage = false; 00636 for( i = 1; i < argc; i++ ) 00637 { 00638 if( !argv[i][0] ) usage_error( argv[0] ); 00639 00640 if( do_flag && argv[i][0] == '-' ) 00641 { 00642 switch( argv[i][1] ) 00643 { 00644 // do flag arguments: 00645 case '-': 00646 do_flag = false; 00647 break; 00648 case 'T': 00649 print_times = true; 00650 break; 00651 case 'h': 00652 case 'H': 00653 print_usage( argv[0], std::cerr ); 00654 printed_usage = true; 00655 break; 00656 case 'f': 00657 list_formats( &mb ); 00658 break; 00659 case 'l': 00660 if( strlen( argv[i] ) == 2 ) 00661 just_list_basic = true; 00662 else if( strlen( argv[i] ) == 3 && argv[i][2] == 'l' ) 00663 just_list = true; 00664 break; 00665 #ifdef MOAB_HAVE_MPI 00666 case 'p': 00667 parallel = true; 00668 if( argv[i][2] == '1' || argv[i][2] == '2' ) resolve_shared = true; 00669 if( argv[i][2] == '2' ) exchange_ghosts = true; 00670 break; 00671 #endif 00672 case 'g': 00673 geom_owners = true; 00674 break; 00675 case 'm': 00676 mesh_owners = true; 00677 break; 00678 case 't': 00679 tag_count = true; 00680 break; 00681 default: 00682 ++i; 00683 switch( argv[i - 1][1] ) 00684 { 00685 case 'O': 00686 read_opts.push_back( argv[i] ); 00687 break; 00688 default: 00689 std::cerr << "Invalid option: " << argv[i] << std::endl; 00690 } 00691 } 00692 } 00693 // do file names 00694 else 00695 { 00696 file_list.push_back( argv[i] ); 00697 } 00698 } 00699 00700 // construct options string from individual options 00701 std::string read_options; 00702 if( parallel ) 00703 { 00704 read_opts.push_back( "PARALLEL=READ_PART" ); 00705 read_opts.push_back( "PARTITION=PARALLEL_PARTITION" ); 00706 } 00707 if( resolve_shared ) read_opts.push_back( "PARALLEL_RESOLVE_SHARED_ENTS" ); 00708 if( exchange_ghosts ) read_opts.push_back( "PARALLEL_GHOSTS=3.0.1" ); 00709 00710 if( !make_opts_string( read_opts, read_options ) ) 00711 { 00712 #ifdef MOAB_HAVE_MPI 00713 MPI_Finalize(); 00714 #endif 00715 return USAGE_ERROR; 00716 } 00717 00718 if( file_list.empty() && !printed_usage ) print_usage( argv[0], std::cerr ); 00719 00720 for( std::vector< std::string >::iterator f = file_list.begin(); f != file_list.end(); ++f ) 00721 { 00722 reset_times(); 00723 printf( "File %s:\n", f->c_str() ); 00724 if( MB_SUCCESS != mb.load_file( f->c_str(), NULL, read_options.c_str() ) ) 00725 { 00726 fprintf( stderr, "Error reading file: %s\n", f->c_str() ); 00727 return 1; 00728 } 00729 00730 if( tag_count ) 00731 rval = gather_tag_counts( 0, file_counts ); 00732 else if( !just_list ) 00733 rval = gather_set_stats( 0, file_stats ); 00734 else 00735 rval = MB_SUCCESS; 00736 00737 if( MB_SUCCESS != rval ) 00738 { 00739 fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() ); 00740 return 1; 00741 } 00742 00743 if( tag_count ) 00744 { 00745 add_tag_counts( total_counts, file_counts ); 00746 print_tag_counts( file_counts ); 00747 file_counts.clear(); 00748 } 00749 else if( just_list ) 00750 { 00751 mb.list_entities( 0, -1 ); 00752 } 00753 else 00754 { 00755 total_stats.add( file_stats ); 00756 print_stats( file_stats ); 00757 file_stats.clear(); 00758 } 00759 00760 if( geom_owners ) 00761 { 00762 Range entities; 00763 Tag dim_tag = 0, id_tag = 0; 00764 rval = mb.tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, dim_tag ); 00765 if( MB_TAG_NOT_FOUND == rval ) 00766 { 00767 fprintf( stderr, "No geometry tag defined.\n" ); 00768 } 00769 else if( MB_SUCCESS != rval ) 00770 { 00771 fprintf( stderr, "Error retreiving geometry tag.\n" ); 00772 return 2; 00773 } 00774 00775 id_tag = mb.globalId_tag(); 00776 00777 if( dim_tag && id_tag ) 00778 { 00779 if( MB_SUCCESS != mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, 0, 1, entities ) ) 00780 { 00781 fprintf( stderr, "Error retreiving geometry entitities.\n" ); 00782 } 00783 } 00784 00785 if( entities.empty() ) 00786 { 00787 fprintf( stderr, "No geometry entities defined in file.\n" ); 00788 } 00789 00790 for( Range::iterator rit = entities.begin(); rit != entities.end(); ++rit ) 00791 { 00792 int id = 0, dim = 0; 00793 if( MB_SUCCESS != mb.tag_get_data( dim_tag, &*rit, 1, &dim ) || 00794 MB_SUCCESS != mb.tag_get_data( id_tag, &*rit, 1, &id ) ) 00795 { 00796 fprintf( stderr, "Error retreiving tag data for geometry entity.\n" ); 00797 continue; 00798 } 00799 00800 printf( "%s %d:\n", geom_type_names[dim], id ); 00801 if( tag_count ) 00802 rval = gather_tag_counts( *rit, file_counts ); 00803 else if( !just_list && !just_list_basic ) 00804 rval = gather_set_stats( *rit, file_stats ); 00805 00806 if( MB_SUCCESS != rval ) 00807 fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() ); 00808 else if( tag_count ) 00809 print_tag_counts( file_counts ); 00810 else if( just_list ) 00811 mb.list_entities( 0, 1 ); 00812 else if( just_list_basic ) 00813 mb.list_entities( 0, 0 ); 00814 else 00815 print_stats( file_stats ); 00816 00817 file_stats.clear(); 00818 file_counts.clear(); 00819 } 00820 } 00821 00822 if( mesh_owners ) 00823 { 00824 for( int t = 0; t < 3; ++t ) 00825 { 00826 Range entities; 00827 Tag tag = 0; 00828 rval = mb.tag_get_handle( mesh_type_tags[t], 1, MB_TYPE_INTEGER, tag ); 00829 if( MB_TAG_NOT_FOUND == rval ) 00830 { 00831 continue; 00832 } 00833 else if( MB_SUCCESS != rval ) 00834 { 00835 fprintf( stderr, "Error retreiving %s tag.\n", mesh_type_tags[t] ); 00836 return 2; 00837 } 00838 00839 if( MB_SUCCESS != mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, 0, 1, entities ) ) 00840 { 00841 fprintf( stderr, "Error retreiving %s entitities.\n", mesh_type_names[t] ); 00842 continue; 00843 } 00844 00845 for( Range::iterator rit = entities.begin(); rit != entities.end(); ++rit ) 00846 { 00847 int id = 0; 00848 if( MB_SUCCESS != mb.tag_get_data( tag, &*rit, 1, &id ) ) 00849 { 00850 fprintf( stderr, "Error retreiving tag data for %s entity.\n", mesh_type_names[t] ); 00851 continue; 00852 } 00853 00854 printf( "%s %d:\n", mesh_type_names[t], id ); 00855 if( tag_count ) 00856 { 00857 rval = gather_tag_counts( *rit, file_counts ); 00858 if( MB_SUCCESS != rval ) 00859 fprintf( stderr, "Error processing tags from file: %s\n", f->c_str() ); 00860 else 00861 print_tag_counts( file_counts ); 00862 } 00863 else if( just_list ) 00864 mb.list_entities( 0, 1 ); 00865 else if( just_list_basic ) 00866 mb.list_entities( 0, 0 ); 00867 else if( !just_list && !just_list_basic ) 00868 { 00869 rval = gather_set_stats( *rit, file_stats ); 00870 00871 if( rval != MB_SUCCESS ) 00872 fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() ); 00873 else 00874 print_stats( file_stats ); 00875 } 00876 file_stats.clear(); 00877 file_counts.clear(); 00878 } 00879 } 00880 } 00881 00882 if( print_times && !proc_id ) write_times( std::cout ); 00883 mb.delete_mesh(); 00884 } 00885 00886 if( file_list.size() > 1 && !just_list && !just_list_basic ) 00887 { 00888 printf( "Total for all files:\n" ); 00889 if( tag_count ) 00890 print_tag_counts( total_counts ); 00891 else 00892 print_stats( total_stats ); 00893 } 00894 #ifdef MOAB_HAVE_MPI 00895 MPI_Finalize(); 00896 #endif 00897 return 0; 00898 }