moab
WriteGMV.cpp
Go to the documentation of this file.
00001 
00017 #ifdef WIN32
00018 #ifdef _DEBUG
00019 // turn off warnings that say they debugging identifier has been truncated
00020 // this warning comes up when using some STL containers
00021 #pragma warning(disable : 4786)
00022 #endif
00023 #endif
00024 
00025 #include "WriteGMV.hpp"
00026 
00027 #include "moab/Interface.hpp"
00028 #include "Internals.hpp"
00029 #include "moab/Range.hpp"
00030 #include "moab/CN.hpp"
00031 #include "MBTagConventions.hpp"
00032 #include "moab/WriteUtilIface.hpp"
00033 #include <fstream>
00034 #include <assert.h>
00035 
00036 namespace moab {
00037 
00038 const char *WriteGMV::gmvTypeNames[] = {
00039   "",
00040   "line",
00041   "tri",
00042   "quad",
00043   "",
00044   "tet",
00045   "pyramid",
00046   "prism",
00047   "",
00048   "hex",
00049   "",
00050   ""
00051 };
00052 
00053 WriterIface* WriteGMV::factory( Interface* iface )
00054   { return new WriteGMV( iface ); }
00055 
00056 WriteGMV::WriteGMV(Interface *impl) 
00057     : mbImpl(impl), mCurrentMeshHandle(0)
00058 {
00059   assert(impl != NULL);
00060 
00061   impl->query_interface( mWriteIface );
00062 
00063   // initialize in case tag_get_handle fails below
00064   mMaterialSetTag  = 0;
00065   mDirichletSetTag = 0;
00066   mNeumannSetTag   = 0;
00067   mHasMidNodesTag  = 0;
00068   mGeomDimensionTag= 0;
00069   mGlobalIdTag= 0;
00070 
00072   // initialize in case tag_get_handle fails below
00074   int zero = 0, negone = -1;
00075   impl->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00076                        mMaterialSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00077 
00078   impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00079                        mDirichletSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00080 
00081   impl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00082                        mNeumannSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone);
00083 
00084   impl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER,
00085                        mGlobalIdTag, MB_TAG_SPARSE|MB_TAG_CREAT, &zero);
00086 
00087   int dum_val_array[] = {-1, -1, -1, -1};
00088   impl->tag_get_handle(HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER,
00089                        mHasMidNodesTag, MB_TAG_SPARSE|MB_TAG_CREAT, dum_val_array);
00090 }
00091 
00092 WriteGMV::~WriteGMV() 
00093 {
00094   mbImpl->release_interface(mWriteIface);
00095 }
00096 
00097 ErrorCode WriteGMV::write_file(const char *file_name,
00098                                  const EntityHandle output_set,
00099                                  const int user_dimension,
00100                                  const bool mesh,
00101                                  const bool poly_mesh) 
00102 {
00103     // general function for writing a mesh
00104   
00105   ErrorCode result = MB_SUCCESS;
00106 
00107     // initialize file
00108 
00109   if (mesh) {
00110     result = local_write_mesh(file_name, output_set, user_dimension, true, false);
00111     if (MB_SUCCESS != result) return result;
00112   }
00113   
00114   if (poly_mesh) {
00115     result = local_write_mesh(file_name, output_set, user_dimension, false, true);
00116     if (MB_SUCCESS != result) return result;
00117   }
00118   
00119   return result;
00120 }
00121 
00122 ErrorCode WriteGMV::write_file( const char* filename,
00123                                   const bool ,
00124                                   const FileOptions& /*opts*/,
00125                                   const EntityHandle* output_sets,
00126                                   const int num_output_sets,
00127                                   const std::vector<std::string>& ,
00128                                   const Tag*,
00129                                   int,
00130                                   int dimension )
00131 {
00132   EntityHandle output_set = 0;
00133   if (output_sets && num_output_sets > 0)
00134   {
00135     if (num_output_sets > 1)
00136       return MB_FAILURE;
00137     output_set = output_sets[0];
00138   }
00139   
00140   if (dimension == 0)
00141   {
00142     mbImpl->get_dimension( dimension );
00143   }
00144   
00145   return write_file( filename, output_set, dimension, true, true );
00146 }
00147   
00148 
00149 ErrorCode WriteGMV::local_write_mesh(const char *file_name,
00150                                        const EntityHandle output_set,
00151                                        const int user_dimension,
00152                                        const bool mesh,
00153                                        const bool poly_mesh)
00154 {
00155   std::ofstream ofile;
00156   ErrorCode result;
00157 
00158   if (mesh) {
00159       // need to insert ".gmv"
00160     std::string tmp_name(file_name);
00161     tmp_name += ".gmv";
00162     ofile.open(tmp_name.c_str());
00163   }
00164   else if (poly_mesh) {
00165       // need to insert ".poly.gmv"
00166     std::string tmp_name(file_name);
00167     tmp_name += ".poly.gmv";
00168     ofile.open(tmp_name.c_str());
00169   }
00170 
00171   ofile << "gmvinput ascii" << std::endl;
00172   
00173     // get elements to be output
00174   Range dum_range, elements, all_verts;
00175   EntityType otype;
00176   if (poly_mesh) {
00177     result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, elements, true);
00178     if (MB_SUCCESS != result) return result;
00179   }
00180   else {
00181     for (otype = CN::TypeDimensionMap[user_dimension].first;
00182          otype <= CN::TypeDimensionMap[user_dimension].second; otype++) {
00183       if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue;
00184       dum_range.clear();
00185       result = mbImpl->get_entities_by_type(output_set, otype, dum_range, true);
00186       if (MB_SUCCESS != result) return result;
00187 
00188       std::copy(dum_range.begin(), dum_range.end(), range_inserter(elements));
00189     }
00190   }
00191   
00192     // gather the vertices in these elements
00193   result = mbImpl->get_adjacencies(elements, 0, false, all_verts, Interface::UNION);
00194   if (MB_SUCCESS != result) return result;
00195   
00196   int num_verts = all_verts.size();
00197   
00198     // allocate coordinate arrays and put pointers to them in a list
00199   double *xcoord = new double[num_verts];
00200   double *ycoord = new double[num_verts];
00201   double *zcoord = new double[num_verts];
00202   std::vector<double*> coord_arrays;
00203   coord_arrays.push_back(xcoord);
00204   coord_arrays.push_back(ycoord);
00205   coord_arrays.push_back(zcoord);
00206   
00207     // fill them in, writing id tags at the same time
00208   result = mWriteIface->get_node_coords(3, num_verts, all_verts, mGlobalIdTag, 1, coord_arrays);
00209   if (MB_SUCCESS != result) return result;
00210 
00211   int i, j;
00212   
00213     //========================================
00214     // WRITE COORDINATE DATA TO FILE HERE
00215 
00216   ofile << "nodev " << num_verts << std::endl;
00217   for (i = 0; i < num_verts; i++) 
00218     ofile << xcoord[i] << " " << ycoord[i] << " " << zcoord[i] << std::endl;
00219   
00220 
00221     //========================================
00222 
00223   delete [] xcoord;
00224   delete [] ycoord;
00225   delete [] zcoord;
00226 
00227     // iterate over types in selected dimension
00228 
00229   std::vector<int> connect;
00230   std::vector<EntityHandle> connecth;
00231 
00232   if (mesh) {
00233     Range sub_range;
00234     
00235     ofile << "cells " << elements.size() << std::endl;
00236   
00237     for (otype = CN::TypeDimensionMap[user_dimension].first;
00238          otype <= CN::TypeDimensionMap[user_dimension].second; otype++) {
00239 
00240       if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue;
00241       
00242         // get the first element of this type in the range, and one past the last
00243       Range::iterator lower =
00244         Range::lower_bound(elements.begin(),
00245                              elements.end(),
00246                              CREATE_HANDLE(otype, MB_START_ID, i));
00247       Range::iterator upper =
00248         Range::lower_bound(elements.begin(),
00249                              elements.end(),
00250                              CREATE_HANDLE(otype+1, MB_START_ID, i));
00251       
00252       if (lower == upper) continue;
00253     
00254         // copy these elements into a subrange
00255       sub_range.clear();
00256       std::copy(lower, upper, range_inserter(sub_range));
00257 
00258         // make sure the connectivity array is big enough
00259       int verts_per = CN::VerticesPerEntity(otype);
00260       if (connect.size() < verts_per*sub_range.size())
00261         connect.reserve(verts_per*sub_range.size());
00262     
00263         // get the connectivity
00264       result = mWriteIface->get_element_connect(sub_range.size(),
00265                                               verts_per,
00266                                               mGlobalIdTag, sub_range,
00267                                               mGlobalIdTag, 1, &connect[0]);
00268       if (MB_SUCCESS != result) return result;
00269 
00270         //========================================
00271         // WRITE CONNECTIVITY DATA TO FILE HERE
00272 
00273       for (i = 0; i < (int) sub_range.size(); i++) {
00274         ofile << gmvTypeNames[otype] << " " << verts_per << std::endl;
00275         for (j = i*verts_per; j < (int) (i+1)*verts_per; j++)
00276           ofile << connect[j] << " ";
00277         ofile << std::endl;
00278       }
00279 
00280         //========================================
00281     }
00282   }
00283   
00284   else if (poly_mesh) {
00285   
00286       // write polygons/hedra, if any
00287     Range polygons, polyhedra;
00288     result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, polygons, true);
00289     if (MB_SUCCESS != result) return result;
00290   
00291     result = mbImpl->get_entities_by_type(output_set, MBPOLYHEDRON, polyhedra, true);
00292     if (MB_SUCCESS != result) return result;
00293 
00294     if (polygons.size() == 0) return result;
00295   
00296       // mark polyhedra with global ids
00297     result = mWriteIface->assign_ids(polyhedra, mGlobalIdTag, 1);
00298     if (MB_SUCCESS != result) return result;
00299 
00300     ofile << "faces " << polygons.size() << " " << polyhedra.size() << std::endl;
00301 
00302     for (Range::iterator rit = polygons.begin(); rit != polygons.end(); rit++) {
00303         // get the vertices
00304       connecth.clear();
00305       result = mbImpl->get_connectivity(&(*rit), 1, connecth, true);
00306       if (MB_SUCCESS != result) return result;
00307 
00308       if (0 == connecth.size()) continue;
00309     
00310         // get the polyhedra, if any
00311       if (user_dimension == 3) {
00312         polyhedra.clear();
00313         result = mbImpl->get_adjacencies(Range(*rit, *rit), 3, false, polyhedra);
00314         if (MB_SUCCESS != result) return result;
00315     
00316           // put them in the connect array
00317         connecth.push_back((polyhedra.size() > 0 ? *polyhedra.begin() : 0));
00318         connecth.push_back((polyhedra.size() > 1 ? *polyhedra.rbegin() : 0));
00319       }
00320     
00321         // replace handles with ids
00322       connect.reserve(connecth.size());
00323 
00324         // pre-set polyhedra ids in case there aren't any
00325       connect[connecth.size()] = 0;
00326       connect[connecth.size()+1] = 0;
00327       result = mbImpl->tag_get_data(mGlobalIdTag, &connecth[0], 
00328                                     connecth.size()-2+polyhedra.size(),
00329                                     &connect[0]);
00330       if (MB_SUCCESS != result) return result;
00331     
00332         // write the data
00333       ofile << connecth.size()-2;
00334     
00335       for (i = 0; i < (int)connecth.size(); i++)
00336         ofile << " " << connect[i];
00337 
00338       ofile << std::endl;
00339     }
00340   }
00341 
00342   ofile << std::endl << "endgmv" << std::endl;
00343   
00344   ofile.close();
00345   
00346   return MB_SUCCESS;
00347 }
00348 
00349 } // namespace moab
00350 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines