MOAB: Mesh Oriented datABase  (version 5.3.1)
WriteTemplate.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 "WriteTemplate.hpp"
00025 
00026 #include <utility>
00027 #include <algorithm>
00028 #include <ctime>
00029 #include <string>
00030 #include <vector>
00031 #include <cstdio>
00032 #include <cstring>
00033 #include <iostream>
00034 
00035 #include "moab/Interface.hpp"
00036 #include "moab/Range.hpp"
00037 #include "moab/CN.hpp"
00038 #include <cassert>
00039 #include "Internals.hpp"
00040 #include "ExoIIUtil.hpp"
00041 #include "MBTagConventions.hpp"
00042 #include "moab/WriteUtilIface.hpp"
00043 
00044 namespace moab
00045 {
00046 
00047 #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id )
00048 
00049 WriterIface* WriteTemplate::factory( Interface* iface )
00050 {
00051     return new WriteTemplate( iface );
00052 }
00053 
00054 WriteTemplate::WriteTemplate( Interface* impl ) : mbImpl( impl )
00055 {
00056     assert( impl != NULL );
00057 
00058     impl->query_interface( mWriteIface );
00059 
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     impl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
00075 }
00076 
00077 WriteTemplate::~WriteTemplate()
00078 {
00079     mbImpl->release_interface( mWriteIface );
00080     mbImpl->tag_delete( mEntityMark );
00081 }
00082 
00083 void WriteTemplate::reset_matset( std::vector< WriteTemplate::MaterialSetData >& matset_info )
00084 {
00085     std::vector< WriteTemplate::MaterialSetData >::iterator iter;
00086 
00087     for( iter = matset_info.begin(); iter != matset_info.end(); ++iter )
00088         delete( *iter ).elements;
00089 }
00090 
00091 ErrorCode WriteTemplate::write_file( const char* file_name,
00092                                      const bool /* overwrite (commented out to remove warning) */,
00093                                      const FileOptions& /*opts*/, const EntityHandle* ent_handles, const int num_sets,
00094                                      const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */,
00095                                      int /* num_tags */, int /* export_dimension */ )
00096 {
00097     assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag );
00098 
00099     // Check the file name
00100     if( NULL == strstr( file_name, ".template" ) ) return MB_FAILURE;
00101 
00102     std::vector< EntityHandle > matsets, dirsets, neusets;
00103 
00104     fileName = file_name;
00105 
00106     // Separate into material sets, dirichlet sets, neumann sets
00107 
00108     if( num_sets == 0 )
00109     {
00110         // Default to all defined sets
00111         Range this_range;
00112         mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range );
00113         std::copy( this_range.begin(), this_range.end(), std::back_inserter( matsets ) );
00114         this_range.clear();
00115         mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range );
00116         std::copy( this_range.begin(), this_range.end(), std::back_inserter( dirsets ) );
00117         this_range.clear();
00118         mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range );
00119         std::copy( this_range.begin(), this_range.end(), std::back_inserter( neusets ) );
00120     }
00121     else
00122     {
00123         int dummy;
00124         for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter )
00125         {
00126             if( MB_SUCCESS == mbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) )
00127                 matsets.push_back( *iter );
00128             else if( MB_SUCCESS == mbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) )
00129                 dirsets.push_back( *iter );
00130             else if( MB_SUCCESS == mbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) )
00131                 neusets.push_back( *iter );
00132         }
00133     }
00134 
00135     // If there is nothing to write just return.
00136     if( matsets.empty() && dirsets.empty() && neusets.empty() ) return MB_FILE_WRITE_ERROR;
00137 
00138     std::vector< WriteTemplate::MaterialSetData > matset_info;
00139     std::vector< WriteTemplate::DirichletSetData > dirset_info;
00140     std::vector< WriteTemplate::NeumannSetData > neuset_info;
00141 
00142     MeshInfo mesh_info;
00143 
00144     matset_info.clear();
00145     if( gather_mesh_information( mesh_info, matset_info, neuset_info, dirset_info, matsets, neusets, dirsets ) !=
00146         MB_SUCCESS )
00147     {
00148         reset_matset( matset_info );
00149         return MB_FAILURE;
00150     }
00151 
00152     // Try to open the file after gather mesh info succeeds
00153     if( /* Test for file open failure */ false )
00154     {
00155         reset_matset( matset_info );
00156         return MB_FAILURE;
00157     }
00158 
00159     if( initialize_file( mesh_info ) != MB_SUCCESS )
00160     {
00161         reset_matset( matset_info );
00162         return MB_FAILURE;
00163     }
00164 
00165     if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS )
00166     {
00167         reset_matset( matset_info );
00168         return MB_FAILURE;
00169     }
00170 
00171     if( write_matsets( mesh_info, matset_info, neuset_info ) )
00172     {
00173         reset_matset( matset_info );
00174         return MB_FAILURE;
00175     }
00176 
00177     return MB_SUCCESS;
00178 }
00179 
00180 ErrorCode WriteTemplate::gather_mesh_information( MeshInfo& mesh_info,
00181                                                   std::vector< WriteTemplate::MaterialSetData >& matset_info,
00182                                                   std::vector< WriteTemplate::NeumannSetData >& neuset_info,
00183                                                   std::vector< WriteTemplate::DirichletSetData >& dirset_info,
00184                                                   std::vector< EntityHandle >& matsets,
00185                                                   std::vector< EntityHandle >& neusets,
00186                                                   std::vector< EntityHandle >& dirsets )
00187 {
00188     std::vector< EntityHandle >::iterator vector_iter, end_vector_iter;
00189 
00190     mesh_info.num_nodes    = 0;
00191     mesh_info.num_elements = 0;
00192     mesh_info.num_matsets  = 0;
00193 
00194     int id = 0;
00195 
00196     vector_iter     = matsets.begin();
00197     end_vector_iter = matsets.end();
00198 
00199     mesh_info.num_matsets = matsets.size();
00200 
00201     std::vector< EntityHandle > parent_meshsets;
00202 
00203     // Clean out the bits for the element mark
00204     mbImpl->tag_delete( mEntityMark );
00205     mbImpl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT );
00206 
00207     int highest_dimension_of_element_matsets = 0;
00208 
00209     for( vector_iter = matsets.begin(); vector_iter != matsets.end(); ++vector_iter )
00210     {
00211         WriteTemplate::MaterialSetData matset_data;
00212         matset_data.elements = new Range;
00213 
00214         // For the purpose of qa records, get the parents of these matsets
00215         if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE;
00216 
00217         // Get all Entity Handles in the mesh set
00218         Range dummy_range;
00219         mbImpl->get_entities_by_handle( *vector_iter, dummy_range, true );
00220 
00221         // Find the dimension of the last entity in this range
00222         Range::iterator entity_iter = dummy_range.end();
00223         --entity_iter;
00224         int this_dim = CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) );
00225         entity_iter  = dummy_range.begin();
00226         while( entity_iter != dummy_range.end() && CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) ) != this_dim )
00227             ++entity_iter;
00228 
00229         if( entity_iter != dummy_range.end() )
00230             std::copy( entity_iter, dummy_range.end(), range_inserter( *( matset_data.elements ) ) );
00231 
00232         assert( matset_data.elements->begin() == matset_data.elements->end() ||
00233                 CN::Dimension( TYPE_FROM_HANDLE( *( matset_data.elements->begin() ) ) ) == this_dim );
00234 
00235         // Get the matset's id
00236         if( mbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
00237         {
00238             MB_SET_ERR( MB_FAILURE, "Couldn't get matset id from a tag for an element matset" );
00239         }
00240 
00241         matset_data.id                = id;
00242         matset_data.number_attributes = 0;
00243 
00244         // Iterate through all the elements in the meshset
00245         Range::iterator elem_range_iter, end_elem_range_iter;
00246         elem_range_iter     = matset_data.elements->begin();
00247         end_elem_range_iter = matset_data.elements->end();
00248 
00249         // Get the entity type for this matset, verifying that it's the same for all elements
00250         // THIS ASSUMES HANDLES SORT BY TYPE!!!
00251         EntityType entity_type = TYPE_FROM_HANDLE( *elem_range_iter );
00252         --end_elem_range_iter;
00253         if( entity_type != TYPE_FROM_HANDLE( *( end_elem_range_iter++ ) ) )
00254         {
00255             MB_SET_ERR( MB_FAILURE, "Entities in matset " << id << " not of common type" );
00256         }
00257 
00258         int dimension = CN::Dimension( entity_type );
00259 
00260         if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension;
00261 
00262         matset_data.moab_type = mbImpl->type_from_handle( *( matset_data.elements->begin() ) );
00263         if( MBMAXTYPE == matset_data.moab_type ) return MB_FAILURE;
00264 
00265         std::vector< EntityHandle > tmp_conn;
00266         mbImpl->get_connectivity( &( *( matset_data.elements->begin() ) ), 1, tmp_conn );
00267         matset_data.element_type =
00268             ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension );
00269 
00270         if( matset_data.element_type == EXOII_MAX_ELEM_TYPE )
00271         {
00272             MB_SET_ERR( MB_FAILURE, "Element type in matset " << id << " didn't get set correctly" );
00273         }
00274 
00275         matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type];
00276 
00277         // Number of nodes for this matset
00278         matset_data.number_elements = matset_data.elements->size();
00279 
00280         // Total number of elements
00281         mesh_info.num_elements += matset_data.number_elements;
00282 
00283         // Get the nodes for the elements
00284         mWriteIface->gather_nodes_from_elements( *matset_data.elements, mEntityMark, mesh_info.nodes );
00285 
00286         if( !neusets.empty() )
00287         {
00288             // If there are neusets, keep track of which elements are being written out
00289             for( Range::iterator iter = matset_data.elements->begin(); iter != matset_data.elements->end(); ++iter )
00290             {
00291                 unsigned char bit = 0x1;
00292                 mbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit );
00293             }
00294         }
00295 
00296         matset_info.push_back( matset_data );
00297     }
00298 
00299     // If user hasn't entered dimension, we figure it out
00300     if( mesh_info.num_dim == 0 )
00301     {
00302         // Never want 1 or zero dimensions
00303         if( highest_dimension_of_element_matsets < 2 )
00304             mesh_info.num_dim = 3;
00305         else
00306             mesh_info.num_dim = highest_dimension_of_element_matsets;
00307     }
00308 
00309     Range::iterator range_iter, end_range_iter;
00310     range_iter     = mesh_info.nodes.begin();
00311     end_range_iter = mesh_info.nodes.end();
00312 
00313     mesh_info.num_nodes = mesh_info.nodes.size();
00314 
00315     //------dirsets--------
00316 
00317     vector_iter     = dirsets.begin();
00318     end_vector_iter = dirsets.end();
00319 
00320     for( ; vector_iter != end_vector_iter; ++vector_iter )
00321     {
00322         WriteTemplate::DirichletSetData dirset_data;
00323         dirset_data.id           = 0;
00324         dirset_data.number_nodes = 0;
00325 
00326         // Get the dirset's id
00327         if( mbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS )
00328         {
00329             MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for dirset " << id );
00330         }
00331 
00332         dirset_data.id = id;
00333 
00334         std::vector< EntityHandle > node_vector;
00335         // Get the nodes of the dirset that are in mesh_info.nodes
00336         if( mbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS )
00337         {
00338             MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in dirset " << id );
00339         }
00340 
00341         std::vector< EntityHandle >::iterator iter, end_iter;
00342         iter     = node_vector.begin();
00343         end_iter = node_vector.end();
00344 
00345         int j                     = 0;
00346         unsigned char node_marked = 0;
00347         ErrorCode result;
00348         for( ; iter != end_iter; ++iter )
00349         {
00350             if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue;
00351             result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
00352 
00353             if( 0x1 == node_marked ) dirset_data.nodes.push_back( *iter );
00354             j++;
00355         }
00356 
00357         dirset_data.number_nodes = dirset_data.nodes.size();
00358         dirset_info.push_back( dirset_data );
00359     }
00360 
00361     //------neusets--------
00362     vector_iter     = neusets.begin();
00363     end_vector_iter = neusets.end();
00364 
00365     for( ; vector_iter != end_vector_iter; ++vector_iter )
00366     {
00367         WriteTemplate::NeumannSetData neuset_data;
00368 
00369         // Get the neuset's id
00370         if( mbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE;
00371 
00372         neuset_data.id              = id;
00373         neuset_data.mesh_set_handle = *vector_iter;
00374 
00375         // Get the sides in two lists, one forward the other reverse; starts with forward sense
00376         // by convention
00377         Range forward_elems, reverse_elems;
00378         if( get_neuset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE;
00379 
00380         ErrorCode result = get_valid_sides( forward_elems, 1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
00381         result = get_valid_sides( reverse_elems, -1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" );
00382 
00383         neuset_data.number_elements = neuset_data.elements.size();
00384         neuset_info.push_back( neuset_data );
00385     }
00386 
00387     return MB_SUCCESS;
00388 }
00389 
00390 ErrorCode WriteTemplate::get_valid_sides( Range& elems, const int sense, WriteTemplate::NeumannSetData& neuset_data )
00391 {
00392     // This is where we see if underlying element of side set element is included in output
00393 
00394     unsigned char element_marked = 0;
00395     ErrorCode result;
00396     for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter )
00397     {
00398         // Should insert here if "side" is a quad/tri on a quad/tri mesh
00399         result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
00400 
00401         if( 0x1 == element_marked )
00402         {
00403             neuset_data.elements.push_back( *iter );
00404 
00405             // TJT TODO: the sense should really be # edges + 1or2
00406             neuset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) );
00407         }
00408         else
00409         {  // Then "side" is probably a quad/tri on a hex/tet mesh
00410             std::vector< EntityHandle > parents;
00411             int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) );
00412 
00413             // Get the adjacent parent element of "side"
00414             if( mbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS )
00415             {
00416                 MB_SET_ERR( MB_FAILURE, "Couldn't get adjacencies for neuset" );
00417             }
00418 
00419             if( !parents.empty() )
00420             {
00421                 // Make sure the adjacent parent element will be output
00422                 for( unsigned int k = 0; k < parents.size(); k++ )
00423                 {
00424                     result = mbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" );
00425 
00426                     int side_no, this_sense, this_offset;
00427                     if( 0x1 == element_marked &&
00428                         mbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS &&
00429                         this_sense == sense )
00430                     {
00431                         neuset_data.elements.push_back( parents[k] );
00432                         neuset_data.side_numbers.push_back( side_no + 1 );
00433                         break;
00434                     }
00435                 }
00436             }
00437             else
00438             {
00439                 MB_SET_ERR( MB_FAILURE, "No parent element exists for element in neuset " << neuset_data.id );
00440             }
00441         }
00442     }
00443 
00444     return MB_SUCCESS;
00445 }
00446 
00447 ErrorCode WriteTemplate::write_nodes( const int num_nodes, const Range& nodes, const int dimension )
00448 {
00449     // See if should transform coordinates
00450     ErrorCode result;
00451     Tag trans_tag;
00452     result                = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag );
00453     bool transform_needed = true;
00454     if( result == MB_TAG_NOT_FOUND ) transform_needed = false;
00455 
00456     int num_coords_to_fill = transform_needed ? 3 : dimension;
00457 
00458     std::vector< double* > coord_arrays( 3 );
00459     coord_arrays[0] = new double[num_nodes];
00460     coord_arrays[1] = new double[num_nodes];
00461     coord_arrays[2] = NULL;
00462 
00463     if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes];
00464 
00465     result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 0, coord_arrays );
00466     if( result != MB_SUCCESS )
00467     {
00468         delete[] coord_arrays[0];
00469         delete[] coord_arrays[1];
00470         if( coord_arrays[2] ) delete[] coord_arrays[2];
00471         return result;
00472     }
00473 
00474     if( transform_needed )
00475     {
00476         double trans_matrix[16];
00477         const EntityHandle mesh = 0;
00478         result                  = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" );
00479 
00480         for( int i = 0; i < num_nodes; i++ )
00481         {
00482             double vec1[3];
00483             double vec2[3];
00484 
00485             vec2[0] = coord_arrays[0][i];
00486             vec2[1] = coord_arrays[1][i];
00487             vec2[2] = coord_arrays[2][i];
00488 
00489             for( int row = 0; row < 3; row++ )
00490             {
00491                 vec1[row] = 0.0;
00492                 for( int col = 0; col < 3; col++ )
00493                     vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] );
00494             }
00495 
00496             coord_arrays[0][i] = vec1[0];
00497             coord_arrays[1][i] = vec1[1];
00498             coord_arrays[2][i] = vec1[2];
00499         }
00500     }
00501 
00502     // Write the nodes
00503 
00504     /* Template - write nodes to file here in some way */
00505 
00506     // Clean up
00507     delete[] coord_arrays[0];
00508     delete[] coord_arrays[1];
00509     if( coord_arrays[2] ) delete[] coord_arrays[2];
00510 
00511     return MB_SUCCESS;
00512 }
00513 
00514 ErrorCode WriteTemplate::write_matsets(
00515     MeshInfo& /* mesh_info (commented out to remove warning) */,
00516     std::vector< WriteTemplate::MaterialSetData >& matset_data,
00517     std::vector< WriteTemplate::NeumannSetData >& /* neuset_data (commented out to remove warning) */ )
00518 {
00519     unsigned int i;
00520     std::vector< int > connect;
00521     const EntityHandle* connecth;
00522     int num_connecth;
00523     ErrorCode result;
00524 
00525     // Don't usually have anywhere near 31 nodes per element
00526     connect.reserve( 31 );
00527     Range::iterator rit;
00528 
00529     WriteTemplate::MaterialSetData matset;
00530     for( i = 0; i < matset_data.size(); i++ )
00531     {
00532         matset = matset_data[i];
00533 
00534         for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit )
00535         {
00536             // Get the connectivity of this element
00537             result = mbImpl->get_connectivity( *rit, connecth, num_connecth );
00538             if( MB_SUCCESS != result ) return result;
00539 
00540             // Get the vertex ids
00541             result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[0] );
00542             if( MB_SUCCESS != result ) return result;
00543 
00544             // Write the data
00545             /* Template - write element connectivity here */
00546 
00547             if( /* Template - check for error condition! */ false ) return MB_FAILURE;
00548         }
00549     }
00550 
00551     return MB_SUCCESS;
00552 }
00553 
00554 ErrorCode WriteTemplate::initialize_file( MeshInfo& mesh_info )
00555 {
00556     // Perform the initializations
00557 
00558     int coord_size, ncoords;
00559 
00560     coord_size = mesh_info.num_dim;
00561     std::cout << "Coord_size = " << coord_size << std::endl;
00562     /* Template - write coord size */
00563 
00564     ncoords = mesh_info.num_nodes;
00565     std::cout << "ncoords = " << ncoords << std::endl;
00566     /* Template - write num nodes*/
00567 
00568     /* Template - write information on the element types & numbers (depends
00569        on material and other sets) */
00570 
00571     /* Node coordinate arrays: */
00572     /* Template - initialize variable to hold coordinate arrays */
00573 
00574     return MB_SUCCESS;
00575 }
00576 
00577 ErrorCode WriteTemplate::open_file( const char* filename )
00578 {
00579     // Not a valid filename
00580     if( strlen( (const char*)filename ) == 0 ) { MB_SET_ERR( MB_FAILURE, "Output filename not specified" ); }
00581 
00582     /* Template - open file & store somewhere */
00583 
00584     // File couldn't be opened
00585     if( /* Template - check for file open error here! */ false )
00586     {
00587         MB_SET_ERR( MB_FAILURE, "Cannot open " << filename );
00588     }
00589 
00590     return MB_SUCCESS;
00591 }
00592 
00593 ErrorCode WriteTemplate::get_neuset_elems( EntityHandle neuset, int current_sense, Range& forward_elems,
00594                                            Range& reverse_elems )
00595 {
00596     Range neuset_elems, neuset_meshsets;
00597 
00598     // Get the sense tag; don't need to check return, might be an error if the tag
00599     // hasn't been created yet
00600     Tag sense_tag = 0;
00601     mbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag );
00602 
00603     // Get the entities in this set
00604     ErrorCode result = mbImpl->get_entities_by_handle( neuset, neuset_elems, true );
00605     if( MB_FAILURE == result ) return result;
00606 
00607     // Now remove the meshsets into the neuset_meshsets; first find the first meshset,
00608     Range::iterator range_iter = neuset_elems.begin();
00609     while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != neuset_elems.end() )
00610         ++range_iter;
00611 
00612     // Then, if there are some, copy them into neuset_meshsets and erase from neuset_elems
00613     if( range_iter != neuset_elems.end() )
00614     {
00615         std::copy( range_iter, neuset_elems.end(), range_inserter( neuset_meshsets ) );
00616         neuset_elems.erase( range_iter, neuset_elems.end() );
00617     }
00618 
00619     // OK, for the elements, check the sense of this set and copy into the right range
00620     // (if the sense is 0, copy into both ranges)
00621 
00622     // Need to step forward on list until we reach the right dimension
00623     Range::iterator dum_it = neuset_elems.end();
00624     --dum_it;
00625     int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) );
00626     dum_it         = neuset_elems.begin();
00627     while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != neuset_elems.end() )
00628         ++dum_it;
00629 
00630     if( current_sense == 1 || current_sense == 0 )
00631         std::copy( dum_it, neuset_elems.end(), range_inserter( forward_elems ) );
00632     if( current_sense == -1 || current_sense == 0 )
00633         std::copy( dum_it, neuset_elems.end(), range_inserter( reverse_elems ) );
00634 
00635     // Now loop over the contained meshsets, getting the sense of those and calling this
00636     // function recursively
00637     for( range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); ++range_iter )
00638     {
00639         // First get the sense; if it's not there, by convention it's forward
00640         int this_sense;
00641         if( 0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) )
00642             this_sense = 1;
00643 
00644         // Now get all the entities on this meshset, with the proper (possibly reversed) sense
00645         get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems );
00646     }
00647 
00648     return result;
00649 }
00650 
00651 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines