Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
size.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <cstdlib>
3 #include <vector>
4 #include <set>
5 #include <string>
6 #include <cstdio>
7 #include <iomanip>
8 #include "moab/MOABConfig.h"
9 #ifndef WIN32
10 #include <sys/times.h>
11 #include <climits>
12 #include <unistd.h>
13 #endif
14 #include <ctime>
15 #ifdef MOAB_HAVE_MPI
16 #include "moab_mpi.h"
17 #endif
18 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
19 #include <termios.h>
20 #include <sys/ioctl.h>
21 #endif
22 #include <cmath>
23 #include <cassert>
24 #include <cfloat>
25 
26 #include "moab/Core.hpp"
27 #include "moab/Range.hpp"
28 #include "MBTagConventions.hpp"
29 #include "moab/Interface.hpp"
30 #include "moab/ReaderWriterSet.hpp"
31 
32 /* Exit values */
33 #define USAGE_ERROR 1
34 #define READ_ERROR 2
35 #define WRITE_ERROR 3
36 #define OTHER_ERROR 4
37 #define ENT_NOT_FOUND 5
38 
39 using namespace moab;
40 
41 #include "measure.hpp"
42 
43 static void print_usage( const char* name, std::ostream& stream )
44 {
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
54 #ifdef MOAB_HAVE_MPI
55  << "\t-p[0|1|2] - Read in parallel[0], optionally also doing resolve_shared_ents "
56  "(1) and exchange_ghosts (2)"
57  << std::endl
58 #endif
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;
63 }
64 
66 
67 struct stat_set
68 {
69  double sum;
70  double sqr;
71  double min;
72  double max;
73  long count;
74 
75  inline stat_set() : sum( 0 ), sqr( 0 ), min( HUGE_VAL ), max( 0 ), count( 0 ) {}
76 
77  inline void add( double val )
78  {
79  if( val < min ) min = val;
80  if( val > max ) max = val;
81  sum += val;
82  sqr += val * val;
83  ++count;
84  }
85 
86  inline void add( const stat_set& stats )
87  {
88  if( stats.min < min ) min = stats.min;
89  if( stats.max > max ) max = stats.max;
90  sum += stats.sum;
91  sqr += stats.sqr;
92  count += stats.count;
93  }
94 
95  inline void clear()
96  {
97  sum = sqr = 0.0;
98  max = count = 0;
99  min = HUGE_VAL;
100  }
101 };
102 
103 struct set_stats
104 {
107  size_t nodes;
108 
109  void add( const set_stats& other )
110  {
111  for( int i = 0; i < MBMAXTYPE; ++i )
112  stats[i].add( other.stats[i] );
113  edge_uses.add( other.edge_uses );
114  }
115 
116  void clear()
117  {
118  for( int i = 0; i < MBMAXTYPE; ++i )
119  stats[i].clear();
120  edge_uses.clear();
121  }
122 };
123 
125 {
126  int count;
127  ErrorCode rval = mb.get_number_entities_by_type( set, MBVERTEX, count );
128  if( MB_SUCCESS != rval ) return rval;
129  stats.nodes = count;
130 
131  int edge_vtx_idx[2];
132  std::vector< EntityHandle > conn;
133  std::vector< double > coords;
134  for( EntityType type = MBEDGE; type < MBENTITYSET; ++type )
135  {
136  int num_edges = CN::NumSubEntities( type, 1 );
137 
138  Range range;
139  rval = mb.get_entities_by_type( set, type, range, true );
140  if( MB_SUCCESS != rval ) return rval;
141  for( Range::iterator i = range.begin(); i != range.end(); ++i )
142  {
143  rval = mb.get_connectivity( &*i, 1, conn, true );
144  if( MB_SUCCESS != rval ) return rval;
145  if( type == MBPOLYHEDRON )
146  {
147  std::vector< EntityHandle > dum_conn( conn );
148  conn.clear();
149  rval = mb.get_adjacencies( &dum_conn[0], dum_conn.size(), 0, false, conn, Interface::UNION );
150  if( MB_SUCCESS != rval ) return rval;
151  }
152  coords.resize( 3 * conn.size() );
153  rval = mb.get_coords( &conn[0], conn.size(), &coords[0] );
154  if( MB_SUCCESS != rval ) return rval;
155  stats.stats[type].add( measure( type, conn.size(), &coords[0] ) );
156 
157  if( type != MBEDGE )
158  {
159  if( type == MBPOLYGON ) num_edges = conn.size();
160 
161  for( int e = 0; e < num_edges; ++e )
162  {
163  if( type == MBPOLYGON )
164  {
165  edge_vtx_idx[0] = e;
166  edge_vtx_idx[1] = ( e + 1 ) % num_edges;
167  }
168  else
169  CN::SubEntityVertexIndices( type, 1, e, edge_vtx_idx );
170  stats.edge_uses.add( edge_length( &coords[3 * edge_vtx_idx[0]], &coords[3 * edge_vtx_idx[1]] ) );
171  }
172  }
173  }
174  }
175  return MB_SUCCESS;
176 }
177 
178 struct TagCounts
179 {
180  TagCounts( std::string n ) : name( n )
181  {
182  std::fill( counts, counts + MBMAXTYPE, 0 );
183  }
184  std::string name;
185  int counts[MBMAXTYPE];
186 };
187 
188 static ErrorCode gather_tag_counts( EntityHandle set, std::vector< TagCounts >& counts )
189 {
190  std::vector< Tag > tags;
191  mb.tag_get_tags( tags );
192  for( size_t i = 0; i < tags.size(); ++i )
193  {
194  std::string name;
195  ErrorCode rval = mb.tag_get_name( tags[i], name );
196  if( MB_SUCCESS != rval || name.empty() ) continue;
197 
198  counts.push_back( name );
199  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
200  mb.get_number_entities_by_type_and_tag( set, t, &tags[i], 0, 1, counts.back().counts[t] );
201  }
202 
203  return MB_SUCCESS;
204 }
205 
206 void add_tag_counts( std::vector< TagCounts >& counts, const std::vector< TagCounts >& add )
207 {
208  for( size_t i = 0; i < add.size(); ++i )
209  {
210  size_t j;
211  for( j = 0; j < counts.size(); ++j )
212  if( add[i].name == counts[j].name ) break;
213  if( j == counts.size() )
214  {
215  counts.push_back( add[i] );
216  continue;
217  }
218  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
219  counts[j].counts[t] += add[i].counts[t];
220  }
221 }
222 
223 static const char* dashes( unsigned count )
224 {
225  static std::vector< char > dashes;
226  dashes.clear();
227  dashes.resize( count + 1, '-' );
228  dashes[count] = '\0';
229  return &dashes[0];
230 }
231 
232 static void print_tag_counts( const std::vector< TagCounts >& counts )
233 {
234  if( counts.empty() )
235  {
236  printf( "<No tags>\n" );
237  return;
238  }
239 
240  int widths[MBMAXTYPE] = { 0 };
241  int name_width = 0;
242  for( size_t i = 0; i < counts.size(); ++i )
243  {
244  if( counts[i].name.length() > (unsigned)name_width ) name_width = counts[i].name.length();
245  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
246  if( counts[i].counts[t] != 0 ) widths[t] = std::max( 8, (int)strlen( CN::EntityTypeName( t ) ) );
247  }
248 
249  if( 0 == std::min_element( widths, widths + MBMAXTYPE ) )
250  {
251  printf( "<No Tagged Entities>\n" );
252  return;
253  }
254 
255  // Print header line
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 );
259  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
260  if( widths[t] ) printf( " %*s", widths[t], CN::EntityTypeName( t ) );
261  printf( "\n%s", dashes( name_width ) );
262  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
263  if( widths[t] ) printf( " %s", dashes( widths[t] ) );
264  printf( "\n" );
265 
266  // print data
267  for( size_t i = 0; i < counts.size(); ++i )
268  {
269  printf( "%*s", name_width, counts[i].name.c_str() );
270  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
271  if( widths[t] ) printf( " %*d", widths[t], counts[i].counts[t] );
272  printf( "\n" );
273  }
274 }
275 
276 static void print_stats( set_stats& stats )
277 {
278  const char* edge_use_name = "1D Side";
279  const char* vertex_name = "Vertex";
280 
281  bool have_some = stats.edge_uses.count > 0 || stats.nodes > 0;
282  for( int i = 0; i < MBMAXTYPE; ++i )
283  if( stats.stats[i].count > 0 ) have_some = true;
284 
285  if( !have_some )
286  {
287  std::cout << "NO MESH" << std::endl;
288  return;
289  }
290 
291  // get field widths
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;
298 
299  unsigned node_count_width = (unsigned)( ceil( log10( (double)stats.nodes ) ) ) + 1;
300  if( count_width < node_count_width ) count_width = node_count_width;
301 
302  for( EntityType i = MBEDGE; i < MBMAXTYPE; ++i )
303  {
304  stat_set& s = stats.stats[i];
305 
306  if( s.count == 0 ) continue;
307 
308  unsigned len = strlen( CN::EntityTypeName( i ) );
309  if( len > type_width ) type_width = len;
310 
311  unsigned cw = (unsigned)( ceil( log10( (double)s.count ) ) ) + 1;
312  if( cw > count_width ) count_width = cw;
313 
314  int tl = (unsigned)( ceil( log10( fabs( s.sum ) ) ) ) + 1;
315  if( tl > total_log ) total_log = tl;
316  }
317 
318  if( total_log > (int)total_width || total_log == -10000 )
319  {
320  total_width = 8;
321  total_prec = 2;
322  }
323  else if( total_log <= -(int)total_width )
324  {
325  total_width = -total_log + 5;
326  total_prec = 2;
327  }
328  else if( total_log < 1 )
329  {
330  total_width = -total_log + 4;
331  total_prec = -total_log + 1;
332  }
333  else
334  {
335  total_width += 2;
336  }
337 
338  // get terminal width
339  unsigned term_width = 80;
340 #if !defined( _MSC_VER ) && !defined( __MINGW32__ )
341  struct winsize size;
342  if( ioctl( fileno( stdout ), TIOCGWINSZ, (char*)&size ) == 0 ) term_width = size.ws_col;
343  if( !term_width ) term_width = 80;
344 #endif
345  assert( term_width > 7 + type_width + count_width + total_width );
346 
347  term_width -= 7; // spaces
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;
353 
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." );
356 
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 ) );
365 
366  for( EntityType i = MBEDGE; i <= MBMAXTYPE; ++i )
367  {
368  stat_set& s = ( i == MBMAXTYPE ) ? stats.edge_uses : stats.stats[i];
369 
370  if( s.count == 0 ) continue;
371 
372  double tmp_dbl = s.sqr / s.count - s.sum * s.sum / (double)s.count / (double)s.count;
373  if( tmp_dbl < 0.0 )
374  {
375  if( tmp_dbl < -100.0 * DBL_EPSILON )
376  std::cout << "WARNING: stat values dubious, s^2 - sig_s = " << tmp_dbl << std::endl;
377  tmp_dbl = 0.0;
378  }
379 
380  printf( "%*s %*ld %*.*g %*.*g %*.*g %*.*g %*.*g %*.*g\n", type_width,
381  i == MBMAXTYPE ? edge_use_name : CN::EntityTypeName( i ), count_width, s.count, total_width, total_prec,
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 ) );
384  }
385  printf( "%*s %*lu\n", type_width, vertex_name, count_width, (unsigned long)stats.nodes );
386 
387  puts( "" );
388 }
389 
390 bool parse_id_list( const char* string, std::set< int >& results )
391 {
392  bool okay = true;
393  char* mystr = strdup( string );
394  for( const char* ptr = strtok( mystr, "," ); ptr; ptr = strtok( 0, "," ) )
395  {
396  char* endptr;
397  long val = strtol( ptr, &endptr, 0 );
398  if( endptr == ptr || val <= 0 )
399  {
400  std::cerr << "Not a valid id: " << ptr << std::endl;
401  okay = false;
402  break;
403  }
404 
405  long val2 = val;
406  if( *endptr == '-' )
407  {
408  const char* sptr = endptr + 1;
409  val2 = strtol( sptr, &endptr, 0 );
410  if( endptr == sptr || val2 <= 0 )
411  {
412  std::cerr << "Not a valid id: " << sptr << std::endl;
413  okay = false;
414  break;
415  }
416  if( val2 < val )
417  {
418  std::cerr << "Invalid id range: " << ptr << std::endl;
419  okay = false;
420  break;
421  }
422  }
423 
424  if( *endptr )
425  {
426  std::cerr << "Unexpected character: " << *endptr << std::endl;
427  okay = false;
428  break;
429  }
430 
431  for( ; val <= val2; ++val )
432  if( !results.insert( (int)val ).second ) std::cerr << "Warning: duplicate Id: " << val << std::endl;
433  }
434 
435  free( mystr );
436  return okay;
437 }
438 
439 bool make_opts_string( std::vector< std::string > options, std::string& opts )
440 {
441  opts.clear();
442  if( options.empty() ) return true;
443 
444  // choose a separator character
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 )
449  {
450  bool seen = false;
451  for( i = options.begin(); i != options.end(); ++i )
452  if( i->find( *sep_ptr, 0 ) != std::string::npos )
453  {
454  seen = true;
455  break;
456  }
457  if( !seen )
458  {
459  separator = *sep_ptr;
460  break;
461  }
462  }
463  if( !separator )
464  {
465  std::cerr << "Error: cannot find separator character for options string" << std::endl;
466  return false;
467  }
468  if( separator != ';' )
469  {
470  opts = ";";
471  opts += separator;
472  }
473 
474  // concatenate options
475  i = options.begin();
476  opts += *i;
477  for( ++i; i != options.end(); ++i )
478  {
479  opts += separator;
480  opts += *i;
481  }
482 
483  return true;
484 }
485 
487 {
488  const char iface_name[] = "ReaderWriterSet";
489  ErrorCode err;
490  ReaderWriterSet* set = 0;
492  std::ostream& str = std::cout;
493 
494  // get ReaderWriterSet
495  err = gMB->query_interface( set );
496  if( err != MB_SUCCESS || !set )
497  {
498  std::cerr << "Internal error: Interface \"" << iface_name << "\" not available.\n";
499  exit( OTHER_ERROR );
500  }
501 
502  // get field width for format description
503  size_t w = 0;
504  for( i = set->begin(); i != set->end(); ++i )
505  if( i->description().length() > w ) w = i->description().length();
506 
507  // write table header
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";
512 
513  // write table data
514  for( i = set->begin(); i != set->end(); ++i )
515  {
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 )
521  str << " " << *j;
522  str << std::endl;
523  }
524  str << std::endl;
525 
526  gMB->release_interface( set );
527  exit( 0 );
528 }
529 
530 static void usage_error( const char* name )
531 {
532  print_usage( name, std::cerr );
533 #ifdef MOAB_HAVE_MPI
534  MPI_Finalize();
535 #endif
536  exit( USAGE_ERROR );
537 }
538 
539 static void print_time( int clk_per_sec, const char* prefix, clock_t ticks, std::ostream& stream )
540 {
541  ticks *= clk_per_sec / 100;
542  clock_t centi = ticks % 100;
543  clock_t seconds = ticks / 100;
544  stream << prefix;
545  if( seconds < 120 )
546  {
547  stream << ( ticks / 100 ) << "." << centi << "s" << std::endl;
548  }
549  else
550  {
551  clock_t minutes = ( seconds / 60 ) % 60;
552  clock_t hours = ( seconds / 3600 );
553  seconds %= 60;
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;
558  }
559 }
560 
562 
563 #ifdef WIN32
564 
565 void reset_times()
566 {
567  abs_time = clock();
568 }
569 
570 void write_times( std::ostream& stream )
571 {
572  clock_t abs_tm = clock();
573  print_time( CLOCKS_PER_SEC, " ", abs_tm - abs_time, stream );
574  abs_time = abs_tm;
575 }
576 
577 #else
578 
580 {
581  tms timebuf;
582  abs_time = times( &timebuf );
583  usr_time = timebuf.tms_utime;
584  sys_time = timebuf.tms_stime;
585 }
586 
587 void write_times( std::ostream& stream )
588 {
589  clock_t usr_tm, sys_tm, abs_tm;
590  tms timebuf;
591  abs_tm = times( &timebuf );
592  usr_tm = timebuf.tms_utime;
593  sys_tm = timebuf.tms_stime;
594  print_time( sysconf( _SC_CLK_TCK ), " real: ", abs_tm - abs_time, stream );
595  print_time( sysconf( _SC_CLK_TCK ), " user: ", usr_tm - usr_time, stream );
596  print_time( sysconf( _SC_CLK_TCK ), " system: ", sys_tm - sys_time, stream );
597  abs_time = abs_tm;
598  usr_time = usr_tm;
599  sys_time = sys_tm;
600 }
601 
602 #endif
603 
604 const char* geom_type_names[] = { "Vertex", "Curve", "Surface", "Volume" };
605 const char* mesh_type_names[] = { "Dirichlet Set", "Neumann Set", "Material Set" };
607 
608 int main( int argc, char* argv[] )
609 {
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;
616  set_stats total_stats, file_stats;
617  std::vector< TagCounts > total_counts, file_counts;
618  ErrorCode rval;
619 
620  Range range;
621 
622  int i;
623  std::vector< std::string > read_opts;
624 
625  int proc_id = 0;
626 #ifdef MOAB_HAVE_MPI
627  MPI_Init( &argc, &argv );
628  MPI_Comm_rank( MPI_COMM_WORLD, &proc_id );
629 #endif
630 
631  // scan arguments
632  bool do_flag = true;
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++ )
637  {
638  if( !argv[i][0] ) usage_error( argv[0] );
639 
640  if( do_flag && argv[i][0] == '-' )
641  {
642  switch( argv[i][1] )
643  {
644  // do flag arguments:
645  case '-':
646  do_flag = false;
647  break;
648  case 'T':
649  print_times = true;
650  break;
651  case 'h':
652  case 'H':
653  print_usage( argv[0], std::cerr );
654  printed_usage = true;
655  break;
656  case 'f':
657  list_formats( &mb );
658  break;
659  case 'l':
660  if( strlen( argv[i] ) == 2 )
661  just_list_basic = true;
662  else if( strlen( argv[i] ) == 3 && argv[i][2] == 'l' )
663  just_list = true;
664  break;
665 #ifdef MOAB_HAVE_MPI
666  case 'p':
667  parallel = true;
668  if( argv[i][2] == '1' || argv[i][2] == '2' ) resolve_shared = true;
669  if( argv[i][2] == '2' ) exchange_ghosts = true;
670  break;
671 #endif
672  case 'g':
673  geom_owners = true;
674  break;
675  case 'm':
676  mesh_owners = true;
677  break;
678  case 't':
679  tag_count = true;
680  break;
681  default:
682  ++i;
683  switch( argv[i - 1][1] )
684  {
685  case 'O':
686  read_opts.push_back( argv[i] );
687  break;
688  default:
689  std::cerr << "Invalid option: " << argv[i] << std::endl;
690  }
691  }
692  }
693  // do file names
694  else
695  {
696  file_list.push_back( argv[i] );
697  }
698  }
699 
700  // construct options string from individual options
701  std::string read_options;
702  if( parallel )
703  {
704  read_opts.push_back( "PARALLEL=READ_PART" );
705  read_opts.push_back( "PARTITION=PARALLEL_PARTITION" );
706  }
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" );
709 
710  if( !make_opts_string( read_opts, read_options ) )
711  {
712 #ifdef MOAB_HAVE_MPI
713  MPI_Finalize();
714 #endif
715  return USAGE_ERROR;
716  }
717 
718  if( file_list.empty() && !printed_usage ) print_usage( argv[0], std::cerr );
719 
720  for( std::vector< std::string >::iterator f = file_list.begin(); f != file_list.end(); ++f )
721  {
722  reset_times();
723  printf( "File %s:\n", f->c_str() );
724  if( MB_SUCCESS != mb.load_file( f->c_str(), NULL, read_options.c_str() ) )
725  {
726  fprintf( stderr, "Error reading file: %s\n", f->c_str() );
727  return 1;
728  }
729 
730  if( tag_count )
731  rval = gather_tag_counts( 0, file_counts );
732  else if( !just_list )
733  rval = gather_set_stats( 0, file_stats );
734  else
735  rval = MB_SUCCESS;
736 
737  if( MB_SUCCESS != rval )
738  {
739  fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() );
740  return 1;
741  }
742 
743  if( tag_count )
744  {
745  add_tag_counts( total_counts, file_counts );
746  print_tag_counts( file_counts );
747  file_counts.clear();
748  }
749  else if( just_list )
750  {
751  mb.list_entities( 0, -1 );
752  }
753  else
754  {
755  total_stats.add( file_stats );
756  print_stats( file_stats );
757  file_stats.clear();
758  }
759 
760  if( geom_owners )
761  {
762  Range entities;
763  Tag dim_tag = 0, id_tag = 0;
765  if( MB_TAG_NOT_FOUND == rval )
766  {
767  fprintf( stderr, "No geometry tag defined.\n" );
768  }
769  else if( MB_SUCCESS != rval )
770  {
771  fprintf( stderr, "Error retreiving geometry tag.\n" );
772  return 2;
773  }
774 
775  id_tag = mb.globalId_tag();
776 
777  if( dim_tag && id_tag )
778  {
779  if( MB_SUCCESS != mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &dim_tag, 0, 1, entities ) )
780  {
781  fprintf( stderr, "Error retreiving geometry entitities.\n" );
782  }
783  }
784 
785  if( entities.empty() )
786  {
787  fprintf( stderr, "No geometry entities defined in file.\n" );
788  }
789 
790  for( Range::iterator rit = entities.begin(); rit != entities.end(); ++rit )
791  {
792  int id = 0, dim = 0;
793  if( MB_SUCCESS != mb.tag_get_data( dim_tag, &*rit, 1, &dim ) ||
794  MB_SUCCESS != mb.tag_get_data( id_tag, &*rit, 1, &id ) )
795  {
796  fprintf( stderr, "Error retreiving tag data for geometry entity.\n" );
797  continue;
798  }
799 
800  printf( "%s %d:\n", geom_type_names[dim], id );
801  if( tag_count )
802  rval = gather_tag_counts( *rit, file_counts );
803  else if( !just_list && !just_list_basic )
804  rval = gather_set_stats( *rit, file_stats );
805 
806  if( MB_SUCCESS != rval )
807  fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() );
808  else if( tag_count )
809  print_tag_counts( file_counts );
810  else if( just_list )
811  mb.list_entities( 0, 1 );
812  else if( just_list_basic )
813  mb.list_entities( 0, 0 );
814  else
815  print_stats( file_stats );
816 
817  file_stats.clear();
818  file_counts.clear();
819  }
820  }
821 
822  if( mesh_owners )
823  {
824  for( int t = 0; t < 3; ++t )
825  {
826  Range entities;
827  Tag tag = 0;
828  rval = mb.tag_get_handle( mesh_type_tags[t], 1, MB_TYPE_INTEGER, tag );
829  if( MB_TAG_NOT_FOUND == rval )
830  {
831  continue;
832  }
833  else if( MB_SUCCESS != rval )
834  {
835  fprintf( stderr, "Error retreiving %s tag.\n", mesh_type_tags[t] );
836  return 2;
837  }
838 
840  {
841  fprintf( stderr, "Error retreiving %s entitities.\n", mesh_type_names[t] );
842  continue;
843  }
844 
845  for( Range::iterator rit = entities.begin(); rit != entities.end(); ++rit )
846  {
847  int id = 0;
848  if( MB_SUCCESS != mb.tag_get_data( tag, &*rit, 1, &id ) )
849  {
850  fprintf( stderr, "Error retreiving tag data for %s entity.\n", mesh_type_names[t] );
851  continue;
852  }
853 
854  printf( "%s %d:\n", mesh_type_names[t], id );
855  if( tag_count )
856  {
857  rval = gather_tag_counts( *rit, file_counts );
858  if( MB_SUCCESS != rval )
859  fprintf( stderr, "Error processing tags from file: %s\n", f->c_str() );
860  else
861  print_tag_counts( file_counts );
862  }
863  else if( just_list )
864  mb.list_entities( 0, 1 );
865  else if( just_list_basic )
866  mb.list_entities( 0, 0 );
867  else if( !just_list && !just_list_basic )
868  {
869  rval = gather_set_stats( *rit, file_stats );
870 
871  if( rval != MB_SUCCESS )
872  fprintf( stderr, "Error processing mesh from file: %s\n", f->c_str() );
873  else
874  print_stats( file_stats );
875  }
876  file_stats.clear();
877  file_counts.clear();
878  }
879  }
880  }
881 
882  if( print_times && !proc_id ) write_times( std::cout );
883  mb.delete_mesh();
884  }
885 
886  if( file_list.size() > 1 && !just_list && !just_list_basic )
887  {
888  printf( "Total for all files:\n" );
889  if( tag_count )
890  print_tag_counts( total_counts );
891  else
892  print_stats( total_stats );
893  }
894 #ifdef MOAB_HAVE_MPI
895  MPI_Finalize();
896 #endif
897  return 0;
898 }