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