Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Export CGNS files. More...
#include <ReadCGNS.hpp>
Public Member Functions | |
ErrorCode | load_file (const char *file_name, const EntityHandle *file_set, const FileOptions &opts, const SubsetList *subset_list=0, const Tag *file_id_tag=0) |
Load mesh from a file. | |
ErrorCode | read_tag_values (const char *file_name, const char *tag_name, const FileOptions &opts, std::vector< int > &tag_values_out, const SubsetList *subset_list=0) |
Read tag values from a file. | |
ReadCGNS (Interface *impl=NULL) | |
Constructor. | |
virtual | ~ReadCGNS () |
Destructor. | |
Static Public Member Functions | |
static ReaderIface * | factory (Interface *) |
factory method | |
Private Member Functions | |
ErrorCode | create_elements (char *sectionName, const Tag *file_id_tag, const EntityType &ent_type, const int &verts_per_elem, long §ion_offset, int elems_count, const std::vector< cgsize_t > &elemsConn) |
ErrorCode | create_sets (char *sectionName, const Tag *file_id_tag, EntityType element_type, const Range &elements, const std::vector< int > &set_ids, int set_type) |
ErrorCode | create_geometric_topology () |
ErrorCode | process_options (const FileOptions &opts) |
Process options passed into the reader. | |
Private Attributes | |
const char * | fileName |
short | mesh_dim |
ReadUtilIface * | readMeshIface |
Interface * | mbImpl |
interface instance | |
Tag | globalId |
Tag | boundary |
Range | geomSets |
Export CGNS files.
Definition at line 20 of file ReadCGNS.hpp.
ReadCGNS::ReadCGNS | ( | Interface * | impl = NULL | ) |
Constructor.
Definition at line 34 of file ReadCGNS.cpp.
References mbImpl, moab::Interface::query_interface(), and readMeshIface.
Referenced by factory().
: fileName( NULL ), mesh_dim( 0 ), mbImpl( impl ), globalId( 0 ), boundary( 0 ) { mbImpl->query_interface( readMeshIface ); }
ReadCGNS::~ReadCGNS | ( | ) | [virtual] |
Destructor.
Definition at line 39 of file ReadCGNS.cpp.
References mbImpl, readMeshIface, and moab::Interface::release_interface().
{ if( readMeshIface ) { mbImpl->release_interface( readMeshIface ); readMeshIface = 0; } }
ErrorCode ReadCGNS::create_elements | ( | char * | sectionName, |
const Tag * | file_id_tag, | ||
const EntityType & | ent_type, | ||
const int & | verts_per_elem, | ||
long & | section_offset, | ||
int | elems_count, | ||
const std::vector< cgsize_t > & | elemsConn | ||
) | [private] |
Definition at line 471 of file ReadCGNS.cpp.
References cgsize_t, create_sets(), ErrorCode, fileName, moab::ReadUtilIface::get_element_connect(), MB_CHK_SET_ERR, MB_SUCCESS, readMeshIface, and moab::ReadUtilIface::update_adjacencies().
Referenced by load_file().
{ ErrorCode result; // Create the element sequence; passes back a pointer to the internal storage for connectivity // and the starting entity handle EntityHandle* conn_array; EntityHandle handle = 0; result = readMeshIface->get_element_connect( elems_count, verts_per_elem, ent_type, 1, handle, conn_array );MB_CHK_SET_ERR( result, fileName << ": Trouble reading elements" ); if( sizeof( EntityHandle ) == sizeof( cgsize_t ) ) { memcpy( conn_array, &elemsConn[0], elemsConn.size() * sizeof( EntityHandle ) ); } else { // if CGNS is compiled without 64bit enabled std::vector< EntityHandle > elemsConnTwin( elemsConn.size(), 0 ); for( int i = 0; i < elemsConn.size(); i++ ) { elemsConnTwin[i] = static_cast< EntityHandle >( elemsConn[i] ); } memcpy( conn_array, &elemsConnTwin[0], elemsConnTwin.size() * sizeof( EntityHandle ) ); } // Notify MOAB of the new elements result = readMeshIface->update_adjacencies( handle, elems_count, verts_per_elem, conn_array ); if( MB_SUCCESS != result ) return result; // ////////////////////////////////// // Create sets and tags Range elements( handle, handle + elems_count - 1 ); // Store element IDs std::vector< int > id_list( elems_count ); // Add 1 to offset id to 1-based numbering for( cgsize_t i = 0; i < elems_count; ++i ) id_list[i] = i + 1 + section_offset; section_offset += elems_count; create_sets( sectionName, file_id_tag, ent_type, elements, id_list, 0 ); return MB_SUCCESS; }
ErrorCode moab::ReadCGNS::create_geometric_topology | ( | ) | [private] |
ErrorCode ReadCGNS::create_sets | ( | char * | sectionName, |
const Tag * | file_id_tag, | ||
EntityType | element_type, | ||
const Range & | elements, | ||
const std::vector< int > & | set_ids, | ||
int | set_type | ||
) | [private] |
Definition at line 525 of file ReadCGNS.cpp.
References moab::Interface::add_entities(), moab::Interface::create_meshset(), ErrorCode, fileName, globalId, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, mbImpl, MESHSET_SET, moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().
Referenced by create_elements().
{ ErrorCode result; result = mbImpl->tag_set_data( globalId, elements, &set_ids[0] ); if( MB_SUCCESS != result ) return result; if( file_id_tag ) { result = mbImpl->tag_set_data( *file_id_tag, elements, &set_ids[0] ); if( MB_SUCCESS != result ) return result; } EntityHandle set_handle; Tag tag_handle; const char* setName = sectionName; mbImpl->tag_get_handle( setName, 1, MB_TYPE_INTEGER, tag_handle, MB_TAG_SPARSE | MB_TAG_CREAT ); // Create set result = mbImpl->create_meshset( MESHSET_SET, set_handle );MB_CHK_SET_ERR( result, fileName << ": Trouble creating set" ); //// Add dummy values to current set // std::vector<int> tags(set_ids.size(), 1); // result = mbImpl->tag_set_data(tag_handle, elements, &tags[0]); // if (MB_SUCCESS != result) return result; // Add them to the set result = mbImpl->add_entities( set_handle, elements );MB_CHK_SET_ERR( result, fileName << ": Trouble putting entities in set" ); return MB_SUCCESS; }
ReaderIface * ReadCGNS::factory | ( | Interface * | iface | ) | [static] |
factory method
Definition at line 29 of file ReadCGNS.cpp.
References ReadCGNS().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
ErrorCode ReadCGNS::load_file | ( | const char * | file_name, |
const EntityHandle * | file_set, | ||
const FileOptions & | opts, | ||
const SubsetList * | subset_list = 0 , |
||
const Tag * | file_id_tag = 0 |
||
) | [virtual] |
Load mesh from a file.
Method all readers must provide to import a mesh.
file_name | The file to read. |
file_set | Optional pointer to entity set representing file. If this is not NULL, reader may optionally tag the pointed-to set with format-specific meta-data. |
subset_list | An optional struct pointer specifying the tags identifying entity sets to be read. |
file_id_tag | If specified, reader should store for each entity it reads, a unique integer ID for this tag. |
Implements moab::ReaderIface.
Definition at line 57 of file ReadCGNS.cpp.
References cgsize_t, moab::Range::clear(), create_elements(), ErrorCode, fileName, geomSets, moab::ReadUtilIface::get_node_coords(), globalId, moab::Interface::globalId_tag(), MATERIAL_SET_TAG_NAME, MB_CHK_SET_ERR, MB_FILE_DOES_NOT_EXIST, MB_INDEX_OUT_OF_RANGE, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_START_ID, MB_SUCCESS, MB_UNSUPPORTED_OPERATION, MBEDGE, MBHEX, mbImpl, MBMAXTYPE, MBPRISM, MBPYRAMID, MBQUAD, MBTET, MBTRI, mesh_dim, moab::ReaderIface::IDTag::num_tag_values, process_options(), readMeshIface, size, moab::ReaderIface::SubsetList::tag_list, moab::ReaderIface::SubsetList::tag_list_length, moab::ReaderIface::IDTag::tag_name, moab::Interface::tag_set_data(), and moab::ReaderIface::IDTag::tag_values.
{ int num_material_sets = 0; const int* material_set_list = 0; if( subset_list ) { if( subset_list->tag_list_length > 1 && !strcmp( subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME ) ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "CGNS supports subset read only by material ID" ); } material_set_list = subset_list->tag_list[0].tag_values; num_material_sets = subset_list->tag_list[0].num_tag_values; } ErrorCode result; geomSets.clear(); globalId = mbImpl->globalId_tag(); // Create set for more convenient check for material set ids std::set< int > blocks; for( const int* mat_set_end = material_set_list + num_material_sets; material_set_list != mat_set_end; ++material_set_list ) blocks.insert( *material_set_list ); // Map of ID->handle for nodes std::map< long, EntityHandle > node_id_map; // Save filename to member variable so we don't need to pass as an argument // to called functions fileName = filename; // Process options; see src/FileOptions.hpp for API for FileOptions class, and // doc/metadata_info.doc for a description of various options used by some of the readers in // MOAB result = process_options( opts );MB_CHK_SET_ERR( result, fileName << ": problem reading options" ); // Open file int filePtr = 0; cg_open( filename, CG_MODE_READ, &filePtr ); if( filePtr <= 0 ) { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error" ); } // Read number of verts, elements, sets long num_verts = 0, num_elems = 0, num_sets = 0; int num_bases = 0, num_zones = 0, num_sections = 0; char zoneName[128]; cgsize_t size[3]; mesh_dim = 3; // Default to 3D // Read number of bases; cg_nbases( filePtr, &num_bases ); if( num_bases > 1 ) { MB_SET_ERR( MB_NOT_IMPLEMENTED, fileName << ": support for number of bases > 1 not implemented" ); } for( int indexBase = 1; indexBase <= num_bases; ++indexBase ) { // Get the number of zones/blocks in current base. cg_nzones( filePtr, indexBase, &num_zones ); if( num_zones > 1 ) { MB_SET_ERR( MB_NOT_IMPLEMENTED, fileName << ": support for number of zones > 1 not implemented" ); } for( int indexZone = 1; indexZone <= num_zones; ++indexZone ) { // Get zone name and size. cg_zone_read( filePtr, indexBase, indexZone, zoneName, size ); // Read number of sections/Parts in current zone. cg_nsections( filePtr, indexBase, indexZone, &num_sections ); num_verts = size[0]; num_elems = size[1]; num_sets = num_sections; std::cout << "\nnumber of nodes = " << num_verts; std::cout << "\nnumber of elems = " << num_elems; std::cout << "\nnumber of parts = " << num_sets << std::endl; // ////////////////////////////////// // Read Nodes // Allocate nodes; these are allocated in one shot, get contiguous handles starting with // start_handle, and the reader is passed back double*'s pointing to MOAB's native // storage for vertex coordinates for those verts std::vector< double* > coord_arrays; EntityHandle handle = 0; result = readMeshIface->get_node_coords( 3, num_verts, MB_START_ID, handle, coord_arrays );MB_CHK_SET_ERR( result, fileName << ": Trouble reading vertices" ); // Fill in vertex coordinate arrays cgsize_t beginPos = 1, endPos = num_verts; // Read nodes coordinates. cg_coord_read( filePtr, indexBase, indexZone, "CoordinateX", RealDouble, &beginPos, &endPos, coord_arrays[0] ); cg_coord_read( filePtr, indexBase, indexZone, "CoordinateY", RealDouble, &beginPos, &endPos, coord_arrays[1] ); cg_coord_read( filePtr, indexBase, indexZone, "CoordinateZ", RealDouble, &beginPos, &endPos, coord_arrays[2] ); // CGNS seems to always include the Z component, even if the mesh is 2D. // Check if Z is zero and determine mesh dimension. // Also create the node_id_map data. double sumZcoord = 0.0; double eps = 1.0e-12; for( long i = 0; i < num_verts; ++i, ++handle ) { int index = i + 1; node_id_map.insert( std::pair< long, EntityHandle >( index, handle ) ).second; sumZcoord += *( coord_arrays[2] + i ); } if( std::abs( sumZcoord ) <= eps ) mesh_dim = 2; // Create reverse map from handle to id std::vector< int > ids( num_verts ); std::vector< int >::iterator id_iter = ids.begin(); std::vector< EntityHandle > handles( num_verts ); std::vector< EntityHandle >::iterator h_iter = handles.begin(); for( std::map< long, EntityHandle >::iterator i = node_id_map.begin(); i != node_id_map.end(); ++i, ++id_iter, ++h_iter ) { *id_iter = i->first; *h_iter = i->second; } // Store IDs in tags result = mbImpl->tag_set_data( globalId, &handles[0], num_verts, &ids[0] ); if( MB_SUCCESS != result ) return result; if( file_id_tag ) { result = mbImpl->tag_set_data( *file_id_tag, &handles[0], num_verts, &ids[0] ); if( MB_SUCCESS != result ) return result; } ids.clear(); handles.clear(); // ////////////////////////////////// // Read elements data EntityType ent_type; long section_offset = 0; // Define which mesh parts are volume families. // Mesh parts with volumeID[X] = 0 are boundary parts. std::vector< int > volumeID( num_sections, 0 ); for( int section = 0; section < num_sections; ++section ) { ElementType_t elemsType; int iparent_flag, nbndry; char sectionName[128]; int verts_per_elem; int cgSection = section + 1; cg_section_read( filePtr, indexBase, indexZone, cgSection, sectionName, &elemsType, &beginPos, &endPos, &nbndry, &iparent_flag ); size_t section_size = endPos - beginPos + 1; // Read element description in current section switch( elemsType ) { case BAR_2: ent_type = MBEDGE; verts_per_elem = 2; break; case TRI_3: ent_type = MBTRI; verts_per_elem = 3; if( mesh_dim == 2 ) volumeID[section] = 1; break; case QUAD_4: ent_type = MBQUAD; verts_per_elem = 4; if( mesh_dim == 2 ) volumeID[section] = 1; break; case TETRA_4: ent_type = MBTET; verts_per_elem = 4; if( mesh_dim == 3 ) volumeID[section] = 1; break; case PYRA_5: ent_type = MBPYRAMID; verts_per_elem = 5; if( mesh_dim == 3 ) volumeID[section] = 1; break; case PENTA_6: ent_type = MBPRISM; verts_per_elem = 6; if( mesh_dim == 3 ) volumeID[section] = 1; break; case HEXA_8: ent_type = MBHEX; verts_per_elem = 8; if( mesh_dim == 3 ) volumeID[section] = 1; break; case MIXED: ent_type = MBMAXTYPE; verts_per_elem = 0; break; default: MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type" ); } if( elemsType == TETRA_4 || elemsType == PYRA_5 || elemsType == PENTA_6 || elemsType == HEXA_8 || elemsType == TRI_3 || elemsType == QUAD_4 || ( ( elemsType == BAR_2 ) && mesh_dim == 2 ) ) { // Read connectivity into conn_array directly cgsize_t iparentdata; cgsize_t connDataSize; // Get number of entries on the connectivity list for this section cg_ElementDataSize( filePtr, indexBase, indexZone, cgSection, &connDataSize ); // Need a temporary vector to later cast to conn_array. std::vector< cgsize_t > elemNodes( connDataSize ); cg_elements_read( filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata ); // ////////////////////////////////// // Create elements, sets and tags create_elements( sectionName, file_id_tag, ent_type, verts_per_elem, section_offset, section_size, elemNodes ); } // Homogeneous mesh type else if( elemsType == MIXED ) { // We must first sort all elements connectivities into continuous vectors cgsize_t connDataSize; cgsize_t iparentdata; cg_ElementDataSize( filePtr, indexBase, indexZone, cgSection, &connDataSize ); std::vector< cgsize_t > elemNodes( connDataSize ); cg_elements_read( filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata ); std::vector< cgsize_t > elemsConn_EDGE; std::vector< cgsize_t > elemsConn_TRI, elemsConn_QUAD; std::vector< cgsize_t > elemsConn_TET, elemsConn_PYRA, elemsConn_PRISM, elemsConn_HEX; cgsize_t count_EDGE, count_TRI, count_QUAD; cgsize_t count_TET, count_PYRA, count_PRISM, count_HEX; // First, get elements count for current section count_EDGE = count_TRI = count_QUAD = 0; count_TET = count_PYRA = count_PRISM = count_HEX = 0; int connIndex = 0; for( int i = beginPos; i <= endPos; i++ ) { elemsType = ElementType_t( elemNodes[connIndex] ); // Get current cell node count. cg_npe( elemsType, &verts_per_elem ); switch( elemsType ) { case BAR_2: count_EDGE += 1; break; case TRI_3: count_TRI += 1; break; case QUAD_4: count_QUAD += 1; break; case TETRA_4: count_TET += 1; break; case PYRA_5: count_PYRA += 1; break; case PENTA_6: count_PRISM += 1; break; case HEXA_8: count_HEX += 1; break; default: MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type" ); } connIndex += ( verts_per_elem + 1 ); // Add one to skip next element descriptor } if( count_EDGE > 0 ) elemsConn_EDGE.resize( count_EDGE * 2 ); if( count_TRI > 0 ) elemsConn_TRI.resize( count_TRI * 3 ); if( count_QUAD > 0 ) elemsConn_QUAD.resize( count_QUAD * 4 ); if( count_TET > 0 ) elemsConn_TET.resize( count_TET * 4 ); if( count_PYRA > 0 ) elemsConn_PYRA.resize( count_PYRA * 5 ); if( count_PRISM > 0 ) elemsConn_PRISM.resize( count_PRISM * 6 ); if( count_HEX > 0 ) elemsConn_HEX.resize( count_HEX * 8 ); // Grab mixed section elements connectivity int idx_edge, idx_tri, idx_quad; int idx_tet, idx_pyra, idx_prism, idx_hex; idx_edge = idx_tri = idx_quad = 0; idx_tet = idx_pyra = idx_prism = idx_hex = 0; connIndex = 0; for( int i = beginPos; i <= endPos; i++ ) { elemsType = ElementType_t( elemNodes[connIndex] ); // Get current cell node count. cg_npe( elemsType, &verts_per_elem ); switch( elemsType ) { case BAR_2: for( int j = 0; j < 2; ++j ) elemsConn_EDGE[idx_edge + j] = elemNodes[connIndex + j + 1]; idx_edge += 2; break; case TRI_3: for( int j = 0; j < 3; ++j ) elemsConn_TRI[idx_tri + j] = elemNodes[connIndex + j + 1]; idx_tri += 3; break; case QUAD_4: for( int j = 0; j < 4; ++j ) elemsConn_QUAD[idx_quad + j] = elemNodes[connIndex + j + 1]; idx_quad += 4; break; case TETRA_4: for( int j = 0; j < 4; ++j ) elemsConn_TET[idx_tet + j] = elemNodes[connIndex + j + 1]; idx_tet += 4; break; case PYRA_5: for( int j = 0; j < 5; ++j ) elemsConn_PYRA[idx_pyra + j] = elemNodes[connIndex + j + 1]; idx_pyra += 5; break; case PENTA_6: for( int j = 0; j < 6; ++j ) elemsConn_PRISM[idx_prism + j] = elemNodes[connIndex + j + 1]; idx_prism += 6; break; case HEXA_8: for( int j = 0; j < 8; ++j ) elemsConn_HEX[idx_hex + j] = elemNodes[connIndex + j + 1]; idx_hex += 8; break; default: MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, fileName << ": Trouble determining element type" ); } connIndex += ( verts_per_elem + 1 ); // Add one to skip next element descriptor } // ////////////////////////////////// // Create elements, sets and tags if( count_EDGE > 0 ) create_elements( sectionName, file_id_tag, MBEDGE, 2, section_offset, count_EDGE, elemsConn_EDGE ); if( count_TRI > 0 ) create_elements( sectionName, file_id_tag, MBTRI, 3, section_offset, count_TRI, elemsConn_TRI ); if( count_QUAD > 0 ) create_elements( sectionName, file_id_tag, MBQUAD, 4, section_offset, count_QUAD, elemsConn_QUAD ); if( count_TET > 0 ) create_elements( sectionName, file_id_tag, MBTET, 4, section_offset, count_TET, elemsConn_TET ); if( count_PYRA > 0 ) create_elements( sectionName, file_id_tag, MBPYRAMID, 5, section_offset, count_PYRA, elemsConn_PYRA ); if( count_PRISM > 0 ) create_elements( sectionName, file_id_tag, MBPRISM, 6, section_offset, count_PRISM, elemsConn_PRISM ); if( count_HEX > 0 ) create_elements( sectionName, file_id_tag, MBHEX, 8, section_offset, count_HEX, elemsConn_HEX ); } // Mixed mesh type } // num_sections cg_close( filePtr ); return result; } // indexZone for } // indexBase for return MB_SUCCESS; }
ErrorCode ReadCGNS::process_options | ( | const FileOptions & | opts | ) | [private] |
Process options passed into the reader.
opts | Options passed into this read |
Definition at line 565 of file ReadCGNS.cpp.
References moab::FileOptions::mark_all_seen(), and MB_SUCCESS.
Referenced by load_file().
{ // Mark all options seen, to avoid compile warning on unused variable opts.mark_all_seen(); return MB_SUCCESS; }
ErrorCode ReadCGNS::read_tag_values | ( | const char * | file_name, |
const char * | tag_name, | ||
const FileOptions & | opts, | ||
std::vector< int > & | tag_values_out, | ||
const SubsetList * | subset_list = 0 |
||
) | [virtual] |
Read tag values from a file.
Read the list if all integer tag values from the file for a tag that is a single integer value per entity.
file_name | The file to read. |
tag_name | The tag for which to read values |
tag_values_out | Output: The list of tag values. |
subset_list | An array of tag name and value sets specifying the subset of the file to read. If multiple tags are specified, the sets that match all tags (intersection) should be read. |
subset_list_length | The length of the 'subset_list' array. |
Implements moab::ReaderIface.
Definition at line 48 of file ReadCGNS.cpp.
References MB_NOT_IMPLEMENTED.
{ return MB_NOT_IMPLEMENTED; }
Tag moab::ReadCGNS::boundary [private] |
Definition at line 78 of file ReadCGNS.hpp.
const char* moab::ReadCGNS::fileName [private] |
Definition at line 68 of file ReadCGNS.hpp.
Referenced by create_elements(), create_sets(), and load_file().
Range moab::ReadCGNS::geomSets [private] |
Definition at line 79 of file ReadCGNS.hpp.
Referenced by load_file().
Tag moab::ReadCGNS::globalId [private] |
Definition at line 77 of file ReadCGNS.hpp.
Referenced by create_sets(), and load_file().
Interface* moab::ReadCGNS::mbImpl [private] |
interface instance
Definition at line 75 of file ReadCGNS.hpp.
Referenced by create_sets(), load_file(), ReadCGNS(), and ~ReadCGNS().
short moab::ReadCGNS::mesh_dim [private] |
Definition at line 70 of file ReadCGNS.hpp.
Referenced by load_file().
ReadUtilIface* moab::ReadCGNS::readMeshIface [private] |
Definition at line 72 of file ReadCGNS.hpp.
Referenced by create_elements(), load_file(), ReadCGNS(), and ~ReadCGNS().