moab
moab::ReadCGNS Class Reference

Export CGNS files. More...

#include <ReadCGNS.hpp>

Inheritance diagram for moab::ReadCGNS:
moab::ReaderIface

List of all members.

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 ReaderIfacefactory (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 &section_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
ReadUtilIfacereadMeshIface
InterfacembImpl
 interface instance
Tag globalId
Tag boundary
Range geomSets

Detailed Description

Export CGNS files.

Author:
Carlos Breviglieri, Carlos Junqueira Junior

Definition at line 20 of file ReadCGNS.hpp.


Constructor & Destructor Documentation

ReadCGNS::ReadCGNS ( Interface impl = NULL)

Constructor.

Definition at line 34 of file ReadCGNS.cpp.

ReadCGNS::~ReadCGNS ( ) [virtual]

Destructor.

Definition at line 40 of file ReadCGNS.cpp.


Member Function Documentation

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 501 of file ReadCGNS.cpp.

{

    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);

    if (MB_SUCCESS != result) {
        readMeshIface->report_error("%s: Trouble reading elements\n", fileName);
        return result;
    }

    memcpy(conn_array, &elemsConn[0], elemsConn.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 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 551 of file ReadCGNS.cpp.

{

    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;
    }

    result = MB_SUCCESS;
    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);
    if (MB_SUCCESS != result) {
        readMeshIface->report_error("%s: Trouble creating set.\n", fileName);
        return result;
    }

//    // 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);
    if (MB_SUCCESS != result) {
        readMeshIface->report_error("%s: Trouble putting entities in set.\n", fileName);
        return result;
    }

    return MB_SUCCESS;

}
ReaderIface * ReadCGNS::factory ( Interface iface) [static]

factory method

Definition at line 29 of file ReadCGNS.cpp.

{
    return new ReadCGNS(iface);
}
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.

Parameters:
file_nameThe file to read.
file_setOptional 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_listAn optional struct pointer specifying the tags identifying entity sets to be read.
file_id_tagIf specified, reader should store for each entity it reads, a unique integer ID for this tag.
Author:
Jason Kraftcheck

Implements moab::ReaderIface.

Definition at line 59 of file ReadCGNS.cpp.

{

    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)) {
            readMeshIface->report_error("CGNS supports subset read only by material ID.");
            return MB_UNSUPPORTED_OPERATION;
        }
        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();
    result = mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER,
                                    globalId, MB_TAG_DENSE | MB_TAG_CREAT, 0);
    if (MB_SUCCESS != result)
        return result;

    // Create set for more convienient 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);
    if (MB_SUCCESS != result) {
        readMeshIface->report_error("%s: problem reading options\n", fileName);
        return result;
    }

    // Open file
    int filePtr = 0;

    cg_open(filename, CG_MODE_READ, &filePtr);

    if (filePtr <= 0) {
        readMeshIface->report_error("%s: fopen returned error.\n", fileName);
        return MB_FILE_DOES_NOT_EXIST;
    }

    // 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) {
        readMeshIface->report_error("%s: support for number of bases > 1 not implemented.\n", fileName);
        return MB_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) {
            readMeshIface->report_error("%s: support for number of zones > 1 not implemented.\n", fileName);
            return MB_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);
            if (MB_SUCCESS != result) {
                readMeshIface->report_error("%s: Trouble reading vertices\n", fileName);
                return result;
            }


            // 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:
                    readMeshIface->report_error("%s: Trouble determining element type.\n", fileName);
                    return MB_INDEX_OUT_OF_RANGE;
                    break;
                }

                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:
                            readMeshIface->report_error("%s: Trouble determining element type.\n", fileName);
                            return MB_INDEX_OUT_OF_RANGE;
                            break;
                        }

                        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:
                            readMeshIface->report_error("%s: Trouble determining element type.\n", fileName);
                            return MB_INDEX_OUT_OF_RANGE;
                            break;
                        }

                        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.

Parameters:
optsOptions passed into this read

Definition at line 602 of file ReadCGNS.cpp.

{
    // 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.

Parameters:
file_nameThe file to read.
tag_nameThe tag for which to read values
tag_values_outOutput: The list of tag values.
subset_listAn 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_lengthThe length of the 'subset_list' array.

Implements moab::ReaderIface.

Definition at line 49 of file ReadCGNS.cpp.

{
    return MB_NOT_IMPLEMENTED;
}

Member Data Documentation

Definition at line 80 of file ReadCGNS.hpp.

const char* moab::ReadCGNS::fileName [private]

Definition at line 70 of file ReadCGNS.hpp.

Definition at line 81 of file ReadCGNS.hpp.

Definition at line 79 of file ReadCGNS.hpp.

interface instance

Definition at line 77 of file ReadCGNS.hpp.

short moab::ReadCGNS::mesh_dim [private]

Definition at line 72 of file ReadCGNS.hpp.

Definition at line 74 of file ReadCGNS.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines