Sierra Toolkit Version of the Day
Sierra Toolkit IO

Namespaces

namespace  stk_example_io

Functions

bool stk::io::include_entity (Ioss::GroupingEntity *entity)
template<typename T >
void stk::io::default_part_processing (const std::vector< T * > &entities, stk::mesh::fem::FEMMetaData &fem_meta)
template<typename T >
void stk::io::default_part_processing (const std::vector< T * > &entities, stk::mesh::MetaData &meta, stk::mesh::EntityRank)
void stk::io::define_output_db (Ioss::Region &io_region, const mesh::BulkData &bulk_data, const Ioss::Region *input_region)
void stk::io::write_output_db (Ioss::Region &io_region, const stk::mesh::BulkData &bulk)
bool stk::io::is_valid_part_field (const stk::mesh::FieldBase *field, stk::mesh::EntityRank part_type, stk::mesh::Part &part, stk::mesh::Part &universal, Ioss::Field::RoleType filter_role, bool add_all)
void stk::io::ioss_add_fields (stk::mesh::Part &part, stk::mesh::EntityRank part_type, Ioss::GroupingEntity *entity, const Ioss::Field::RoleType filter_role, bool add_all)
void stk::io::define_io_fields (Ioss::GroupingEntity *entity, Ioss::Field::RoleType role, stk::mesh::Part &part, stk::mesh::EntityRank part_type)
const CellTopologyData * stk::io::map_topology_ioss_to_cell (const Ioss::ElementTopology *topology)
std::string stk::io::map_topology_cell_to_ioss (const CellTopologyData *cell_top, int spatial_dimension)
void stk::io::get_entity_list (Ioss::GroupingEntity *io_entity, stk::mesh::EntityRank part_type, const stk::mesh::BulkData &bulk, std::vector< stk::mesh::Entity * > &entities)
void stk::io::field_data_from_ioss (const stk::mesh::FieldBase *field, std::vector< stk::mesh::Entity * > &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name)
void stk::io::field_data_to_ioss (const stk::mesh::FieldBase *field, std::vector< stk::mesh::Entity * > &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name, Ioss::Field::RoleType filter_role)
const stk::mesh::Field< double,
stk::mesh::ElementNode > * 
stk::io::get_distribution_factor_field (const stk::mesh::Part &p)
void stk::io::set_distribution_factor_field (stk::mesh::Part &p, const stk::mesh::Field< double, stk::mesh::ElementNode > &df_field)
const Ioss::Field::RoleType * stk::io::get_field_role (const stk::mesh::FieldBase &f)
void stk::io::set_field_role (stk::mesh::FieldBase &f, const Ioss::Field::RoleType &role)
bool stk::io::is_part_io_part (stk::mesh::Part &part)
void stk::io::put_io_part_attribute (mesh::Part &part, Ioss::GroupingEntity *entity)
const Ioss::GroupingEntity * stk::io::get_associated_ioss_entity (const mesh::Part &part)
void stk::io::internal_part_processing (Ioss::GroupingEntity *entity, stk::mesh::fem::FEMMetaData &meta)
void stk::io::internal_part_processing (Ioss::EntityBlock *entity, stk::mesh::fem::FEMMetaData &meta)
void stk::io::internal_part_processing (Ioss::GroupingEntity *entity, stk::mesh::MetaData &meta)
void stk::io::internal_part_processing (Ioss::EntityBlock *entity, stk::mesh::MetaData &meta)
bool stk::io::invalid_rank (stk::mesh::EntityRank rank)
stk::mesh::EntityRank stk::io::part_primary_entity_rank (const stk::mesh::Part &part)
stk::mesh::EntityRank stk::io::element_rank (const stk::mesh::MetaData &meta)
stk::mesh::EntityRank stk::io::side_rank (const stk::mesh::MetaData &meta)
stk::mesh::EntityRank stk::io::face_rank (const stk::mesh::MetaData &meta)
stk::mesh::EntityRank stk::io::edge_rank (const stk::mesh::MetaData &meta)
stk::mesh::EntityRank stk::io::node_rank (const stk::mesh::MetaData &meta)
void stk::io::set_cell_topology (stk::mesh::Part &part, const CellTopologyData *const cell_topology)
const CellTopologyData * stk::io::get_cell_topology (const stk::mesh::Part &part)
void stk::io::initialize_spatial_dimension (stk::mesh::fem::FEMMetaData &fem_meta, size_t spatial_dimension, const std::vector< std::string > &entity_rank_names)
void stk::io::initialize_spatial_dimension (stk::mesh::MetaData &meta, size_t spatial_dimension, const std::vector< std::string > &entity_rank_names)
void stk::io::get_io_field_type (const stk::mesh::FieldBase *field, const stk::mesh::FieldRestriction &res, std::pair< std::string, Ioss::Field::BasicType > *result)
int main (int argc, char **argv)

Detailed Description

IO Example Code

The code samples below should closely match the code in the example file stk_io/use_cases/io_example.cpp which is compilable and executable. It can be used to experiment with the stk::io and Ioss functionality. If there is any discrepancy between the documentation below and the code found in io_example.cpp; trust the actual code.

Include Files

The following include files are required for this example.

 #include <stk_util/parallel/Parallel.hpp>
 #include <init/Ionit_Initializer.h>
 #include <Ioss_SubSystem.h>
 
 #include <stk_mesh/base/Field.hpp>
 #include <stk_mesh/base/FieldData.hpp>
 #include <stk_mesh/base/MetaData.hpp>
 #include <stk_mesh/base/BulkData.hpp>
 #include <stk_mesh/fem/TopologyHelpers.hpp>
 #include <stk_mesh/fem/TopologyDimensions.hpp>
 
 #include <stk_io/IossBridge.hpp>

Main IO Control

The io_example function provides all mesh input and results output functionality for this example application. It would most likely be split into multiple functions in a real application. The function takes as arguments an MPI communicator; the name of the mesh file to read from and the name of the results database to write to.

  void io_example( stk::ParallelMachine comm,
                   const std::string& in_filename,
                   const std::string& out_filename)

Initialization

The IO system must be initialized via a call to Ioss::Init::Initializer. This sets up which database types are supported and performs other behind the scenes initialization duties.

    Ioss::Init::Initializer init_db;

Open Mesh Database

The input mesh file must be associated with an Ioss::DatabaseIO object. The IO system must be told the type of the database to be opened; in this example, the type is "exodusII". If the file does not exist or could not be opened, the Ioss::IOFactory will return NULL; if the file does exist and can be opened, but has other problems, then the dbi->ok() function will return false.

Once the datbase has been opened, it is then associated with an Ioss::Region which is the main interface to the mesh description stored in the mesh database.

    std::string dbtype("exodusII");
    Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(dbtype, in_filename, Ioss::READ_MODEL,
                                                    (MPI_Comm)comm);
    if (dbi == NULL || !dbi->ok()) {
      std::cerr  << "ERROR: Could not open database '" << in_filename
                 << "' of type '" << dbtype << "'\n";
      std::exit(EXIT_FAILURE);
    }

    // NOTE: 'in_region' owns 'dbi' pointer at this time...
    Ioss::Region in_region(dbi, "input_model");

Optional Subsetting

The stk::io functions provide a basic subsetting capability. If an Ioss entity (Ioss::ElementBlock, Ioss::NodeSet, Ioss::FaceSet, Ioss::EdgeSet, ...) has the "omitted" property defined and the value of the property is "1", then the associated entity will be omitted from the stk::mesh model. At any time prior to defining the stk::mesh::MetaData, the application can set the property on any entities that should be omitted from the model.

The following code example shows how this subsetting capability works by omitting the element blocks with names "cblock", "eblock", "i1", and "i2". These are element blocks in a file that is used in one of the stk::io use cases.

    // Example command line in current code corresponding to behavior below:
    std::cout << "\nWhen processing file multi-block.g for use case 2, the blocks below will be omitted:\n";
    std::cout << "\tOMIT BLOCK Cblock Eblock I1 I2\n\n";
    Ioss::ElementBlock *eb = in_region.get_element_block("cblock");
    if (eb != NULL)
      eb->property_add(Ioss::Property(std::string("omitted"), 1));

    eb = in_region.get_element_block("eblock");
    if (eb != NULL)
      eb->property_add(Ioss::Property(std::string("omitted"), 1));

    eb = in_region.get_element_block("i1"); 
    if (eb != NULL)
      eb->property_add(Ioss::Property(std::string("omitted"), 1));

    eb = in_region.get_element_block("i2");
    if (eb != NULL)
      eb->property_add(Ioss::Property(std::string("omitted"), 1));

Define MetaData

The following block of code shows how the Ioss metadata is queried and used to define the stk::mesh::MetaData for the analysis model. Each of the process_* functions is described in more detail later on.

    stk::mesh::MetaData meta_data;
    process_elementblocks(in_region, meta_data);
    process_nodeblocks(in_region,    meta_data);
    process_facesets(in_region,      meta_data);
    process_edgesets(in_region,      meta_data);
    process_nodesets(in_region,      meta_data);

Define Other Information

At this point, the application would define other stk::mesh::Field's that exist on the mesh parts or any other data that needs to be set before the meta data is comitted. Once this is done, the meta data can be commited.

    meta_data.commit();

Define Bulk Data

The following block of code defines a stk::mesh::BulkData object and populates it with the bulk data from the mesh database. Each of the process_* function is described in more detail later on. Following this, the analysis mesh is defined and ready for use.

    stk::mesh::BulkData bulk_data(meta_data, comm);
    process_elementblocks(in_region, bulk_data);
    process_nodeblocks(in_region,    bulk_data);
    process_facesets(in_region,      bulk_data);
    process_edgesets(in_region,      bulk_data);
    process_nodesets(in_region,      bulk_data);

Output

Once the analysis mesh is defined, the application will typically want to define one or more output databases; for example, results, heartbeat, history, and/or restart. In the example below, a results database is defined and associated with an Ioss::Region. The define_output_db() function extracts the metadata from the stk::mesh MetaData and BulkData so that the output region corresponds as much as possible to the input region. The "in_region" argument to the function is optional and if present will synchronize names and ids in the input mesh with the corresponding entities in the output mesh.

Once the output database metadata is defined, the write_output_db() function is called to output the initial data to the file corresponding to this database. Following this call, the file should contain all of the non-transient data corresponding to the analysis mesh.

    Ioss::DatabaseIO *dbo = Ioss::IOFactory::create(dbtype, out_filename,
                                                    Ioss::WRITE_RESULTS,
                                                    (MPI_Comm)comm);
    if (dbo == NULL || !dbo->ok()) {
      std::cerr << "ERROR: Could not open results database '" << out_filename
                << "' of type '" << dbtype << "'\n";
      std::exit(EXIT_FAILURE);
    }

    // NOTE: 'out_region' owns 'dbo' pointer at this time...
    Ioss::Region out_region(dbo, "results_output");
      
    stk::io::define_output_db(out_region, bulk_data, &in_region);
    stk::io::write_output_db(out_region,  bulk_data);

Define Transient Output Fields

At this time, the application would define what stk::mesh::Field fields should be output to the results database and what they would be named.

In this example, all fields existing on the input mesh database are defined on the parts in the stk::mesh.

The real app would also only register a subset of the stk::mesh fields as output fields and would probably have a mapping from the internally used name to some name picked by the user. In this example, all Ioss::Field::TRANSIENT fields defined on the stk::mesh are output to the results database and the internal stk::mesh field name is used as the name on the database....

See ioss_add_fields() for more details on how to add a field.

    out_region.begin_mode(Ioss::STATE_DEFINE_TRANSIENT);

    // Special processing for nodeblock (all nodes in model)...
    stk::io::ioss_add_fields(meta_data.universal_part(), stk::mesh::Node,
                             out_region.get_node_blocks()[0],
                             Ioss::Field::TRANSIENT);
    
    const stk::mesh::PartVector & all_parts = meta_data.get_parts();
    for ( stk::mesh::PartVector::const_iterator
            ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {

      stk::mesh::Part * const part = *ip;

      // Check whether this part should be output to results database.
      if (stk::io::is_part_io_part(*part)) {
        // Get Ioss::GroupingEntity corresponding to this part...
        Ioss::GroupingEntity *entity = out_region.get_entity(part->name());
        if (entity != NULL) {
          if (entity->type() == Ioss::FACESET || entity->type() == Ioss::EDGESET) {
            int block_count = entity->block_count();
            for (int i=0; i < block_count; i++) {
              Ioss::EntityBlock *fb = entity->get_block(i);
              stk::io::ioss_add_fields(*part, part->primary_entity_type(),
                                       fb, Ioss::Field::TRANSIENT);
            }
          } else {
            stk::io::ioss_add_fields(*part, part->primary_entity_type(),
                                     entity, Ioss::Field::TRANSIENT);
          }
        } else {
        }
      }
    }
    out_region.end_mode(Ioss::STATE_DEFINE_TRANSIENT);

Read and Write Transient Fields (Execute Loop)

At this time, the input and output databases are ready for reading and/or writing transient field data. This is where an application would typically have its execute loop which marches through time.

In the example below, the code queries the input mesh region for the number of timesteps it contains and then simply reads all data on the input database for each timestep and writes the corresponding data to the results database.

    // Read and Write transient fields... 
    out_region.begin_mode(Ioss::STATE_TRANSIENT);
    int timestep_count = in_region.get_property("state_count").get_int();
    for (int step = 1; step <= timestep_count; step++) {
      double time = in_region.get_state_time(step);

      // Read data from the io input mesh database into stk::mesh fields...
      process_input_request(in_region, bulk_data, step);

      // execute()

      // Write data from the stk::mesh fields out to the output database.a
      int out_step = out_region.add_state(time);
      process_output_request(out_region, bulk_data, out_step);
    }
    out_region.end_mode(Ioss::STATE_TRANSIENT);
  }

End of Application

As the input and output Ioss::Region objects go out of scope, they will close the files associated with them and do all cleanup.

Entity Processing Routine Details -- MetaData.

process_nodeblocks

  void process_nodeblocks(Ioss::Region &region, stk::mesh::MetaData &meta)
  {
    const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
    assert(node_blocks.size() == 1);

    Ioss::NodeBlock *nb = node_blocks[0];

    assert(nb->field_exists("mesh_model_coordinates"));
    Ioss::Field coordinates = nb->get_field("mesh_model_coordinates");
    int spatial_dim = coordinates.transformed_storage()->component_count();
    
    stk::mesh::Field<double,stk::mesh::Cartesian> & coord_field =
      meta.declare_field<stk::mesh::Field<double,stk::mesh::Cartesian> >("coordinates");

    meta.put_field( coord_field, stk::mesh::Node, meta.universal_part(),
                    spatial_dim);

   // For this case we are just defining a field for each
   // transient field that is present in the mesh...
    stk::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk::mesh::Node);
  }

process_elementblocks

  void process_elementblocks(Ioss::Region &region, stk::mesh::MetaData &meta)
  {
    const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
    stk::io::default_part_processing(elem_blocks, meta, stk::mesh::Element);

    // Parts were created above, now handle element block specific
    // information (topology, attributes, ...);
    for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
        it != elem_blocks.end(); ++it) {
      Ioss::ElementBlock *entity = *it;
      
      if (stk::io::include_entity(entity)) {
        stk::mesh::Part* const part = meta.get_part(entity->name());
        assert(part != NULL);

        // Element Block attributes (if any)...  For this example 
        // we are just defining a field for each attribute field 
        // that is present in the mesh...
        stk::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE,
                                  *part, part->primary_entity_type());

        // For this case we are just defining a field for each
        // transient field that is present in the mesh...
        stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
                                  *part, part->primary_entity_type());

        std::cout << entity->type_string() << ": " << entity->name()
                  << " , celltop = " << stk::mesh::get_cell_topology(*part)->name
                  << std::endl ;
      }
    }
  }

process_nodesets

  void process_nodesets(Ioss::Region &region, stk::mesh::MetaData &meta)
  {
    const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
    stk::io::default_part_processing(node_sets, meta, stk::mesh::Node);
    
    // In this example, "distribution_factor" is a default field that
    // is automatically declared on all objects that it exists on as
    // is done in current framework?
    stk::mesh::Field<double> & distribution_factors_field =
      meta.declare_field<stk::mesh::Field<double> >("distribution_factors");

    for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
        it != node_sets.end(); ++it) {
      Ioss::NodeSet *entity = *it;

      if (stk::io::include_entity(entity)) {
        stk::mesh::Part* const part = meta.get_part(entity->name());
        assert(part != NULL);
        assert(entity->field_exists("distribution_factors"));

        meta.put_field(distribution_factors_field, stk::mesh::Node, *part);

        // For this case we are just defining a field for each
        // transient field that is present in the mesh...
        stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
                                  *part, part->primary_entity_type());
      }
    }
  }

process_surface_entity

  void process_surface_entity(Ioss::GroupingEntity *entity, stk::mesh::MetaData &meta,
                              stk::mesh::EntityType entity_type)
  {
    assert(entity->type() == Ioss::FACESET || entity->type() == Ioss::EDGESET);
    if (entity->type() == Ioss::FACESET) {
      Ioss::FaceSet *fs = dynamic_cast<Ioss::FaceSet *>(entity);
      assert(fs != NULL);
      const Ioss::FaceBlockContainer& blocks = fs->get_face_blocks();
      stk::io::default_part_processing(blocks, meta, entity_type);
    } else if (entity->type() == Ioss::EDGESET) {
      Ioss::EdgeSet *es = dynamic_cast<Ioss::EdgeSet *>(entity);
      assert(es != NULL);
      const Ioss::EdgeBlockContainer& blocks = es->get_edge_blocks();
      stk::io::default_part_processing(blocks, meta, entity_type);
    }

    stk::mesh::Part* const fs_part = meta.get_part(entity->name());
    assert(fs_part != NULL);
    
    stk::mesh::Field<double, stk::mesh::ElementNode> *distribution_factors_field = NULL;
    bool surface_df_defined = false; // Has the surface df field been defined yet?
      

    int block_count = entity->block_count();
    for (int i=0; i < block_count; i++) {
      Ioss::EntityBlock *fb = entity->get_block(i);
      if (stk::io::include_entity(fb)) {
        std::cout << fb->type_string() << " " << fb->name() << "\n";
        stk::mesh::Part * const fb_part = meta.get_part(fb->name());
        assert(fb_part != NULL);
        meta.declare_part_subset(*fs_part, *fb_part);
      
        if (fb->field_exists("distribution_factors")) {
          if (!surface_df_defined) {
            std::string field_name = entity->name() + "_distribution_factors";
            distribution_factors_field =
              &meta.declare_field<stk::mesh::Field<double, stk::mesh::ElementNode> >(field_name);
            stk::io::set_distribution_factor_field(*fs_part, *distribution_factors_field);
            surface_df_defined = true;
          }
          stk::io::set_distribution_factor_field(*fb_part, *distribution_factors_field);
          int face_node_count = fb->topology()->number_nodes();
          meta.put_field(*distribution_factors_field, fb_part->primary_entity_type(),
                         *fb_part, face_node_count);
        }

        // For this case we are just defining a field for each
        // transient field that is present in the mesh...
        stk::io::define_io_fields(fb, Ioss::Field::TRANSIENT,
                                  *fb_part, fb_part->primary_entity_type());
      }
    }
  }

process_facesets

  void process_facesets(Ioss::Region &region, stk::mesh::MetaData &meta)
  {
    const Ioss::FaceSetContainer& face_sets = region.get_facesets();
    stk::io::default_part_processing(face_sets, meta, stk::mesh::Face);
    
    for(Ioss::FaceSetContainer::const_iterator it = face_sets.begin();
        it != face_sets.end(); ++it) {
      Ioss::FaceSet *entity = *it;

      if (stk::io::include_entity(entity)) {
        process_surface_entity(entity, meta, stk::mesh::Face);
      }
    }
  }

process_edgesets

  void process_edgesets(Ioss::Region &region, stk::mesh::MetaData &meta)
  {
    const Ioss::EdgeSetContainer& edge_sets = region.get_edgesets();
    stk::io::default_part_processing(edge_sets, meta, stk::mesh::Edge);

    for(Ioss::EdgeSetContainer::const_iterator it = edge_sets.begin();
        it != edge_sets.end(); ++it) {
      Ioss::EdgeSet *entity = *it;

      if (stk::io::include_entity(entity)) {
        process_surface_entity(entity, meta, stk::mesh::Edge);
      }
    }
  }

Entity Processing Routine Details -- BulkData

process_nodeblocks

  void process_nodeblocks(Ioss::Region &region, stk::mesh::BulkData &bulk)
  {
    // This must be called after the "process_element_blocks" call
    // since there may be nodes that exist in the database that are
    // not part of the analysis mesh due to subsetting of the element
    // blocks. 

    const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
    assert(node_blocks.size() == 1);

    Ioss::NodeBlock *nb = node_blocks[0];

    std::vector<const stk::mesh::Entity*> nodes;
    stk::io::get_entity_list(nb, stk::mesh::Node, bulk, nodes);
      
    const stk::mesh::MetaData& meta = MetaData::get(bulk);

    // NOTE: Application would probably store this field (and others)
    // somewhere after the declaration instead of looking it up each
    // time it is needed.
    stk::mesh::Field<double,stk::mesh::Cartesian> *coord_field =
      meta.get_field<stk::mesh::Field<double,stk::mesh::Cartesian> >("coordinates");

    stk::io::field_data_from_ioss(coord_field, nodes, nb, "mesh_model_coordinates");
  }

process_elementblocks

  void process_elementblocks(Ioss::Region &region, stk::mesh::BulkData &bulk)
  {
    const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();

    for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
        it != elem_blocks.end(); ++it) {
      Ioss::ElementBlock *entity = *it;

      if (stk::io::include_entity(entity)) {
        const std::string &name = entity->name();
        const stk::mesh::MetaData& meta = MetaData::get(bulk);
        stk::mesh::Part* const part = meta.get_part(name);
        assert(part != NULL);
        
        const CellTopologyData* cell_topo = stk::mesh::get_cell_topology(*part);
        assert(cell_topo != NULL);

        std::vector<stk::mesh::entity_id_type> elem_ids ;
        std::vector<stk::mesh::entity_id_type> connectivity ;
        
        entity->get_field_data("ids", elem_ids);
        entity->get_field_data("connectivity", connectivity);

        int element_count = elem_ids.size();
        int nodes_per_elem = cell_topo->node_count ;

        std::vector<const stk::mesh::Entity*> elements(element_count);
        for(int i=0; i<element_count; ++i) {
          stk::mesh::entity_id_type *conn = &connectivity[i*nodes_per_elem];
          elements[i] = &stk::mesh::declare_element(bulk, *part, elem_ids[i], conn);
        }

        // For this example, we are just taking all attribute fields
        // found on the io database and populating fields on the
        // corresponding mesh part.  In practice, would probably be
        // selective about which attributes to use...
        Ioss::NameList names;
        entity->field_describe(Ioss::Field::ATTRIBUTE, &names);
        for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
          if (*I == "attribute" && names.size() > 1)
            continue;
          stk::mesh::FieldBase *field = meta.get_field<stk::mesh::FieldBase>(*I);
          stk::io::field_data_from_ioss(field, elements, entity, *I);
          
        }
      }
    }
  }

process_nodesets

  void process_nodesets(Ioss::Region &region, stk::mesh::BulkData &bulk)
  {
    // Should only process nodes that have already been defined via the element
    // blocks connectivity lists.
    const Ioss::NodeSetContainer& node_sets = region.get_nodesets();

    for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
        it != node_sets.end(); ++it) {
      Ioss::NodeSet *entity = *it;

      if (stk::io::include_entity(entity)) {
        const std::string & name = entity->name();
        const stk::mesh::MetaData& meta = MetaData::get(bulk);
        stk::mesh::Part* const part = meta.get_part(name);
        assert(part != NULL);
        stk::mesh::PartVector add_parts( 1 , part );

        std::vector<int> node_ids ;
        int node_count = entity->get_field_data("ids", node_ids);
        
        std::vector<const stk::mesh::Entity*> nodes(node_count);
        for(int i=0; i<node_count; ++i) {
          const stk::mesh::entity_key_type key =
            stk::mesh::entity_key(stk::mesh::Node, node_ids[i]);

          nodes[i] = bulk.get_entity( key );
          if (nodes[i] != NULL)
            bulk.declare_entity(key, add_parts );
        }

        // Application would probably store this field (and others)
        // somewhere after the declaration instead of looking it up
        // each time it is needed.
        stk::mesh::Field<double> *df_field =
          meta.get_field<stk::mesh::Field<double> >("distribution_factors");

        if (df_field != NULL) {
          stk::io::field_data_from_ioss(df_field, nodes, entity, "distribution_factors");
        }
      }
    }
  }

process_surface_entity

  void process_surface_entity(const Ioss::GroupingEntity* io ,
                              stk::mesh::BulkData & bulk)
  {
    assert(io->type() == Ioss::FACESET || io->type() == Ioss::EDGESET);
    const stk::mesh::MetaData& meta = MetaData::get(bulk);

    int block_count = io->block_count();
    for (int i=0; i < block_count; i++) {
      Ioss::EntityBlock *block = io->get_block(i);
      if (stk::io::include_entity(block)) {
        std::vector<int> side_ids ;
        std::vector<int> elem_side ;
        
        stk::mesh::Part * const fb_part = meta.get_part(block->name());

        block->get_field_data("ids", side_ids);
        block->get_field_data("element_side", elem_side);
        
        assert(side_ids.size() * 2 == elem_side.size());
        stk::mesh::PartVector add_parts( 1 , fb_part );
        
        int side_count = side_ids.size();
        std::vector<const stk::mesh::Entity*> sides(side_count);
        for(int is=0; is<side_count; ++is) {
      
          const stk::mesh::entity_key_type elem_key =
            stk::mesh::entity_key(stk::mesh::Element, elem_side[is*2]);
          
          // Ioss uses 1-based side ordinal, stk::mesh uses 0-based.
          // Hence the '-1' in the following line.
          int side_ordinal = elem_side[is*2+1] - 1 ;
          
          stk::mesh::Entity* const elem = bulk.get_entity(elem_key);
          // If NULL, then the element was probably assigned to an
          // element block that appears in the database, but was
          // subsetted out of the analysis mesh. Only process if
          // non-null.
          if (elem != NULL) { 
            stk::mesh::Entity& side =
              stk::mesh::declare_element_side(bulk, side_ids[is], *elem, side_ordinal);
            bulk.change_entity_parts( side, add_parts );
            sides[is] = &side;
          } else {
            sides[is] = NULL;
          }
        }

        const stk::mesh::Field<double, stk::mesh::ElementNode> *df_field =
          stk::io::get_distribution_factor_field(*fb_part);
        if (df_field != NULL) {
          stk::io::field_data_from_ioss(df_field, sides, block, "distribution_factors");
        }
      }
    }
  }

process_facesets

  void process_facesets(Ioss::Region &region, stk::mesh::BulkData &bulk)
  {
    const Ioss::FaceSetContainer& face_sets = region.get_facesets();
    
    for(Ioss::FaceSetContainer::const_iterator it = face_sets.begin();
        it != face_sets.end(); ++it) {
      Ioss::FaceSet *entity = *it;
      
      if (stk::io::include_entity(entity)) {
        process_surface_entity(entity, bulk);
      }
    }
  }

process_edgesets

  void process_edgesets(Ioss::Region &region, stk::mesh::BulkData &bulk)
  {
    const Ioss::EdgeSetContainer& edge_sets = region.get_edgesets();
    
    for(Ioss::EdgeSetContainer::const_iterator it = edge_sets.begin();
        it != edge_sets.end(); ++it) {
      Ioss::EdgeSet *entity = *it;
      
      if (stk::io::include_entity(entity)) {
        process_surface_entity(entity, bulk);
      }
    }
  } 

Entity Processing Routine Details -- Field Data to/from Ioss

  void get_field_data(stk::mesh::BulkData &bulk, stk::mesh::Part &part,
                      stk::mesh::EntityType part_type, 
                      Ioss::GroupingEntity *io_entity,
                      Ioss::Field::RoleType filter_role)
  {
    std::vector<const stk::mesh::Entity*> entities;
    stk::io::get_entity_list(io_entity, part_type, bulk, entities);

    stk::mesh::MetaData & meta = MetaData::get(part);
    stk::mesh::Part &universal = meta.universal_part();
    const std::vector<stk::mesh::FieldBase*> &fields = meta.get_fields();

    std::vector<stk::mesh::FieldBase *>::const_iterator I = fields.begin();
    while (I != fields.end()) {
      const stk::mesh::FieldBase *f = *I; ++I;
      if (stk::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
        stk::io::field_data_from_ioss(f, entities, io_entity, f->name());
      }
    }
  }

  void put_field_data(stk::mesh::BulkData &bulk, stk::mesh::Part &part,
                      stk::mesh::EntityType part_type, 
                      Ioss::GroupingEntity *io_entity,
                      Ioss::Field::RoleType filter_role)
  {
    std::vector<const stk::mesh::Entity*> entities;
    stk::io::get_entity_list(io_entity, part_type, bulk, entities);
      
    stk::mesh::MetaData & meta = MetaData::get(part);
    stk::mesh::Part &universal = meta.universal_part();
    const std::vector<stk::mesh::FieldBase*> &fields = meta.get_fields();

    std::vector<stk::mesh::FieldBase *>::const_iterator I = fields.begin();
    while (I != fields.end()) {
      const stk::mesh::FieldBase *f = *I; ++I;
      if (stk::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
        stk::io::field_data_to_ioss(f, entities, io_entity, f->name());
      }
    }
  }

Entity Processing Routine Details -- Input Request

  void process_input_request(Ioss::Region &region,
                             stk::mesh::BulkData &bulk,
                             int step)
  {
    region.begin_state(step);

    // Special processing for nodeblock (all nodes in model)...
    const stk::mesh::MetaData & meta = MetaData::get(bulk);

    // Get field data from nodeblock...
    get_field_data(bulk, meta.universal_part(), stk::mesh::Node,
                   region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
    
    const stk::mesh::PartVector & all_parts = meta.get_parts();
    for ( stk::mesh::PartVector::const_iterator
            ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {

      stk::mesh::Part * const part = *ip;

      // Check whether this part should be output to results database.
      if (stk::io::is_part_io_part(*part)) {
        // Get Ioss::GroupingEntity corresponding to this part...
        Ioss::GroupingEntity *entity = region.get_entity(part->name());
        if (entity != NULL) {
          if (entity->type() == Ioss::FACESET || entity->type() == Ioss::EDGESET) {
            int block_count = entity->block_count();
            for (int i=0; i < block_count; i++) {
              Ioss::EntityBlock *fb = entity->get_block(i);
              // Real application would have different filtering mechanism
              get_field_data(bulk, *part, part->primary_entity_type(),
                       fb, Ioss::Field::TRANSIENT);
            }
          } else {
            get_field_data(bulk, *part, part->primary_entity_type(),
                           entity, Ioss::Field::TRANSIENT);
          }
        }
      }
    }

    region.end_state(step);
  }

Entity Processing Routine Details -- Output Request

  void process_output_request(Ioss::Region &region,
                              stk::mesh::BulkData &bulk,
                              int step)
  {
    region.begin_state(step);
    // Special processing for nodeblock (all nodes in model)...
    const stk::mesh::MetaData & meta = MetaData::get(bulk);

    put_field_data(bulk, meta.universal_part(), stk::mesh::Node,
                   region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
    
    const stk::mesh::PartVector & all_parts = meta.get_parts();
    for ( stk::mesh::PartVector::const_iterator
            ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {

      stk::mesh::Part * const part = *ip;

      // Check whether this part should be output to results database.
      if (stk::io::is_part_io_part(*part)) {

        // Get Ioss::GroupingEntity corresponding to this part...
        Ioss::GroupingEntity *entity = region.get_entity(part->name());
        if (entity != NULL) {

          if (entity->type() == Ioss::FACESET || entity->type() == Ioss::EDGESET) {
            int block_count = entity->block_count();

            for (int i=0; i < block_count; i++) {
              Ioss::EntityBlock *fb = entity->get_block(i);
              // Real application would have different filtering mechanism
              put_field_data(bulk, *part, part->primary_entity_type(),
                             fb, Ioss::Field::TRANSIENT);
            }
          } else {
            put_field_data(bulk, *part, part->primary_entity_type(),
                           entity, Ioss::Field::TRANSIENT);
          }
        }
      }
    }
    region.end_state(step);
  }
}

The Sierra Toolkit IO product contains functions related to the transfer of data between the Ioss classes and the stk::mesh classes. These functions do not provide a total turnkey mesh reading or results writing capability; rather, they provide helper functions for the application to use which make it easier to read and/or write the data. The application has full control over the mesh reading and results/restart writing.


Function Documentation

bool stk::io::include_entity ( Ioss::GroupingEntity *  entity)

Returns true if the Ioss 'entity' should be a 'part' in the analysis mesh. Returns false if the application is only using a subset of the database entities and this entity is not to be used. The function checks whether the "omitted" property exists and if it does, whether the value of the property is "1". The "omitted" property is set by the application during parsing or pre-mesh reading time.

Definition at line 945 of file IossBridge.cpp.

template<typename T >
void stk::io::default_part_processing ( const std::vector< T * > &  entities,
stk::mesh::fem::FEMMetaData fem_meta 
)

This is the primary function used by an application to define the stk::mesh which corresponds to the Ioss mesh read from the finite element model (e.g. exodusII file). For all entities in the passed in 'entities' list, the function will determine whether the entity should be included (see stk::io::include_entity()), and it will then delcare a part corresponding to the entity. It also adds the io_part attribute (see stk::io::define_output_db()) which will cause the part to be output to a results or restart file.

Definition at line 83 of file IossBridge.hpp.

template<typename T >
void stk::io::default_part_processing ( const std::vector< T * > &  entities,
stk::mesh::MetaData meta,
stk::mesh::EntityRank   
)
Deprecated:

Definition at line 94 of file IossBridge.hpp.

void stk::io::define_output_db ( Ioss::Region &  io_region,
const mesh::BulkData &  bulk_data,
const Ioss::Region *  input_region = NULL 
)

Given the newly created Ioss::Region 'io_region', define the model corresponding to the stk::mesh 'bulk_data'. If the optional 'input_region' is passed as an argument, then synchronize all names and ids found on 'input_region' to the output region 'io_region'. The routine will query all parts in 'bulk_data' and if they are io_parts (define by the existance of the IOPartAttribute attribute on the part), then a corresponding Ioss entity will be defined. This routine only deals with the non-transient portion of the model; no transient fields are defined at this point.

Definition at line 1160 of file IossBridge.cpp.

void stk::io::write_output_db ( Ioss::Region &  io_region,
const mesh::BulkData &  bulk 
)

Given an Ioss::Region 'io_region' which has already had its metadata defined via 'define_output_db()' call; transfer all bulk data (node coordinates, element connectivity, ...) to the output database that corresponds to this Ioss::Region. At return, all non-transient portions of the output database will have been output.

Definition at line 1447 of file IossBridge.cpp.

bool stk::io::is_valid_part_field ( const stk::mesh::FieldBase field,
stk::mesh::EntityRank  part_type,
stk::mesh::Part part,
stk::mesh::Part universal,
Ioss::Field::RoleType  filter_role,
bool  add_all 
)

Determine whether the field is defined on the specified part and should also be associated with a Ioss GroupingEntity for input or output

Determine whether the field is defined on the specified part and should also be associated with an Ioss::GroupingEntity for input or output.

The 'universal' part is argument currently only used for an EntityRank of type 'node'. In this case, the field is only valid if it does exist on 'part', but does not exist on 'universal' unless 'part' and 'universal' are the same part. The motivation for this is that an Ioss::NodeBlock corresponds to the universal part and an Ioss::NodeSet corresponds to the sub part. Without the check, all nodeblock fields would also be defined on the nodeset which is not what is desired.

The 'filter_role' only selects fields with the specified role (e.g., TRANSIENT, ATTRIBUTE, ..., see Ioss documentation for valid roles) unless 'add_all == true' is specified.

The field's role is defined via a call to 'stkio::set_field_role'

Definition at line 564 of file IossBridge.cpp.

void stk::io::ioss_add_fields ( stk::mesh::Part part,
stk::mesh::EntityRank  part_type,
Ioss::GroupingEntity *  entity,
const Ioss::Field::RoleType  filter_role,
bool  add_all 
)

Add all stk::Fields on the entities of the specified part_type on the specified part of the specified role * to the specified Ioss::GroupingEntity

Add all stk::Fields on the specified part of the specified filter_role to the specified Ioss::GroupingEntity. Retrieves all fields; calls 'is_valid_part_field'; and adds those that return true.

Definition at line 811 of file IossBridge.cpp.

void stk::io::define_io_fields ( Ioss::GroupingEntity *  entity,
Ioss::Field::RoleType  role,
stk::mesh::Part part,
stk::mesh::EntityRank  part_type 
)

For the given Ioss::GroupingEntity "entity", find all fields that exist on the input database of type "role" and declare them on the give stk::mesh::Part "part". The "part_type" argument specifies the entity type (node, element, ...) that the field should be declared on for this "part"

The "role" will typically be either "ATTRIBUTE" or "TRANSIENT"

For the given Ioss::GroupingEntity "entity", find all fields that exist on the input database of type "role" and declare them on the give stk::mesh::Part "part". The "part_type" argument specifies the entity type (node, element, ...) that the field should be declared on for this "part"

The "role" will typically be either "ATTRIBUTE" or "TRANSIENT"

This is essentially the complement of the 'ioss_add_fields' function.

Todo:
IMPLEMENT Need a field selection mechanism and a field naming (ioss_name -> stk::name) For now, select all and give the stk field the same name as the ioss field.

Skip the attribute field that is named "attribute"

Todo:
IMPLEMENT Need to determine whether these are multi-state fields or constant, or interpolated, or ...

Definition at line 848 of file IossBridge.cpp.

const CellTopologyData * stk::io::map_topology_ioss_to_cell ( const Ioss::ElementTopology *  topology)
Todo:
QUESTION Should this function be at the application level, or provided by stk_io? In either case, applications should have capabilty to register new mappings.

Given an Ioss::ElementTopolgy, return the corresponding CellTopologyData. If a corresponding topology is not found, a runtime error exception will be thrown.

Todo:
REFACTOR Consider either using or integrating the Trilinos CellTopology package into or with the Ioss::ElementTopology classes. That would then totally eliminate the need for these fragile mapping functions. However, it would still need to be extensible via application registration of new type mappings.

Definition at line 610 of file IossBridge.cpp.

std::string stk::io::map_topology_cell_to_ioss ( const CellTopologyData *  cell_top,
int  spatial_dimension 
)

Given a CellTopologyData and a spatial_dimension, return the corresponding Ioss::ElementTopology. If a corresponding topology is not found, a runtime error exception will be thrown.

Definition at line 627 of file IossBridge.cpp.

void stk::io::get_entity_list ( Ioss::GroupingEntity *  io_entity,
stk::mesh::EntityRank  part_type,
const stk::mesh::BulkData bulk,
std::vector< stk::mesh::Entity * > &  entities 
)

For the given Ioss entity, create a vector of stk::mesh::Entity pointers such that the entities in the 'entities' list match the order of the entities in the Ioss entity. If there is not a corresponding stk::mesh::Entity, the entry at that location will be NULL. Upon return, the size of the 'entities' list should match the number of entities in 'io_entity'. The returned list is typically used to get/put field data from/to an Ioss::GroupingEntity to/from an stk::mesh::Field. See stk::io::field_data_from_ioss() and stk::io::field_data_to_ioss() for examples.

Definition at line 878 of file IossBridge.cpp.

void stk::io::field_data_from_ioss ( const stk::mesh::FieldBase field,
std::vector< stk::mesh::Entity * > &  entities,
Ioss::GroupingEntity *  io_entity,
const std::string &  io_fld_name 
)

Fill the specified 'field' with data from the Ioss field named 'io_fld_name' on the Ioss entity 'io_entity'. The mapping from the meshobjects in the Ioss io_entity to the stk::mesh::Entities is given by the 'entities' list.

Todo:
REFACTOR Need some additional compatability checks between Ioss field and stk::mesh::Field; better error messages...

Definition at line 894 of file IossBridge.cpp.

void stk::io::field_data_to_ioss ( const stk::mesh::FieldBase field,
std::vector< stk::mesh::Entity * > &  entities,
Ioss::GroupingEntity *  io_entity,
const std::string &  io_fld_name,
Ioss::Field::RoleType  filter_role 
)

Extract data from the specified 'field' and put it to the Ioss field named 'io_fld_name' on the Ioss entity 'io_entity'. The mapping from the meshobjects in the Ioss io_entity to the stk::mesh::Entities is given by the 'entities' list.

Todo:
REFACTOR Need some additional compatability checks between Ioss field and stk::mesh::Field; better error messages...

Definition at line 914 of file IossBridge.cpp.

const mesh::Field< double, mesh::ElementNode > * stk::io::get_distribution_factor_field ( const mesh::Part &  p)

Returns the stk::mesh::Field which contains the distribution factors for the specified part 'p'. Returns NULL if there is no such field.

Definition at line 1487 of file IossBridge.cpp.

void stk::io::set_distribution_factor_field ( mesh::Part &  p,
const mesh::Field< double, mesh::ElementNode > &  df_field 
)

Defines the stk::mesh::Field which contains the distribution factors for the specified part 'p'.

Definition at line 1492 of file IossBridge.cpp.

const Ioss::Field::RoleType * stk::io::get_field_role ( const mesh::FieldBase &  f)

Returns the Ioss::Field::RoleType of the mesh::Field 'f'. This must have earlier been defined using stk::io::set_field_role(). Returns NULL if the role was not defined.

Definition at line 1499 of file IossBridge.cpp.

void stk::io::set_field_role ( mesh::FieldBase &  f,
const Ioss::Field::RoleType &  role 
)

Defines the Ioss::Field::RoleType of the mesh::Field 'f' to be 'role'.

Definition at line 1504 of file IossBridge.cpp.

bool stk::io::is_part_io_part ( mesh::Part &  part)

Returns whether the mesh::Part 'p' should be output to a results or restart database. Or, in other words, whether the part should have an Ioss::GroupingEntity of the correct type defined in an Ioss::Region. The function will return true if the part 'p' has an IOPartAttribute defined on it. The attributed is defined via the stk::io::put_io_part_attribute() function.

Definition at line 1482 of file IossBridge.cpp.

void stk::io::put_io_part_attribute ( mesh::Part &  part,
Ioss::GroupingEntity *  entity = NULL 
)

Define an attribute on the specified part 'part' indicating that this part should be used for io.

See also:
is_part_io_part()

Definition at line 541 of file IossBridge.cpp.

void stk::io::internal_part_processing ( Ioss::GroupingEntity *  entity,
stk::mesh::MetaData meta 
)
Deprecated:

Definition at line 734 of file IossBridge.cpp.

void stk::io::internal_part_processing ( Ioss::EntityBlock *  entity,
stk::mesh::MetaData meta 
)
Deprecated:

Todo:
IMPLEMENT Determine whether application can work with this topology type... Perhaps map_topology_ioss_to_cell only returns a valid topology if the application has registered

that it can handle that specific topology.

Todo:
IMPLEMENT handle cell_topolgy mapping error...

Definition at line 749 of file IossBridge.cpp.

void stk::io::initialize_spatial_dimension ( mesh::MetaData &  meta,
size_t  spatial_dimension,
const std::vector< std::string > &  entity_rank_names 
)
Deprecated:

Definition at line 439 of file IossBridge.cpp.

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends