root/MOAB/trunk/WriteGMV.cpp

Revision 2303, 11.2 kB (checked in by kraftche, 3 months ago)

make qa_list argument to writers const

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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 Coroporation, 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
17 #ifdef WIN32
18 #ifdef _DEBUG
19 // turn off warnings that say they debugging identifier has been truncated
20 // this warning comes up when using some STL containers
21 #pragma warning(disable : 4786)
22 #endif
23 #endif
24
25 #include "WriteGMV.hpp"
26
27 #include "MBInterface.hpp"
28 #include "MBInternals.hpp"
29 #include "MBRange.hpp"
30 #include "MBCN.hpp"
31 #include "MBTagConventions.hpp"
32 #include "MBWriteUtilIface.hpp"
33 #include <fstream>
34 #include <assert.h>
35
36 const char *WriteGMV::gmvTypeNames[] = {
37   "",
38   "line",
39   "tri",
40   "quad",
41   "",
42   "tet",
43   "pyramid",
44   "prism",
45   "",
46   "hex",
47   "",
48   ""
49 };
50
51 MBWriterIface* WriteGMV::factory( MBInterface* iface )
52   { return new WriteGMV( iface ); }
53
54 WriteGMV::WriteGMV(MBInterface *impl)
55     : mbImpl(impl), mCurrentMeshHandle(0)
56 {
57   assert(impl != NULL);
58
59   std::string iface_name = "MBWriteUtilIface";
60   impl->query_interface(iface_name, reinterpret_cast<void**>(&mWriteIface));
61
62   // initialize in case tag_get_handle fails below
63   mMaterialSetTag  = 0;
64   mDirichletSetTag = 0;
65   mNeumannSetTag   = 0;
66   mHasMidNodesTag  = 0;
67   mGeomDimensionTag= 0;
68   mGlobalIdTag= 0;
69
70   //! get and cache predefined tag handles
71   // initialize in case tag_get_handle fails below
72   //! get and cache predefined tag handles
73   int dum_val = 0;
74   MBErrorCode result = impl->tag_get_handle(MATERIAL_SET_TAG_NAME,  mMaterialSetTag);
75   if (MB_TAG_NOT_FOUND == result)
76     result = impl->tag_create(MATERIAL_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mMaterialSetTag,
77                               &dum_val);
78  
79   result = impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, mDirichletSetTag);
80   if (MB_TAG_NOT_FOUND == result)
81     result = impl->tag_create(DIRICHLET_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mDirichletSetTag,
82                               &dum_val);
83  
84   result = impl->tag_get_handle(NEUMANN_SET_TAG_NAME,   mNeumannSetTag);
85   if (MB_TAG_NOT_FOUND == result)
86     result = impl->tag_create(NEUMANN_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mNeumannSetTag,
87                               &dum_val);
88  
89   result = impl->tag_get_handle(HAS_MID_NODES_TAG_NAME, mHasMidNodesTag);
90   if (MB_TAG_NOT_FOUND == result) {
91     int dum_val_array[] = {0, 0, 0, 0};
92     result = impl->tag_create(HAS_MID_NODES_TAG_NAME, 4*sizeof(int), MB_TAG_SPARSE, mHasMidNodesTag,
93                               dum_val_array);
94   }
95  
96   result = impl->tag_get_handle(GLOBAL_ID_TAG_NAME,             mGlobalIdTag);
97   if (MB_TAG_NOT_FOUND == result)
98     result = impl->tag_create(GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mGlobalIdTag,
99                               &dum_val);
100 }
101
102 WriteGMV::~WriteGMV() 
103 {
104   std::string iface_name = "MBWriteUtilIface";
105   mbImpl->release_interface(iface_name, mWriteIface);
106 }
107
108 MBErrorCode WriteGMV::write_file(const char *file_name,
109                                  const MBEntityHandle output_set,
110                                  const int user_dimension,
111                                  const bool mesh,
112                                  const bool poly_mesh)
113 {
114     // general function for writing a mesh
115  
116   MBErrorCode result = MB_SUCCESS;
117
118     // initialize file
119
120   if (mesh) {
121     result = local_write_mesh(file_name, output_set, user_dimension, true, false);
122     if (MB_SUCCESS != result) return result;
123   }
124  
125   if (poly_mesh) {
126     result = local_write_mesh(file_name, output_set, user_dimension, false, true);
127     if (MB_SUCCESS != result) return result;
128   }
129  
130   return result;
131 }
132
133 MBErrorCode WriteGMV::write_file( const char* filename,
134                                   const bool ,
135                                   const FileOptions& opts,
136                                   const MBEntityHandle* output_sets,
137                                   const int num_output_sets,
138                                   const std::vector<std::string>& ,
139                                   int dimension )
140 {
141   MBEntityHandle output_set = 0;
142   if (output_sets && num_output_sets > 0)
143   {
144     if (num_output_sets > 1)
145       return MB_FAILURE;
146     output_set = output_sets[0];
147   }
148  
149   if (dimension == 0)
150   {
151     mbImpl->get_dimension( dimension );
152   }
153  
154   return write_file( filename, output_set, dimension, true, true );
155 }
156  
157
158 MBErrorCode WriteGMV::local_write_mesh(const char *file_name,
159                                        const MBEntityHandle output_set,
160                                        const int user_dimension,
161                                        const bool mesh,
162                                        const bool poly_mesh)
163 {
164   std::ofstream ofile;
165   MBErrorCode result;
166
167   if (mesh) {
168       // need to insert ".gmv"
169     std::string tmp_name(file_name);
170     tmp_name += ".gmv";
171     ofile.open(tmp_name.c_str());
172   }
173   else if (poly_mesh) {
174       // need to insert ".poly.gmv"
175     std::string tmp_name(file_name);
176     tmp_name += ".poly.gmv";
177     ofile.open(tmp_name.c_str());
178   }
179
180   ofile << "gmvinput ascii" << std::endl;
181  
182     // get elements to be output
183   MBRange dum_range, elements, all_verts;
184   MBEntityType otype;
185   if (poly_mesh) {
186     result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, elements, true);
187     if (MB_SUCCESS != result) return result;
188   }
189   else {
190     for (otype = MBCN::TypeDimensionMap[user_dimension].first;
191          otype <= MBCN::TypeDimensionMap[user_dimension].second; otype++) {
192       if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue;
193       dum_range.clear();
194       result = mbImpl->get_entities_by_type(output_set, otype, dum_range, true);
195       if (MB_SUCCESS != result) return result;
196
197       std::copy(dum_range.begin(), dum_range.end(), mb_range_inserter(elements));
198     }
199   }
200  
201     // gather the vertices in these elements
202   result = mbImpl->get_adjacencies(elements, 0, false, all_verts, MBInterface::UNION);
203   if (MB_SUCCESS != result) return result;
204  
205   int num_verts = all_verts.size();
206  
207     // allocate coordinate arrays and put pointers to them in a list
208   double *xcoord = new double[num_verts];
209   double *ycoord = new double[num_verts];
210   double *zcoord = new double[num_verts];
211   std::vector<double*> coord_arrays;
212   coord_arrays.push_back(xcoord);
213   coord_arrays.push_back(ycoord);
214   coord_arrays.push_back(zcoord);
215  
216     // fill them in, writing id tags at the same time
217   result = mWriteIface->get_node_arrays(3, num_verts, all_verts, mGlobalIdTag, 1, coord_arrays);
218   if (MB_SUCCESS != result) return result;
219
220   int i, j;
221  
222     //========================================
223     // WRITE COORDINATE DATA TO FILE HERE
224
225   ofile << "nodev " << num_verts << std::endl;
226   for (i = 0; i < num_verts; i++)
227     ofile << xcoord[i] << " " << ycoord[i] << " " << zcoord[i] << std::endl;
228  
229
230     //========================================
231
232   delete [] xcoord;
233   delete [] ycoord;
234   delete [] zcoord;
235
236     // iterate over types in selected dimension
237
238   std::vector<int> connect;
239   std::vector<MBEntityHandle> connecth;
240
241   if (mesh) {
242     MBRange sub_range;
243    
244     ofile << "cells " << elements.size() << std::endl;
245  
246     for (MBEntityType otype = MBCN::TypeDimensionMap[user_dimension].first;
247          otype <= MBCN::TypeDimensionMap[user_dimension].second; otype++) {
248
249       if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue;
250      
251         // get the first element of this type in the range, and one past the last
252       MBRange::iterator lower =
253         MBRange::lower_bound(elements.begin(),
254                              elements.end(),
255                              CREATE_HANDLE(otype, MB_START_ID, i));
256       MBRange::iterator upper =
257         MBRange::lower_bound(elements.begin(),
258                              elements.end(),
259                              CREATE_HANDLE(otype+1, MB_START_ID, i));
260      
261       if (lower == upper) continue;
262    
263         // copy these elements into a subrange
264       sub_range.clear();
265       std::copy(lower, upper, mb_range_inserter(sub_range));
266
267         // make sure the connectivity array is big enough
268       int verts_per = MBCN::VerticesPerEntity(otype);
269       if (connect.size() < verts_per*sub_range.size())
270         connect.reserve(verts_per*sub_range.size());
271    
272         // get the connectivity
273       result = mWriteIface->get_element_array(sub_range.size(),
274                                               verts_per,
275                                               mGlobalIdTag, sub_range,
276                                               mGlobalIdTag, 1, &connect[0]);
277       if (MB_SUCCESS != result) return result;
278
279         //========================================
280         // WRITE CONNECTIVITY DATA TO FILE HERE
281
282       for (i = 0; i < (int) sub_range.size(); i++) {
283         ofile << gmvTypeNames[otype] << " " << verts_per << std::endl;
284         for (j = i*verts_per; j < (int) (i+1)*verts_per; j++)
285           ofile << connect[j] << " ";
286         ofile << std::endl;
287       }
288
289         //========================================
290     }
291   }
292  
293   else if (poly_mesh) {
294  
295       // write polygons/hedra, if any
296     MBRange polygons, polyhedra;
297     result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, polygons, true);
298     if (MB_SUCCESS != result) return result;
299  
300     result = mbImpl->get_entities_by_type(output_set, MBPOLYHEDRON, polyhedra, true);
301     if (MB_SUCCESS != result) return result;
302
303     if (polygons.size() == 0) return result;
304  
305       // mark polyhedra with global ids
306     result = mWriteIface->assign_ids(polyhedra, mGlobalIdTag, 1);
307     if (MB_SUCCESS != result) return result;
308
309     ofile << "faces " << polygons.size() << " " << polyhedra.size() << std::endl;
310
311     for (MBRange::iterator rit = polygons.begin(); rit != polygons.end(); rit++) {
312         // get the vertices
313       connecth.clear();
314       result = mbImpl->get_connectivity(&(*rit), 1, connecth, true);
315       if (MB_SUCCESS != result) return result;
316
317       if (0 == connecth.size()) continue;
318    
319         // get the polyhedra, if any
320       if (user_dimension == 3) {
321         polyhedra.clear();
322         result = mbImpl->get_adjacencies(MBRange(*rit, *rit), 3, false, polyhedra);
323         if (MB_SUCCESS != result) return result;
324    
325           // put them in the connect array
326         connecth.push_back((polyhedra.size() > 0 ? *polyhedra.begin() : 0));
327         connecth.push_back((polyhedra.size() > 1 ? *polyhedra.rbegin() : 0));
328       }
329    
330         // replace handles with ids
331       connect.reserve(connecth.size());
332
333         // pre-set polyhedra ids in case there aren't any
334       connect[connecth.size()] = 0;
335       connect[connecth.size()+1] = 0;
336       result = mbImpl->tag_get_data(mGlobalIdTag, &connecth[0],
337                                     connecth.size()-2+polyhedra.size(),
338                                     &connect[0]);
339       if (MB_SUCCESS != result) return result;
340    
341         // write the data
342       ofile << connecth.size()-2;
343    
344       for (i = 0; i < (int)connecth.size(); i++)
345         ofile << " " << connect[i];
346
347       ofile << std::endl;
348     }
349   }
350
351   ofile << std::endl << "endgmv" << std::endl;
352  
353   ofile.close();
354  
355   return MB_SUCCESS;
356 }
357
Note: See TracBrowser for help on using the browser.