![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00033 #include
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