Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
gsets.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <cstdlib>
3 #include "moab/Range.hpp"
4 #include "moab/Core.hpp"
5 #include "MBTagConventions.hpp"
6 #include "moab/GeomTopoTool.hpp"
7 
8 using namespace moab;
9 
15 Tag idTag = 0;
16 bool printAnonSets = false;
17 bool printSVSense = false;
18 
20 GeomTopoTool geomTool( &mb );
21 
22 static void usage( const char* name, bool brief = true )
23 {
24  std::ostream& str = brief ? std::cerr : std::cout;
25  if( !brief )
26  str << name << ": A tool to export entity set parent/child relations" << std::endl
27  << " for use as input to graphviz" << std::endl;
28  str << "Usage: " << name << " [-a | [-g] [-m] [-n] ] <input_file>" << std::endl
29  << " " << name << " -h" << std::endl;
30  if( brief ) exit( 1 );
31  str << " The default behavior is equivalent to \"-gmn\"." << std::endl
32  << " If any of the following options are used to specify which " << std::endl
33  << " sets to output, then there are no defaults. Only the " << std::endl
34  << " indicated sets will be output." << std::endl
35  << " -a : write all sets (default is only geom, mesh, and named)" << std::endl
36  << " -g : write geometric topology sets" << std::endl
37  << " -m : write material sets and boundary condition sets" << std::endl
38  << " -n : write named sets" << std::endl
39  << " -s : label surface-volume links with sense" << std::endl
40  << " The default link behavior is to both child links" << std::endl
41  << " and containment with solid lines." << std::endl
42  << " -P : do not write child links" << std::endl
43  << " -p : write child links with dashed lines" << std::endl
44  << " -C : do not write containment links" << std::endl
45  << " -c : write containment links with dashed lines" << std::endl;
46  exit( 0 );
47 }
48 
49 enum Link
50 {
51  NONE = 0,
53  DASHED
54 };
55 static void write_dot( Link contained, Link children );
56 static void dot_nodes( std::ostream& s, Range& sets_out );
57 static void dot_children( std::ostream& s, const Range& sets, bool dashed );
58 static void dot_contained( std::ostream& s, const Range& sets, bool dashed );
59 
60 int main( int argc, char* argv[] )
61 {
62  Link children = SOLID, contained = SOLID;
63  bool printGeomSets = true;
64  bool printMeshSets = true;
65  bool printNamedSets = true;
66  const char* input_file = 0;
67  bool geom_flag = false, mesh_flag = false, name_flag = false, all_flag = false;
68  bool no_more_flags = false;
69  for( int i = 1; i < argc; ++i )
70  {
71  if( no_more_flags || argv[i][0] != '-' )
72  {
73  if( input_file ) usage( argv[0] );
74  input_file = argv[i];
75  continue;
76  }
77  for( int j = 1; argv[i][j]; ++j )
78  {
79  switch( argv[i][j] )
80  {
81  case 'a':
82  all_flag = true;
83  break;
84  case 'g':
85  geom_flag = true;
86  break;
87  case 'm':
88  mesh_flag = true;
89  break;
90  case 'n':
91  name_flag = true;
92  break;
93  case 's':
94  printSVSense = true;
95  break;
96  case 'P':
97  children = NONE;
98  break;
99  case 'p':
100  children = DASHED;
101  break;
102  case 'C':
103  contained = NONE;
104  break;
105  case 'c':
106  contained = DASHED;
107  break;
108  case '-':
109  no_more_flags = true;
110  break;
111  case 'h':
112  usage( argv[0], false );
113  break;
114  default:
115  std::cerr << "Unknown flag: '" << argv[i][j] << "'" << std::endl;
116  usage( argv[0] );
117  }
118  }
119  }
120 
121  if( !input_file )
122  {
123  std::cerr << "No input file specified." << std::endl;
124  usage( argv[0] );
125  }
126 
127  if( all_flag )
128  {
129  printGeomSets = printMeshSets = printNamedSets = printAnonSets = true;
130  }
131  else if( geom_flag || mesh_flag || name_flag )
132  {
133  printGeomSets = geom_flag;
134  printMeshSets = mesh_flag;
135  printNamedSets = name_flag;
136  }
137 
138  if( MB_SUCCESS != mb.load_mesh( input_file ) )
139  {
140  std::cerr << input_file << ": file read failed." << std::endl;
141  return 1;
142  }
143 
144  Tag t;
145  if( printGeomSets )
146  {
148  {
149  geomTag = t;
150  }
151  }
152  if( printMeshSets )
153  {
155  {
156  blockTag = t;
157  }
159  {
160  nodeTag = t;
161  }
163  {
164  sideTag = t;
165  }
166  }
167  if( printNamedSets )
168  {
170  {
171  nameTag = t;
172  }
173  }
174  idTag = mb.globalId_tag();
175 
176  write_dot( contained, children );
177  return 0;
178 }
179 
180 void write_dot( Link contained, Link children )
181 {
182  Range sets;
183  std::cout << "digraph {" << std::endl;
184  dot_nodes( std::cout, sets );
185  std::cout << std::endl;
186  if( contained ) dot_contained( std::cout, sets, contained == DASHED );
187  if( children ) dot_children( std::cout, sets, children == DASHED );
188  std::cout << "}" << std::endl;
189 }
190 
191 static void dot_get_sets( Range& curr_sets, Range& result_sets, Tag tag, void* tag_val = 0 )
192 {
193  if( !tag ) return;
194 
195  result_sets.clear();
196  mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, &tag_val, 1, result_sets );
197  result_sets = subtract( result_sets, curr_sets );
198  curr_sets.merge( result_sets );
199 }
200 
201 static void dot_write_node( std::ostream& s, EntityHandle h, const char* label, int* id = 0 )
202 {
203  s << 's' << mb.id_from_handle( h ) << " [label = \"" << label;
204  if( id ) s << ' ' << *id;
205  s << "\"];" << std::endl;
206 }
207 
208 static void dot_write_id_nodes( std::ostream& s, const Range& entites, Tag id_tag, const char* type_name )
209 {
210  int id;
211  for( Range::iterator i = entites.begin(); i != entites.end(); ++i )
212  if( MB_SUCCESS == mb.tag_get_data( id_tag, &*i, 1, &id ) ) dot_write_node( s, *i, type_name, &id );
213 }
214 
215 void dot_nodes( std::ostream& s, Range& sets )
216 {
217  Range vol_sets, surf_sets, curv_sets, vert_sets;
218  Range block_sets, side_sets, node_sets;
219  Range named_sets, other_sets;
220 
221  dot_get_sets( sets, named_sets, nameTag );
222 
223  int dim = 3;
224  dot_get_sets( sets, vol_sets, geomTag, &dim );
225  dim = 2;
226  dot_get_sets( sets, surf_sets, geomTag, &dim );
227  dim = 1;
228  dot_get_sets( sets, curv_sets, geomTag, &dim );
229  dim = 0;
230  dot_get_sets( sets, vert_sets, geomTag, &dim );
231 
232  dot_get_sets( sets, block_sets, blockTag );
233  dot_get_sets( sets, side_sets, sideTag );
234  dot_get_sets( sets, node_sets, nodeTag );
235 
236  if( printAnonSets )
237  {
238  mb.get_entities_by_type( 0, MBENTITYSET, other_sets );
239  Range xsect = subtract( other_sets, sets );
240  sets.swap( other_sets );
241  other_sets.swap( xsect );
242  }
243 
244  dot_write_id_nodes( s, vol_sets, idTag, "Volume" );
245  dot_write_id_nodes( s, surf_sets, idTag, "Surface" );
246  dot_write_id_nodes( s, curv_sets, idTag, "Curve" );
247  dot_write_id_nodes( s, vert_sets, idTag, "Vertex" );
248  dot_write_id_nodes( s, block_sets, blockTag, "Block" );
249  dot_write_id_nodes( s, side_sets, sideTag, "Neumann Set" );
250  dot_write_id_nodes( s, node_sets, nodeTag, "Dirichlet Set" );
251 
252  Range::iterator i;
253  char name[NAME_TAG_SIZE + 1];
254  for( i = named_sets.begin(); i != named_sets.end(); ++i )
255  {
256  if( MB_SUCCESS == mb.tag_get_data( nameTag, &*i, 1, name ) )
257  {
258  name[NAME_TAG_SIZE] = '\0';
259  dot_write_node( s, *i, name );
260  }
261  }
262  for( i = other_sets.begin(); i != other_sets.end(); ++i )
263  {
264  int id = mb.id_from_handle( *i );
265  dot_write_node( s, *i, "EntitySet ", &id );
266  }
267 }
268 
269 static void dot_down_link( std::ostream& s,
270  EntityHandle parent,
272  bool dashed,
273  const char* label = 0 )
274 {
275  s << 's' << mb.id_from_handle( parent ) << " -> " << 's' << mb.id_from_handle( child );
276  if( dashed && label )
277  s << " [style = dashed label = \"" << label << "\"]";
278  else if( dashed )
279  s << " [style = dashed]";
280  else if( label )
281  s << " [label = \"" << label << "\"]";
282  s << ';' << std::endl;
283 }
284 
285 void dot_children( std::ostream& s, const Range& sets, bool dashed )
286 {
287  int sense;
288  const char *fstr = "forward", *rstr = "reverse";
289  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
290  {
291  Range parents;
292  mb.get_parent_meshsets( *i, parents );
293  parents = intersect( parents, sets );
294 
295  for( Range::iterator j = parents.begin(); j != parents.end(); ++j )
296  {
297  const char* linklabel = 0;
298  if( printSVSense && MB_SUCCESS == geomTool.get_sense( *i, *j, sense ) )
299 
300  // check here only one sense, as before...
301  linklabel = ( sense == (int)SENSE_FORWARD ) ? fstr : rstr;
302 
303  dot_down_link( s, *j, *i, dashed, linklabel );
304  }
305  }
306 }
307 
308 void dot_contained( std::ostream& s, const Range& sets, bool dashed )
309 {
310  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
311  {
312  Range contained;
313  mb.get_entities_by_type( *i, MBENTITYSET, contained );
314  contained = intersect( contained, sets );
315 
316  for( Range::iterator j = contained.begin(); j != contained.end(); ++j )
317  dot_down_link( s, *i, *j, dashed );
318  }
319 }