Branch data Line data Source code
1 : : /**
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : #ifdef WIN32
17 : : #ifdef _DEBUG
18 : : // turn off warnings that say they debugging identifier has been truncated
19 : : // this warning comes up when using some STL containers
20 : : #pragma warning( disable : 4786 )
21 : : #endif
22 : : #endif
23 : :
24 : : #include "WriteGMV.hpp"
25 : :
26 : : #include "moab/Interface.hpp"
27 : : #include "Internals.hpp"
28 : : #include "moab/Range.hpp"
29 : : #include "moab/CN.hpp"
30 : : #include "MBTagConventions.hpp"
31 : : #include "moab/WriteUtilIface.hpp"
32 : : #include <fstream>
33 : : #include <assert.h>
34 : :
35 : : namespace moab
36 : : {
37 : :
38 : : const char* WriteGMV::gmvTypeNames[] = { "", "line", "tri", "quad", "", "tet", "pyramid", "prism", "", "hex", "", "" };
39 : :
40 : 0 : WriterIface* WriteGMV::factory( Interface* iface )
41 : : {
42 [ # # ]: 0 : return new WriteGMV( iface );
43 : : }
44 : :
45 : 0 : WriteGMV::WriteGMV( Interface* impl ) : mbImpl( impl )
46 : : {
47 [ # # ]: 0 : assert( impl != NULL );
48 : :
49 [ # # ]: 0 : impl->query_interface( mWriteIface );
50 : :
51 : : // initialize in case tag_get_handle fails below
52 : 0 : mMaterialSetTag = 0;
53 : 0 : mDirichletSetTag = 0;
54 : 0 : mNeumannSetTag = 0;
55 : 0 : mHasMidNodesTag = 0;
56 : 0 : mGeomDimensionTag = 0;
57 : 0 : mGlobalIdTag = 0;
58 : :
59 : : //! get and cache predefined tag handles
60 : : // initialize in case tag_get_handle fails below
61 : : //! get and cache predefined tag handles
62 : 0 : int negone = -1;
63 : : impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
64 [ # # ]: 0 : &negone );
65 : :
66 : : impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
67 [ # # ]: 0 : &negone );
68 : :
69 : : impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
70 [ # # ]: 0 : &negone );
71 : :
72 [ # # ]: 0 : mGlobalIdTag = impl->globalId_tag();
73 : :
74 : 0 : int dum_val_array[] = { -1, -1, -1, -1 };
75 : : impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT,
76 [ # # ]: 0 : dum_val_array );
77 : 0 : }
78 : :
79 : 0 : WriteGMV::~WriteGMV()
80 : : {
81 : 0 : mbImpl->release_interface( mWriteIface );
82 [ # # ]: 0 : }
83 : :
84 : 0 : ErrorCode WriteGMV::write_file( const char* file_name, const EntityHandle output_set, const int user_dimension,
85 : : const bool mesh, const bool poly_mesh )
86 : : {
87 : : // general function for writing a mesh
88 : :
89 : 0 : ErrorCode result = MB_SUCCESS;
90 : :
91 : : // initialize file
92 : :
93 [ # # ]: 0 : if( mesh )
94 : : {
95 : 0 : result = local_write_mesh( file_name, output_set, user_dimension, true, false );
96 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
97 : : }
98 : :
99 [ # # ]: 0 : if( poly_mesh )
100 : : {
101 : 0 : result = local_write_mesh( file_name, output_set, user_dimension, false, true );
102 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
103 : : }
104 : :
105 : 0 : return result;
106 : : }
107 : :
108 : 0 : ErrorCode WriteGMV::write_file( const char* filename, const bool, const FileOptions& /*opts*/,
109 : : const EntityHandle* output_sets, const int num_output_sets,
110 : : const std::vector< std::string >&, const Tag*, int, int dimension )
111 : : {
112 : 0 : EntityHandle output_set = 0;
113 [ # # ][ # # ]: 0 : if( output_sets && num_output_sets > 0 )
114 : : {
115 [ # # ]: 0 : if( num_output_sets > 1 ) return MB_FAILURE;
116 : 0 : output_set = output_sets[0];
117 : : }
118 : :
119 [ # # ]: 0 : if( dimension == 0 ) { mbImpl->get_dimension( dimension ); }
120 : :
121 : 0 : return write_file( filename, output_set, dimension, true, true );
122 : : }
123 : :
124 : 0 : ErrorCode WriteGMV::local_write_mesh( const char* file_name, const EntityHandle output_set, const int user_dimension,
125 : : const bool mesh, const bool poly_mesh )
126 : : {
127 [ # # ]: 0 : std::ofstream ofile;
128 : : ErrorCode result;
129 : :
130 [ # # ]: 0 : if( mesh )
131 : : {
132 : : // need to insert ".gmv"
133 [ # # ]: 0 : std::string tmp_name( file_name );
134 [ # # ]: 0 : tmp_name += ".gmv";
135 [ # # ][ # # ]: 0 : ofile.open( tmp_name.c_str() );
136 : : }
137 [ # # ]: 0 : else if( poly_mesh )
138 : : {
139 : : // need to insert ".poly.gmv"
140 [ # # ]: 0 : std::string tmp_name( file_name );
141 [ # # ]: 0 : tmp_name += ".poly.gmv";
142 [ # # ][ # # ]: 0 : ofile.open( tmp_name.c_str() );
143 : : }
144 : :
145 [ # # ][ # # ]: 0 : ofile << "gmvinput ascii" << std::endl;
146 : :
147 : : // get elements to be output
148 [ # # ][ # # ]: 0 : Range dum_range, elements, all_verts;
[ # # ]
149 : : EntityType otype;
150 [ # # ]: 0 : if( poly_mesh )
151 : : {
152 [ # # ]: 0 : result = mbImpl->get_entities_by_type( output_set, MBPOLYGON, elements, true );
153 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
154 : : }
155 : : else
156 : : {
157 [ # # ][ # # ]: 0 : for( otype = CN::TypeDimensionMap[user_dimension].first; otype <= CN::TypeDimensionMap[user_dimension].second;
158 : : otype++ )
159 : : {
160 [ # # ][ # # ]: 0 : if( otype == MBPOLYGON || otype == MBPOLYHEDRON ) continue;
161 [ # # ]: 0 : dum_range.clear();
162 [ # # ]: 0 : result = mbImpl->get_entities_by_type( output_set, otype, dum_range, true );
163 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
164 : :
165 [ # # ][ # # ]: 0 : std::copy( dum_range.begin(), dum_range.end(), range_inserter( elements ) );
[ # # ][ # # ]
166 : : }
167 : : }
168 : :
169 : : // gather the vertices in these elements
170 [ # # ]: 0 : result = mbImpl->get_adjacencies( elements, 0, false, all_verts, Interface::UNION );
171 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
172 : :
173 [ # # ]: 0 : int num_verts = all_verts.size();
174 : :
175 : : // allocate coordinate arrays and put pointers to them in a list
176 [ # # ][ # # ]: 0 : double* xcoord = new double[num_verts];
177 [ # # ][ # # ]: 0 : double* ycoord = new double[num_verts];
178 [ # # ][ # # ]: 0 : double* zcoord = new double[num_verts];
179 [ # # ]: 0 : std::vector< double* > coord_arrays;
180 [ # # ]: 0 : coord_arrays.push_back( xcoord );
181 [ # # ]: 0 : coord_arrays.push_back( ycoord );
182 [ # # ]: 0 : coord_arrays.push_back( zcoord );
183 : :
184 : : // fill them in, writing id tags at the same time
185 [ # # ]: 0 : result = mWriteIface->get_node_coords( 3, num_verts, all_verts, mGlobalIdTag, 1, coord_arrays );
186 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
187 : :
188 : : int i, j;
189 : :
190 : : //========================================
191 : : // WRITE COORDINATE DATA TO FILE HERE
192 : :
193 [ # # ][ # # ]: 0 : ofile << "nodev " << num_verts << std::endl;
[ # # ]
194 [ # # ]: 0 : for( i = 0; i < num_verts; i++ )
195 [ # # ][ # # ]: 0 : ofile << xcoord[i] << " " << ycoord[i] << " " << zcoord[i] << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
196 : :
197 : : //========================================
198 : :
199 [ # # ]: 0 : delete[] xcoord;
200 [ # # ]: 0 : delete[] ycoord;
201 [ # # ]: 0 : delete[] zcoord;
202 : :
203 : : // iterate over types in selected dimension
204 : :
205 [ # # ]: 0 : std::vector< int > connect;
206 [ # # ]: 0 : std::vector< EntityHandle > connecth;
207 : :
208 [ # # ]: 0 : if( mesh )
209 : : {
210 [ # # ]: 0 : Range sub_range;
211 : :
212 [ # # ][ # # ]: 0 : ofile << "cells " << elements.size() << std::endl;
[ # # ][ # # ]
213 : :
214 [ # # ][ # # ]: 0 : for( otype = CN::TypeDimensionMap[user_dimension].first; otype <= CN::TypeDimensionMap[user_dimension].second;
[ # # ]
215 : : otype++ )
216 : : {
217 : :
218 [ # # ][ # # ]: 0 : if( otype == MBPOLYGON || otype == MBPOLYHEDRON ) continue;
219 : :
220 : : // get the first element of this type in the range, and one past the last
221 : : Range::iterator lower =
222 [ # # ][ # # ]: 0 : Range::lower_bound( elements.begin(), elements.end(), CREATE_HANDLE( otype, MB_START_ID, i ) );
[ # # ][ # # ]
223 : : Range::iterator upper =
224 [ # # ][ # # ]: 0 : Range::lower_bound( elements.begin(), elements.end(), CREATE_HANDLE( otype + 1, MB_START_ID, i ) );
[ # # ][ # # ]
225 : :
226 [ # # ][ # # ]: 0 : if( lower == upper ) continue;
227 : :
228 : : // copy these elements into a subrange
229 [ # # ]: 0 : sub_range.clear();
230 [ # # ][ # # ]: 0 : std::copy( lower, upper, range_inserter( sub_range ) );
231 : :
232 : : // make sure the connectivity array is big enough
233 [ # # ]: 0 : int verts_per = CN::VerticesPerEntity( otype );
234 [ # # ][ # # ]: 0 : if( connect.size() < verts_per * sub_range.size() ) connect.resize( verts_per * sub_range.size() );
[ # # ][ # # ]
235 : :
236 : : // get the connectivity
237 [ # # ]: 0 : result = mWriteIface->get_element_connect( sub_range.size(), verts_per, mGlobalIdTag, sub_range,
238 [ # # ][ # # ]: 0 : mGlobalIdTag, 1, &connect[0] );
239 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
240 : :
241 : : //========================================
242 : : // WRITE CONNECTIVITY DATA TO FILE HERE
243 : :
244 [ # # ][ # # ]: 0 : for( i = 0; i < (int)sub_range.size(); i++ )
245 : : {
246 [ # # ][ # # ]: 0 : ofile << gmvTypeNames[otype] << " " << verts_per << std::endl;
[ # # ][ # # ]
247 [ # # ]: 0 : for( j = i * verts_per; j < (int)( i + 1 ) * verts_per; j++ )
248 [ # # ][ # # ]: 0 : ofile << connect[j] << " ";
[ # # ]
249 [ # # ]: 0 : ofile << std::endl;
250 : : }
251 : :
252 : : //========================================
253 : 0 : }
254 : : }
255 : :
256 [ # # ]: 0 : else if( poly_mesh )
257 : : {
258 : :
259 : : // write polygons/hedra, if any
260 [ # # ][ # # ]: 0 : Range polygons, polyhedra;
[ # # ]
261 [ # # ]: 0 : result = mbImpl->get_entities_by_type( output_set, MBPOLYGON, polygons, true );
262 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
263 : :
264 [ # # ]: 0 : result = mbImpl->get_entities_by_type( output_set, MBPOLYHEDRON, polyhedra, true );
265 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
266 : :
267 [ # # ][ # # ]: 0 : if( polygons.size() == 0 ) return result;
268 : :
269 : : // mark polyhedra with global ids
270 [ # # ]: 0 : result = mWriteIface->assign_ids( polyhedra, mGlobalIdTag, 1 );
271 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
272 : :
273 [ # # ][ # # ]: 0 : ofile << "faces " << polygons.size() << " " << polyhedra.size() << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
274 : :
275 [ # # ][ # # ]: 0 : for( Range::iterator rit = polygons.begin(); rit != polygons.end(); ++rit )
[ # # ][ # # ]
[ # # ]
276 : : {
277 : : // get the vertices
278 : 0 : connecth.clear();
279 [ # # ][ # # ]: 0 : result = mbImpl->get_connectivity( &( *rit ), 1, connecth, true );
280 [ # # ][ # # ]: 0 : if( MB_SUCCESS != result ) return result;
281 : :
282 [ # # ]: 0 : if( 0 == connecth.size() ) continue;
283 : :
284 : : // get the polyhedra, if any
285 [ # # ]: 0 : if( user_dimension == 3 )
286 : : {
287 [ # # ]: 0 : polyhedra.clear();
288 [ # # ][ # # ]: 0 : result = mbImpl->get_adjacencies( Range( *rit, *rit ), 3, false, polyhedra );
[ # # ][ # # ]
289 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
290 : :
291 : : // put them in the connect array
292 [ # # ][ # # ]: 0 : connecth.push_back( ( polyhedra.size() > 0 ? *polyhedra.begin() : 0 ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
293 [ # # ][ # # ]: 0 : connecth.push_back( ( polyhedra.size() > 1 ? *polyhedra.rbegin() : 0 ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
294 : : }
295 : :
296 : : // replace handles with ids
297 [ # # ]: 0 : connect.resize( connecth.size() + 2 );
298 : :
299 : : // pre-set polyhedra ids in case there aren't any
300 [ # # ]: 0 : connect[connecth.size()] = 0;
301 [ # # ]: 0 : connect[connecth.size() + 1] = 0;
302 : : result =
303 [ # # ][ # # ]: 0 : mbImpl->tag_get_data( mGlobalIdTag, &connecth[0], connecth.size() - 2 + polyhedra.size(), &connect[0] );
[ # # ][ # # ]
304 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
305 : :
306 : : // write the data
307 [ # # ]: 0 : ofile << connecth.size() - 2;
308 : :
309 [ # # ]: 0 : for( i = 0; i < (int)connecth.size(); i++ )
310 [ # # ][ # # ]: 0 : ofile << " " << connect[i];
[ # # ]
311 : :
312 [ # # ]: 0 : ofile << std::endl;
313 : 0 : }
314 : : }
315 : :
316 [ # # ][ # # ]: 0 : ofile << std::endl << "endgmv" << std::endl;
[ # # ]
317 : :
318 [ # # ]: 0 : ofile.close();
319 : :
320 : 0 : return MB_SUCCESS;
321 : : }
322 : :
323 [ + - ][ + - ]: 228 : } // namespace moab
|