Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
moab::WriteGmsh Class Reference

Export Gmsh files. More...

#include <WriteGmsh.hpp>

+ Inheritance diagram for moab::WriteGmsh:
+ Collaboration diagram for moab::WriteGmsh:

Public Member Functions

 WriteGmsh (Interface *impl)
 Constructor. More...
 
virtual ~WriteGmsh ()
 Destructor. More...
 
ErrorCode write_file (const char *file_name, const bool overwrite, const FileOptions &opts, const EntityHandle *output_list, const int num_sets, const std::vector< std::string > &qa_list, const Tag *tag_list=NULL, int num_tags=0, int export_dimension=3)
 writes out a file More...
 
- Public Member Functions inherited from moab::WriterIface
virtual ~WriterIface ()
 

Static Public Member Functions

static WriterIfacefactory (Interface *)
 factory method More...
 

Private Attributes

InterfacembImpl
 interface instance More...
 
WriteUtilIfacemWriteIface
 

Detailed Description

Export Gmsh files.

Author
Jason Kraftcheck

Known limitations:

  • Tag data and most sets cannot be saved.
  • For blocks, geometry sets, and parallel partitions, the sets are saved but the IDs may be lost.
  • File format does not support general polygons or polyhedra.
  • File format does not support higher-order volume elements other than TET10 and HEX27.

Definition at line 40 of file WriteGmsh.hpp.

Constructor & Destructor Documentation

◆ WriteGmsh()

moab::WriteGmsh::WriteGmsh ( Interface impl)

Constructor.

Definition at line 25 of file WriteGmsh.cpp.

25  : mbImpl( impl )
26 {
28 }

References mWriteIface, and moab::Interface::query_interface().

Referenced by factory().

◆ ~WriteGmsh()

moab::WriteGmsh::~WriteGmsh ( )
virtual

Destructor.

Definition at line 30 of file WriteGmsh.cpp.

31 {
33 }

References mbImpl, mWriteIface, and moab::Interface::release_interface().

Member Function Documentation

◆ factory()

WriterIface * moab::WriteGmsh::factory ( Interface iface)
static

factory method

Definition at line 20 of file WriteGmsh.cpp.

21 {
22  return new WriteGmsh( iface );
23 }

References iface, and WriteGmsh().

Referenced by moab::ReaderWriterSet::ReaderWriterSet().

◆ write_file()

ErrorCode moab::WriteGmsh::write_file ( const char *  file_name,
const bool  overwrite,
const FileOptions opts,
const EntityHandle output_list,
const int  num_sets,
const std::vector< std::string > &  qa_list,
const Tag tag_list = NULL,
int  num_tags = 0,
int  export_dimension = 3 
)
virtual

writes out a file

Writes out a file.

Implements moab::WriterIface.

Definition at line 51 of file WriteGmsh.cpp.

60 {
61  ErrorCode rval;
62  Tag global_id = 0, block_tag = 0, geom_tag = 0, prtn_tag = 0;
63 
64  if( !overwrite )
65  {
66  rval = mWriteIface->check_doesnt_exist( file_name );
67  if( MB_SUCCESS != rval ) return rval;
68  }
69 
70  // Get tags
71  global_id = mbImpl->globalId_tag();
73  if( global_id ) mbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag );
75 
76  // Define arrays to hold entity sets of interest
77  Range sets[3];
78  Tag set_tags[] = { block_tag, geom_tag, prtn_tag };
79  Tag set_ids[] = { block_tag, 0 /*global_id*/, prtn_tag };
80 
81  // Get entities to write
82  Range elements, nodes;
83  if( !output_list )
84  {
85  rval = mbImpl->get_entities_by_dimension( 0, 0, nodes, false );
86  if( MB_SUCCESS != rval ) return rval;
87  for( int d = 1; d <= 3; ++d )
88  {
89  Range tmp_range;
90  rval = mbImpl->get_entities_by_dimension( 0, d, tmp_range, false );
91  if( MB_SUCCESS != rval ) return rval;
92  elements.merge( tmp_range );
93  }
94 
95  for( int s = 0; s < 3; ++s )
96  {
97  if( set_tags[s] )
98  {
99  rval = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, set_tags + s, 0, 1, sets[s] );
100  if( MB_SUCCESS != rval ) return rval;
101  }
102  }
103  }
104  else
105  {
106  for( int i = 0; i < num_sets; ++i )
107  {
108  EntityHandle set = output_list[i];
109  for( int d = 1; d < 3; ++d )
110  {
111  Range tmp_range, tmp_nodes;
112  rval = mbImpl->get_entities_by_dimension( set, d, tmp_range, true );
113  if( rval != MB_SUCCESS ) return rval;
114  elements.merge( tmp_range );
115  rval = mbImpl->get_adjacencies( tmp_range, set, false, tmp_nodes );
116  if( rval != MB_SUCCESS ) return rval;
117  nodes.merge( tmp_nodes );
118  }
119 
120  for( int s = 0; s < 3; ++s )
121  {
122  if( set_tags[s] )
123  {
124  Range tmp_range;
125  rval = mbImpl->get_entities_by_type_and_tag( set, MBENTITYSET, set_tags + s, 0, 1, tmp_range );
126  if( MB_SUCCESS != rval ) return rval;
127  sets[s].merge( tmp_range );
128  int junk;
129  rval = mbImpl->tag_get_data( set_tags[s], &set, 1, &junk );
130  if( MB_SUCCESS == rval ) sets[s].insert( set );
131  }
132  }
133  }
134  }
135 
136  if( elements.empty() )
137  {
138  MB_SET_ERR( MB_ENTITY_NOT_FOUND, "Nothing to write" );
139  }
140 
141  // Get global IDs for all elements.
142  // First try to get from tag. If tag is not defined or not set
143  // for all elements, use handle value instead.
144  std::vector< int > global_id_array( elements.size() );
145  std::vector< int >::iterator id_iter;
146  if( !global_id || MB_SUCCESS != mbImpl->tag_get_data( global_id, elements, &global_id_array[0] ) )
147  {
148  id_iter = global_id_array.begin();
149  for( Range::iterator i = elements.begin(); i != elements.end(); ++i, ++id_iter )
150  *id_iter = mbImpl->id_from_handle( *i );
151  }
152 
153  // Figure out the maximum ID value so we know where to start allocating
154  // new IDs when we encounter ID conflicts.
155  int max_id = 0;
156  for( id_iter = global_id_array.begin(); id_iter != global_id_array.end(); ++id_iter )
157  if( *id_iter > max_id ) max_id = *id_iter;
158 
159  // Initialize ElemInfo struct for each element
160  std::map< EntityHandle, ElemInfo > elem_sets; // Per-element info
161  std::set< int > elem_global_ids; // Temporary for finding duplicate IDs
162  id_iter = global_id_array.begin();
163  // Iterate backwards to give highest-dimension entities first dibs for
164  // a conflicting ID.
165  for( Range::reverse_iterator i = elements.rbegin(); i != elements.rend(); ++i )
166  {
167  int id = *id_iter;
168  ++id_iter;
169  if( !elem_global_ids.insert( id ).second ) id = ++max_id;
170 
171  ElemInfo& ei = elem_sets[*i];
172  ei.count = 0;
173  ei.id = id;
174 
175  EntityType type = mbImpl->type_from_handle( *i );
176  int num_vtx;
177  const EntityHandle* conn;
178  rval = mbImpl->get_connectivity( *i, conn, num_vtx );
179  if( MB_SUCCESS != rval ) return rval;
180 
181  ei.type = GmshUtil::get_gmsh_type( type, num_vtx );
182  if( ei.type < 0 )
183  {
184  MB_SET_ERR( MB_FILE_WRITE_ERROR, "Gmem file format does not support element of type "
185  << CN::EntityTypeName( type ) << " with " << num_vtx << " vertices" );
186  }
187  }
188  // Don't need these any more, free memory.
189  elem_global_ids.clear();
190  global_id_array.clear();
191 
192  // For each material set, geometry set, or partition; store
193  // the ID of the set on each element.
194  for( int s = 0; s < 3; ++s )
195  {
196  if( !set_tags[s] ) continue;
197 
198  for( Range::iterator i = sets[s].begin(); i != sets[s].end(); ++i )
199  {
200  int id;
201  if( set_ids[s] )
202  {
203  rval = mbImpl->tag_get_data( set_ids[s], &*i, 1, &id );
204  if( MB_SUCCESS != rval ) return rval;
205  }
206  else
207  id = mbImpl->id_from_handle( *i );
208 
209  Range elems;
210  rval = mbImpl->get_entities_by_handle( *i, elems );
211  if( MB_SUCCESS != rval ) return rval;
212 
213  elems = intersect( elems, elements );
214  for( Range::iterator j = elems.begin(); j != elems.end(); ++j )
215  elem_sets[*j].set( s, id );
216  }
217  }
218 
219  // Create file
220  std::ofstream out( file_name );
221  if( !out ) return MB_FILE_DOES_NOT_EXIST;
222 
223  // Write header
224  out << "$MeshFormat" << std::endl;
225  out << "2.0 0 " << sizeof( double ) << std::endl;
226  out << "$EndMeshFormat" << std::endl;
227 
228  // Set precision for node coordinates
229  int precision;
230  if( MB_SUCCESS != options.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION;
231  const int old_precision = out.precision();
232  out.precision( precision );
233 
234  // Write nodes
235  out << "$Nodes" << std::endl;
236  out << nodes.size() << std::endl;
237  std::vector< double > coords( 3 * nodes.size() );
238  rval = mbImpl->get_coords( nodes, &coords[0] );
239  if( MB_SUCCESS != rval ) return rval;
240  std::vector< double >::iterator c = coords.begin();
241  for( Range::iterator i = nodes.begin(); i != nodes.end(); ++i )
242  {
243  out << mbImpl->id_from_handle( *i );
244  out << " " << *c;
245  ++c;
246  out << " " << *c;
247  ++c;
248  out << " " << *c;
249  ++c;
250  out << std::endl;
251  }
252  out << "$EndNodes" << std::endl;
253  coords.clear();
254 
255  // Restore stream state
256  out.precision( old_precision );
257 
258  // Write elements
259  out << "$Elements" << std::endl;
260  out << elem_sets.size() << std::endl;
261  for( std::map< EntityHandle, ElemInfo >::iterator i = elem_sets.begin(); i != elem_sets.end(); ++i )
262  {
263  int num_vtx;
264  const EntityHandle* conn;
265  rval = mbImpl->get_connectivity( i->first, conn, num_vtx );
266  if( MB_SUCCESS != rval ) return rval;
267  out << i->second.id << ' ' << i->second.type << ' ' << i->second.count;
268  for( int j = 0; j < i->second.count; ++j )
269  out << ' ' << i->second.sets[j];
270 
271  const int* order = GmshUtil::gmshElemTypes[i->second.type].node_order;
272 
273  // Need to re-order vertices
274  if( order )
275  {
276  for( int j = 0; j < num_vtx; ++j )
277  out << ' ' << mbImpl->id_from_handle( conn[order[j]] );
278  }
279  else
280  {
281  for( int j = 0; j < num_vtx; ++j )
282  out << ' ' << mbImpl->id_from_handle( conn[j] );
283  }
284  out << std::endl;
285  }
286  out << "$EndElements" << std::endl;
287 
288  // Done
289  return MB_SUCCESS;
290 }

References moab::Range::begin(), moab::WriteUtilIface::check_doesnt_exist(), moab::ElemInfo::count, moab::DEFAULT_PRECISION, moab::Range::empty(), moab::Range::end(), moab::CN::EntityTypeName(), ErrorCode, GEOM_DIMENSION_TAG_NAME, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type_and_tag(), moab::GmshUtil::get_gmsh_type(), moab::FileOptions::get_int_option(), moab::Interface::globalId_tag(), moab::GmshUtil::gmshElemTypes, moab::ElemInfo::id, moab::Interface::id_from_handle(), moab::Range::insert(), moab::intersect(), MATERIAL_SET_TAG_NAME, MB_ENTITY_NOT_FOUND, MB_FILE_DOES_NOT_EXIST, MB_FILE_WRITE_ERROR, MB_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, MBENTITYSET, mbImpl, moab::Range::merge(), mWriteIface, moab::GmshElemType::node_order, PARALLEL_PARTITION_TAG_NAME, moab::Range::rbegin(), moab::Range::rend(), moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::ElemInfo::type, and moab::Interface::type_from_handle().

Member Data Documentation

◆ mbImpl

Interface* moab::WriteGmsh::mbImpl
private

interface instance

Definition at line 66 of file WriteGmsh.hpp.

Referenced by write_file(), and ~WriteGmsh().

◆ mWriteIface

WriteUtilIface* moab::WriteGmsh::mWriteIface
private

Definition at line 67 of file WriteGmsh.hpp.

Referenced by write_file(), WriteGmsh(), and ~WriteGmsh().


The documentation for this class was generated from the following files: