Sierra Toolkit  Version of the Day
Sierra Toolkit IO

Namespaces

 stk_example_io
 

Functions

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

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_classic::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_classic::mesh model. At any time prior to defining the stk_classic::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_classic::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_classic::mesh::MetaData for the analysis model. Each of the process_* functions is described in more detail later on.

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_classic::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_classic::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_classic::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_classic::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_classic::io::define_output_db(out_region, bulk_data, &in_region);
stk_classic::io::write_output_db(out_region, bulk_data);

Define Transient Output Fields

At this time, the application would define what stk_classic::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_classic::mesh.

The real app would also only register a subset of the stk_classic::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_classic::mesh are output to the results database and the internal stk_classic::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_classic::io::ioss_add_fields(meta_data.universal_part(), stk_classic::mesh::Node,
out_region.get_node_blocks()[0],
Ioss::Field::TRANSIENT);
const stk_classic::mesh::PartVector & all_parts = meta_data.get_parts();
for ( stk_classic::mesh::PartVector::const_iterator
ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
stk_classic::mesh::Part * const part = *ip;
// Check whether this part should be output to results database.
// 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_classic::io::ioss_add_fields(*part, part->primary_entity_type(),
fb, Ioss::Field::TRANSIENT);
}
} else {
stk_classic::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_classic::mesh fields...
process_input_request(in_region, bulk_data, step);
// execute()
// Write data from the stk_classic::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_classic::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();
meta.put_field( coord_field, stk_classic::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_classic::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk_classic::mesh::Node);
}

process_elementblocks

void process_elementblocks(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
{
const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
stk_classic::io::default_part_processing(elem_blocks, meta, stk_classic::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;
stk_classic::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_classic::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_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
*part, part->primary_entity_type());
std::cout << entity->type_string() << ": " << entity->name()
<< " , celltop = " << stk_classic::mesh::get_cell_topology(*part)->name
<< std::endl ;
}
}
}

process_nodesets

void process_nodesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
{
const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
stk_classic::io::default_part_processing(node_sets, meta, stk_classic::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_classic::mesh::Field<double> & distribution_factors_field =
meta.declare_field<stk_classic::mesh::Field<double> >("distribution_factors");
for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
it != node_sets.end(); ++it) {
Ioss::NodeSet *entity = *it;
stk_classic::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_classic::mesh::Node, *part);
// For this case we are just defining a field for each
// transient field that is present in the mesh...
stk_classic::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
*part, part->primary_entity_type());
}
}
}

process_surface_entity

void process_surface_entity(Ioss::GroupingEntity *entity, stk_classic::mesh::MetaData &meta,
stk_classic::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_classic::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_classic::io::default_part_processing(blocks, meta, entity_type);
}
stk_classic::mesh::Part* const fs_part = meta.get_part(entity->name());
assert(fs_part != 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);
std::cout << fb->type_string() << " " << fb->name() << "\n";
stk_classic::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 =
stk_classic::io::set_distribution_factor_field(*fs_part, *distribution_factors_field);
surface_df_defined = true;
}
stk_classic::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_classic::io::define_io_fields(fb, Ioss::Field::TRANSIENT,
*fb_part, fb_part->primary_entity_type());
}
}
}

process_facesets

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

process_edgesets

void process_edgesets(Ioss::Region &region, stk_classic::mesh::MetaData &meta)
{
const Ioss::EdgeSetContainer& edge_sets = region.get_edgesets();
stk_classic::io::default_part_processing(edge_sets, meta, stk_classic::mesh::Edge);
for(Ioss::EdgeSetContainer::const_iterator it = edge_sets.begin();
it != edge_sets.end(); ++it) {
Ioss::EdgeSet *entity = *it;
process_surface_entity(entity, meta, stk_classic::mesh::Edge);
}
}
}

Entity Processing Routine Details -- BulkData

process_nodeblocks

void process_nodeblocks(Ioss::Region &region, stk_classic::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_classic::mesh::Entity*> nodes;
stk_classic::io::get_entity_list(nb, stk_classic::mesh::Node, bulk, nodes);
const stk_classic::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_classic::io::field_data_from_ioss(coord_field, nodes, nb, "mesh_model_coordinates");
}

process_elementblocks

void process_elementblocks(Ioss::Region &region, stk_classic::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;
const std::string &name = entity->name();
const stk_classic::mesh::MetaData& meta = MetaData::get(bulk);
stk_classic::mesh::Part* const part = meta.get_part(name);
assert(part != NULL);
const CellTopologyData* cell_topo = stk_classic::mesh::get_cell_topology(*part);
assert(cell_topo != NULL);
std::vector<stk_classic::mesh::entity_id_type> elem_ids ;
std::vector<stk_classic::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_classic::mesh::Entity*> elements(element_count);
for(int i=0; i<element_count; ++i) {
stk_classic::mesh::entity_id_type *conn = &connectivity[i*nodes_per_elem];
elements[i] = &stk_classic::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_classic::io::field_data_from_ioss(field, elements, entity, *I);
}
}
}
}

process_nodesets

void process_nodesets(Ioss::Region &region, stk_classic::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;
const std::string & name = entity->name();
const stk_classic::mesh::MetaData& meta = MetaData::get(bulk);
stk_classic::mesh::Part* const part = meta.get_part(name);
assert(part != NULL);
stk_classic::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_classic::mesh::Entity*> nodes(node_count);
for(int i=0; i<node_count; ++i) {
const stk_classic::mesh::entity_key_type key =
stk_classic::mesh::entity_key(stk_classic::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.
meta.get_field<stk_classic::mesh::Field<double> >("distribution_factors");
if (df_field != NULL) {
stk_classic::io::field_data_from_ioss(df_field, nodes, entity, "distribution_factors");
}
}
}
}

process_surface_entity

void process_surface_entity(const Ioss::GroupingEntity* io ,
{
assert(io->type() == Ioss::FACESET || io->type() == Ioss::EDGESET);
const stk_classic::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);
std::vector<int> side_ids ;
std::vector<int> elem_side ;
stk_classic::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_classic::mesh::PartVector add_parts( 1 , fb_part );
int side_count = side_ids.size();
std::vector<const stk_classic::mesh::Entity*> sides(side_count);
for(int is=0; is<side_count; ++is) {
const stk_classic::mesh::entity_key_type elem_key =
stk_classic::mesh::entity_key(stk_classic::mesh::Element, elem_side[is*2]);
// Ioss uses 1-based side ordinal, stk_classic::mesh uses 0-based.
// Hence the '-1' in the following line.
int side_ordinal = elem_side[is*2+1] - 1 ;
stk_classic::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_classic::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;
}
}
if (df_field != NULL) {
stk_classic::io::field_data_from_ioss(df_field, sides, block, "distribution_factors");
}
}
}
}

process_facesets

void process_facesets(Ioss::Region &region, stk_classic::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;
process_surface_entity(entity, bulk);
}
}
}

process_edgesets

void process_edgesets(Ioss::Region &region, stk_classic::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;
process_surface_entity(entity, bulk);
}
}
}

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

void get_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part,
stk_classic::mesh::EntityType part_type,
Ioss::GroupingEntity *io_entity,
Ioss::Field::RoleType filter_role)
{
std::vector<const stk_classic::mesh::Entity*> entities;
stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities);
stk_classic::mesh::MetaData & meta = MetaData::get(part);
const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields();
std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin();
while (I != fields.end()) {
const stk_classic::mesh::FieldBase *f = *I; ++I;
if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
stk_classic::io::field_data_from_ioss(f, entities, io_entity, f->name());
}
}
}
void put_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part,
stk_classic::mesh::EntityType part_type,
Ioss::GroupingEntity *io_entity,
Ioss::Field::RoleType filter_role)
{
std::vector<const stk_classic::mesh::Entity*> entities;
stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities);
stk_classic::mesh::MetaData & meta = MetaData::get(part);
const std::vector<stk_classic::mesh::FieldBase*> &fields = meta.get_fields();
std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin();
while (I != fields.end()) {
const stk_classic::mesh::FieldBase *f = *I; ++I;
if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role)) {
stk_classic::io::field_data_to_ioss(f, entities, io_entity, f->name());
}
}
}

Entity Processing Routine Details -- Input Request

void process_input_request(Ioss::Region &region,
int step)
{
region.begin_state(step);
// Special processing for nodeblock (all nodes in model)...
const stk_classic::mesh::MetaData & meta = MetaData::get(bulk);
// Get field data from nodeblock...
get_field_data(bulk, meta.universal_part(), stk_classic::mesh::Node,
region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
const stk_classic::mesh::PartVector & all_parts = meta.get_parts();
for ( stk_classic::mesh::PartVector::const_iterator
ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
stk_classic::mesh::Part * const part = *ip;
// Check whether this part should be output to results database.
// 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,
int step)
{
region.begin_state(step);
// Special processing for nodeblock (all nodes in model)...
const stk_classic::mesh::MetaData & meta = MetaData::get(bulk);
put_field_data(bulk, meta.universal_part(), stk_classic::mesh::Node,
region.get_node_blocks()[0], Ioss::Field::TRANSIENT);
const stk_classic::mesh::PartVector & all_parts = meta.get_parts();
for ( stk_classic::mesh::PartVector::const_iterator
ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
stk_classic::mesh::Part * const part = *ip;
// Check whether this part should be output to results database.
// 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_classic::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

◆ include_entity()

bool stk_classic::io::include_entity ( const 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 1035 of file IossBridge.cpp.

◆ internal_part_processing() [1/2]

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

Definition at line 792 of file IossBridge.cpp.

◆ internal_part_processing() [2/2]

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

Definition at line 807 of file IossBridge.cpp.

◆ default_part_processing() [1/2]

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

This is the primary function used by an application to define the stk_classic::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_classic::io::include_entity()), and it will then delcare a part corresponding to the entity. It also adds the io_part attribute (see stk_classic::io::define_output_db()) which will cause the part to be output to a results or restart file.

Definition at line 93 of file IossBridge.hpp.

◆ default_part_processing() [2/2]

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

Definition at line 104 of file IossBridge.hpp.

◆ define_output_db()

void stk_classic::io::define_output_db ( Ioss::Region &  io_region,
const mesh::BulkData bulk_data,
const Ioss::Region *  input_region = NULL,
const stk_classic::mesh::Selector anded_selector = NULL,
const bool  sort_stk_parts = false 
)

Given the newly created Ioss::Region 'io_region', define the model corresponding to the stk_classic::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.

Parameters
[in]sort_stk_partsForce a sorted order on the stk_mesh parts so all pieces of a decomposed mesh have consistent part ordering. Normally not necessary, since MetaData is created from a parallel-consistent data base. It is useful in cases such as streaming refinement where each piece of a parallel- decomposed mesh is read in sequentially and parts are thus possibly created in different orderings.

Definition at line 1276 of file IossBridge.cpp.

◆ write_output_db()

void stk_classic::io::write_output_db ( Ioss::Region &  io_region,
const mesh::BulkData bulk,
const stk_classic::mesh::Selector anded_selector = NULL 
)

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 1643 of file IossBridge.cpp.

◆ is_valid_part_field()

bool stk_classic::io::is_valid_part_field ( const stk_classic::mesh::FieldBase field,
const stk_classic::mesh::EntityRank  part_type,
const stk_classic::mesh::Part part,
const stk_classic::mesh::Part universal,
const 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 'stk_classic::io::set_field_role'

Definition at line 620 of file IossBridge.cpp.

◆ ioss_add_fields()

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

Add all stk_classic::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_classic::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 868 of file IossBridge.cpp.

◆ define_io_fields()

void stk_classic::io::define_io_fields ( Ioss::GroupingEntity *  entity,
Ioss::Field::RoleType  role,
stk_classic::mesh::Part part,
stk_classic::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_classic::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_classic::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.

Definition at line 905 of file IossBridge.cpp.

◆ map_topology_ioss_to_cell()

const CellTopologyData * stk_classic::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 670 of file IossBridge.cpp.

◆ map_topology_cell_to_ioss()

std::string stk_classic::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 687 of file IossBridge.cpp.

◆ get_entity_list()

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

For the given Ioss entity, create a vector of stk_classic::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_classic::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_classic::mesh::Field. See stk_classic::io::field_data_from_ioss() and stk_classic::io::field_data_to_ioss() for examples.

Definition at line 952 of file IossBridge.cpp.

◆ field_data_from_ioss()

void stk_classic::io::field_data_from_ioss ( const stk_classic::mesh::FieldBase field,
std::vector< stk_classic::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_classic::mesh::Entities is given by the 'entities' list.

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

Definition at line 964 of file IossBridge.cpp.

◆ field_data_to_ioss()

void stk_classic::io::field_data_to_ioss ( const stk_classic::mesh::FieldBase field,
std::vector< stk_classic::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_classic::mesh::Entities is given by the 'entities' list.

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

Definition at line 999 of file IossBridge.cpp.

◆ get_distribution_factor_field()

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

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

Definition at line 1701 of file IossBridge.cpp.

◆ set_distribution_factor_field()

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

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

Definition at line 1706 of file IossBridge.cpp.

◆ get_field_role()

const Ioss::Field::RoleType * stk_classic::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_classic::io::set_field_role(). Returns NULL if the role was not defined.

Definition at line 1713 of file IossBridge.cpp.

◆ set_field_role()

void stk_classic::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 1718 of file IossBridge.cpp.

◆ is_part_io_part()

bool stk_classic::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_classic::io::put_io_part_attribute() function.

Definition at line 1696 of file IossBridge.cpp.

◆ put_io_part_attribute()

void stk_classic::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 570 of file IossBridge.cpp.

◆ remove_io_part_attribute()

void stk_classic::io::remove_io_part_attribute ( mesh::Part part)

Remove the existing attribute on the specified part 'part' that indicates that this part should be used for io.

See also
is_part_io_part()

Definition at line 589 of file IossBridge.cpp.

◆ initialize_spatial_dimension()

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

Definition at line 468 of file IossBridge.cpp.