10 #include <sys/times.h>
18 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
20 #include <sys/ioctl.h>
37 #define ENT_NOT_FOUND 5
43 static void print_usage(
const char* name, std::ostream& stream )
45 stream <<
"Usage: " << name <<
" <options> <input_file> [<input_file2> ...]" << std::endl
46 <<
"Options: " << std::endl
47 <<
"\t-f - List available file formats and exit." << std::endl
48 <<
"\t-g - print counts by geometric owner" << std::endl
49 <<
"\t-h - Print this help text and exit." << std::endl
50 <<
"\t-l - Print counts of mesh" << std::endl
51 <<
"\t-ll - Verbose listing of every entity" << std::endl
52 <<
"\t-m - Print counts per block/boundary" << std::endl
53 <<
"\t-O option - Specify read option." << std::endl
55 <<
"\t-p[0|1|2] - Read in parallel[0], optionally also doing resolve_shared_ents "
56 "(1) and exchange_ghosts (2)"
59 <<
"\t-t - Print counts by tag" << std::endl
60 <<
"\t-T - Time read of files." << std::endl
61 <<
"\t-- - treat all subsequent options as file names" << std::endl
62 <<
"\t (allows file names beginning with '-')" << std::endl;
75 inline stat_set() :
sum( 0 ), sqr( 0 ), min( HUGE_VAL ), max( 0 ), count( 0 ) {}
77 inline void add(
double val )
79 if( val < min ) min = val;
80 if( val > max ) max = val;
88 if( stats.
min < min ) min = stats.
min;
89 if( stats.
max > max ) max = stats.
max;
112 stats[i].add( other.
stats[i] );
132 std::vector< EntityHandle > conn;
133 std::vector< double > coords;
147 std::vector< EntityHandle > dum_conn( conn );
152 coords.resize( 3 * conn.size() );
153 rval =
mb.
get_coords( &conn[0], conn.size(), &coords[0] );
159 if( type ==
MBPOLYGON ) num_edges = conn.size();
161 for(
int e = 0; e < num_edges; ++e )
166 edge_vtx_idx[1] = ( e + 1 ) % num_edges;
182 std::fill( counts, counts +
MBMAXTYPE, 0 );
190 std::vector< Tag > tags;
192 for(
size_t i = 0; i < tags.size(); ++i )
196 if(
MB_SUCCESS != rval || name.empty() )
continue;
198 counts.push_back( name );
206 void add_tag_counts( std::vector< TagCounts >& counts,
const std::vector< TagCounts >& add )
208 for(
size_t i = 0; i < add.size(); ++i )
211 for( j = 0; j < counts.size(); ++j )
212 if( add[i].name == counts[j].name )
break;
213 if( j == counts.size() )
215 counts.push_back( add[i] );
219 counts[j].counts[t] += add[i].counts[t];
223 static const char*
dashes(
unsigned count )
225 static std::vector< char >
dashes;
227 dashes.resize( count + 1,
'-' );
236 printf(
"<No tags>\n" );
242 for(
size_t i = 0; i < counts.size(); ++i )
244 if( counts[i].name.length() > (
unsigned)name_width ) name_width = counts[i].name.length();
246 if( counts[i].counts[t] != 0 ) widths[t] = std::max( 8, (
int)strlen(
CN::EntityTypeName( t ) ) );
249 if( 0 == std::min_element( widths, widths +
MBMAXTYPE ) )
251 printf(
"<No Tagged Entities>\n" );
256 const char* name_title =
"Tag Name";
257 if( (
unsigned)name_width < strlen( name_title ) ) name_width = strlen( name_title );
258 printf(
"%*s", name_width, name_title );
261 printf(
"\n%s",
dashes( name_width ) );
263 if( widths[t] ) printf(
" %s",
dashes( widths[t] ) );
267 for(
size_t i = 0; i < counts.size(); ++i )
269 printf(
"%*s", name_width, counts[i].name.c_str() );
271 if( widths[t] ) printf(
" %*d", widths[t], counts[i].counts[t] );
278 const char* edge_use_name =
"1D Side";
279 const char* vertex_name =
"Vertex";
283 if( stats.
stats[i].
count > 0 ) have_some =
true;
287 std::cout <<
"NO MESH" << std::endl;
292 unsigned type_width = std::max( strlen( vertex_name ), strlen( edge_use_name ) );
293 unsigned count_width = 5;
294 unsigned total_width = 5;
295 unsigned total_prec = 2;
296 unsigned precision = 5;
297 int total_log = -10000;
299 unsigned node_count_width = (unsigned)( ceil( log10( (
double)stats.
nodes ) ) ) + 1;
300 if( count_width < node_count_width ) count_width = node_count_width;
306 if( s.
count == 0 )
continue;
309 if( len > type_width ) type_width = len;
311 unsigned cw = (unsigned)( ceil( log10( (
double)s.
count ) ) ) + 1;
312 if( cw > count_width ) count_width = cw;
314 int tl = (unsigned)( ceil( log10( fabs( s.
sum ) ) ) ) + 1;
315 if( tl > total_log ) total_log = tl;
318 if( total_log > (
int)total_width || total_log == -10000 )
323 else if( total_log <= -(
int)total_width )
325 total_width = -total_log + 5;
328 else if( total_log < 1 )
330 total_width = -total_log + 4;
331 total_prec = -total_log + 1;
339 unsigned term_width = 80;
340 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
342 if( ioctl( fileno( stdout ), TIOCGWINSZ, (
char*)&
size ) == 0 ) term_width =
size.ws_col;
343 if( !term_width ) term_width = 80;
345 assert( term_width > 7 + type_width + count_width + total_width );
348 term_width -= type_width;
349 term_width -= count_width;
350 term_width -= total_width;
351 unsigned val_width = term_width / 5;
352 if( val_width < 8 ) val_width = 8;
354 printf(
"%*s %*s %*s %*s %*s %*s %*s %*s\n", type_width,
"type", count_width,
"count", total_width,
"total",
355 val_width,
"minimum", val_width,
"average", val_width,
"rms", val_width,
"maximum", val_width,
"std.dev." );
357 printf(
"%*s ", type_width,
dashes( type_width ) );
358 printf(
"%*s ", count_width,
dashes( count_width ) );
359 printf(
"%*s ", total_width,
dashes( total_width ) );
360 printf(
"%*s ", val_width,
dashes( val_width ) );
361 printf(
"%*s ", val_width,
dashes( val_width ) );
362 printf(
"%*s ", val_width,
dashes( val_width ) );
363 printf(
"%*s ", val_width,
dashes( val_width ) );
364 printf(
"%*s\n", val_width,
dashes( val_width ) );
370 if( s.
count == 0 )
continue;
375 if( tmp_dbl < -100.0 * DBL_EPSILON )
376 std::cout <<
"WARNING: stat values dubious, s^2 - sig_s = " << tmp_dbl << std::endl;
380 printf(
"%*s %*ld %*.*g %*.*g %*.*g %*.*g %*.*g %*.*g\n", type_width,
382 s.
sum, val_width, precision, s.
min, val_width, precision, s.
sum / s.
count, val_width, precision,
383 sqrt( s.
sqr / s.
count ), val_width, precision, s.
max, val_width, precision, sqrt( tmp_dbl ) );
385 printf(
"%*s %*lu\n", type_width, vertex_name, count_width, (
unsigned long)stats.
nodes );
393 char* mystr = strdup(
string );
394 for(
const char* ptr = strtok( mystr,
"," ); ptr; ptr = strtok( 0,
"," ) )
397 long val = strtol( ptr, &endptr, 0 );
398 if( endptr == ptr || val <= 0 )
400 std::cerr <<
"Not a valid id: " << ptr << std::endl;
408 const char* sptr = endptr + 1;
409 val2 = strtol( sptr, &endptr, 0 );
410 if( endptr == sptr || val2 <= 0 )
412 std::cerr <<
"Not a valid id: " << sptr << std::endl;
418 std::cerr <<
"Invalid id range: " << ptr << std::endl;
426 std::cerr <<
"Unexpected character: " << *endptr << std::endl;
431 for( ; val <= val2; ++val )
432 if( !results.insert( (
int)val ).second ) std::cerr <<
"Warning: duplicate Id: " << val << std::endl;
442 if( options.empty() )
return true;
445 std::vector< std::string >::const_iterator i;
446 char separator =
'\0';
447 const char* alt_separators =
";+,:\t\n";
448 for(
const char* sep_ptr = alt_separators; *sep_ptr; ++sep_ptr )
451 for( i = options.begin(); i != options.end(); ++i )
452 if( i->find( *sep_ptr, 0 ) != std::string::npos )
459 separator = *sep_ptr;
465 std::cerr <<
"Error: cannot find separator character for options string" << std::endl;
468 if( separator !=
';' )
477 for( ++i; i != options.end(); ++i )
488 const char iface_name[] =
"ReaderWriterSet";
492 std::ostream& str = std::cout;
498 std::cerr <<
"Internal error: Interface \"" << iface_name <<
"\" not available.\n";
504 for( i = set->
begin(); i != set->
end(); ++i )
505 if( i->description().length() > w ) w = i->description().length();
508 str <<
"Format " << std::setw( w ) << std::left <<
"Description"
509 <<
" Read Write File Name Suffixes\n"
510 <<
"------ " << std::setw( w ) << std::setfill(
'-' ) <<
"" << std::setfill(
' ' )
511 <<
" ---- ----- ------------------\n";
514 for( i = set->
begin(); i != set->
end(); ++i )
516 std::vector< std::string > ext;
517 i->get_extensions( ext );
518 str << std::setw( 6 ) << i->name() <<
" " << std::setw( w ) << std::left << i->description() <<
" "
519 << ( i->have_reader() ?
" yes" :
" no" ) <<
" " << ( i->have_writer() ?
" yes" :
" no" ) <<
" ";
520 for( std::vector< std::string >::iterator j = ext.begin(); j != ext.end(); ++j )
539 static void print_time(
int clk_per_sec,
const char* prefix, clock_t ticks, std::ostream& stream )
541 ticks *= clk_per_sec / 100;
542 clock_t centi = ticks % 100;
543 clock_t seconds = ticks / 100;
547 stream << ( ticks / 100 ) <<
"." << centi <<
"s" << std::endl;
551 clock_t minutes = ( seconds / 60 ) % 60;
552 clock_t hours = ( seconds / 3600 );
554 if( hours ) stream << hours <<
"h";
555 if( minutes ) stream << minutes <<
"m";
556 if( seconds || centi ) stream << seconds <<
"." << centi <<
"s";
557 stream <<
" (" << ( ticks / 100 ) <<
"." << centi <<
"s)" << std::endl;
572 clock_t abs_tm = clock();
589 clock_t usr_tm, sys_tm, abs_tm;
591 abs_tm = times( &timebuf );
592 usr_tm = timebuf.tms_utime;
593 sys_tm = timebuf.tms_stime;
608 int main(
int argc,
char* argv[] )
610 bool geom_owners =
false;
611 bool mesh_owners =
false;
612 bool just_list =
false;
613 bool just_list_basic =
false;
614 bool tag_count =
false;
615 std::vector< std::string > file_list;
617 std::vector< TagCounts > total_counts, file_counts;
623 std::vector< std::string > read_opts;
627 MPI_Init( &argc, &argv );
628 MPI_Comm_rank( MPI_COMM_WORLD, &proc_id );
633 bool print_times =
false;
634 bool parallel =
false, resolve_shared =
false, exchange_ghosts =
false;
635 bool printed_usage =
false;
636 for( i = 1; i < argc; i++ )
640 if( do_flag && argv[i][0] ==
'-' )
654 printed_usage =
true;
660 if( strlen( argv[i] ) == 2 )
661 just_list_basic =
true;
662 else if( strlen( argv[i] ) == 3 && argv[i][2] ==
'l' )
668 if( argv[i][2] ==
'1' || argv[i][2] ==
'2' ) resolve_shared =
true;
669 if( argv[i][2] ==
'2' ) exchange_ghosts =
true;
683 switch( argv[i - 1][1] )
686 read_opts.push_back( argv[i] );
689 std::cerr <<
"Invalid option: " << argv[i] << std::endl;
696 file_list.push_back( argv[i] );
701 std::string read_options;
704 read_opts.push_back(
"PARALLEL=READ_PART" );
705 read_opts.push_back(
"PARTITION=PARALLEL_PARTITION" );
707 if( resolve_shared ) read_opts.push_back(
"PARALLEL_RESOLVE_SHARED_ENTS" );
708 if( exchange_ghosts ) read_opts.push_back(
"PARALLEL_GHOSTS=3.0.1" );
718 if( file_list.empty() && !printed_usage )
print_usage( argv[0], std::cerr );
720 for( std::vector< std::string >::iterator f = file_list.begin(); f != file_list.end(); ++f )
723 printf(
"File %s:\n", f->c_str() );
726 fprintf( stderr,
"Error reading file: %s\n", f->c_str() );
732 else if( !just_list )
739 fprintf( stderr,
"Error processing mesh from file: %s\n", f->c_str() );
755 total_stats.
add( file_stats );
763 Tag dim_tag = 0, id_tag = 0;
767 fprintf( stderr,
"No geometry tag defined.\n" );
771 fprintf( stderr,
"Error retreiving geometry tag.\n" );
777 if( dim_tag && id_tag )
781 fprintf( stderr,
"Error retreiving geometry entitities.\n" );
787 fprintf( stderr,
"No geometry entities defined in file.\n" );
796 fprintf( stderr,
"Error retreiving tag data for geometry entity.\n" );
803 else if( !just_list && !just_list_basic )
807 fprintf( stderr,
"Error processing mesh from file: %s\n", f->c_str() );
812 else if( just_list_basic )
824 for(
int t = 0; t < 3; ++t )
835 fprintf( stderr,
"Error retreiving %s tag.\n",
mesh_type_tags[t] );
841 fprintf( stderr,
"Error retreiving %s entitities.\n",
mesh_type_names[t] );
850 fprintf( stderr,
"Error retreiving tag data for %s entity.\n",
mesh_type_names[t] );
859 fprintf( stderr,
"Error processing tags from file: %s\n", f->c_str() );
865 else if( just_list_basic )
867 else if( !just_list && !just_list_basic )
872 fprintf( stderr,
"Error processing mesh from file: %s\n", f->c_str() );
882 if( print_times && !proc_id )
write_times( std::cout );
886 if( file_list.size() > 1 && !just_list && !just_list_basic )
888 printf(
"Total for all files:\n" );