Sierra Toolkit  Version of the Day
MeshReadWriteUtils.cpp
00001  /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010, 2011 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #include <stk_io/MeshReadWriteUtils.hpp>
00010 
00011 #include <stk_mesh/base/BulkData.hpp>
00012 #include <stk_mesh/base/GetEntities.hpp>
00013 #include <stk_mesh/fem/FEMMetaData.hpp>
00014 #include <stk_mesh/fem/FEMHelpers.hpp>
00015 
00016 #include <stk_mesh/base/Field.hpp>
00017 #include <stk_mesh/base/FieldData.hpp>
00018 #include <stk_mesh/base/FieldParallel.hpp>
00019 
00020 #include <Shards_BasicTopologies.hpp>
00021 
00022 #include <stk_io/IossBridge.hpp>
00023 
00024 #include <Ioss_SubSystem.h>
00025 
00026 #include <stk_util/util/tokenize.hpp>
00027 #include <iostream>
00028 #include <sstream>
00029 #include <cmath>
00030 
00031 #include <limits>
00032 #include <assert.h>
00033 
00034 namespace {
00035 void process_surface_entity(Ioss::SideSet *sset, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00036 {
00037   assert(sset->type() == Ioss::SIDESET);
00038   const Ioss::SideBlockContainer& blocks = sset->get_side_blocks();
00039   stk_classic::io::default_part_processing(blocks, fem_meta);
00040 
00041   stk_classic::mesh::Part* const ss_part = fem_meta.get_part(sset->name());
00042   assert(ss_part != NULL);
00043 
00044   stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *distribution_factors_field = NULL;
00045   bool surface_df_defined = false; // Has the surface df field been defined yet?
00046 
00047   size_t block_count = sset->block_count();
00048   for (size_t i=0; i < block_count; i++) {
00049     Ioss::SideBlock *sb = sset->get_block(i);
00050     if (stk_classic::io::include_entity(sb)) {
00051       stk_classic::mesh::Part * const sb_part = fem_meta.get_part(sb->name());
00052       assert(sb_part != NULL);
00053       fem_meta.declare_part_subset(*ss_part, *sb_part);
00054 
00055       if (sb->field_exists("distribution_factors")) {
00056         if (!surface_df_defined) {
00057           std::string field_name = sset->name() + "_df";
00058           distribution_factors_field =
00059             &fem_meta.declare_field<stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> >(field_name);
00060           stk_classic::io::set_field_role(*distribution_factors_field, Ioss::Field::MESH);
00061           stk_classic::io::set_distribution_factor_field(*ss_part, *distribution_factors_field);
00062           surface_df_defined = true;
00063         }
00064         stk_classic::io::set_distribution_factor_field(*sb_part, *distribution_factors_field);
00065         int side_node_count = sb->topology()->number_nodes();
00066         stk_classic::mesh::put_field(*distribution_factors_field,
00067                              stk_classic::io::part_primary_entity_rank(*sb_part),
00068                              *sb_part, side_node_count);
00069       }
00070     }
00071   }
00072 }
00073 
00074   size_t get_entities(stk_classic::mesh::Part &part,
00075           const stk_classic::mesh::BulkData &bulk,
00076           std::vector<stk_classic::mesh::Entity*> &entities,
00077           const stk_classic::mesh::Selector *anded_selector)
00078   {
00079     stk_classic::mesh::MetaData & meta = stk_classic::mesh::MetaData::get(part);
00080     stk_classic::mesh::EntityRank type = stk_classic::io::part_primary_entity_rank(part);
00081     
00082     stk_classic::mesh::Selector own = meta.locally_owned_part();
00083     stk_classic::mesh::Selector selector = part & own;
00084     if (anded_selector) selector &= *anded_selector;
00085     
00086     get_selected_entities(selector, bulk.buckets(type), entities);
00087     return entities.size();
00088   }
00089 }
00090 
00091 // ========================================================================
00092 template <typename INT>
00093 void process_surface_entity(const Ioss::SideSet* sset, stk_classic::mesh::BulkData & bulk, INT /*dummy*/)
00094 {
00095   assert(sset->type() == Ioss::SIDESET);
00096 
00097   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00098 
00099   size_t block_count = sset->block_count();
00100   for (size_t i=0; i < block_count; i++) {
00101     Ioss::SideBlock *block = sset->get_block(i);
00102     if (stk_classic::io::include_entity(block)) {
00103       std::vector<INT> side_ids ;
00104       std::vector<INT> elem_side ;
00105 
00106       stk_classic::mesh::Part * const sb_part = fem_meta.get_part(block->name());
00107       stk_classic::mesh::EntityRank elem_rank = fem_meta.element_rank();
00108 
00109       block->get_field_data("ids", side_ids);
00110       block->get_field_data("element_side", elem_side);
00111 
00112       assert(side_ids.size() * 2 == elem_side.size());
00113       stk_classic::mesh::PartVector add_parts( 1 , sb_part );
00114 
00115       size_t side_count = side_ids.size();
00116       std::vector<stk_classic::mesh::Entity*> sides(side_count);
00117       for(size_t is=0; is<side_count; ++is) {
00118         stk_classic::mesh::Entity* const elem = bulk.get_entity(elem_rank, elem_side[is*2]);
00119 
00120         // If NULL, then the element was probably assigned to an
00121         // element block that appears in the database, but was
00122         // subsetted out of the analysis mesh. Only process if
00123         // non-null.
00124         if (elem != NULL) {
00125           // Ioss uses 1-based side ordinal, stk_classic::mesh uses 0-based.
00126           int side_ordinal = elem_side[is*2+1] - 1;
00127 
00128           stk_classic::mesh::Entity* side_ptr = NULL;
00129           side_ptr = &stk_classic::mesh::fem::declare_element_side(bulk, side_ids[is], *elem, side_ordinal);
00130           stk_classic::mesh::Entity& side = *side_ptr;
00131 
00132           bulk.change_entity_parts( side, add_parts );
00133           sides[is] = &side;
00134         } else {
00135           sides[is] = NULL;
00136         }
00137       }
00138 
00139       const stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *df_field =
00140         stk_classic::io::get_distribution_factor_field(*sb_part);
00141       if (df_field != NULL) {
00142         stk_classic::io::field_data_from_ioss(df_field, sides, block, "distribution_factors");
00143       }
00144 
00145       // Add all attributes as fields.
00146       // If the only attribute is 'attribute', then add it; otherwise the other attributes are the
00147       // named components of the 'attribute' field, so add them instead.
00148       Ioss::NameList names;
00149       block->field_describe(Ioss::Field::ATTRIBUTE, &names);
00150       for(Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
00151         if(*I == "attribute" && names.size() > 1)
00152           continue;
00153         stk_classic::mesh::FieldBase *field = fem_meta.get_field<stk_classic::mesh::FieldBase> (*I);
00154         if (field)
00155           stk_classic::io::field_data_from_ioss(field, sides, block, *I);
00156       }
00157     }
00158   }
00159 }
00160 
00161 void process_surface_entity(const Ioss::SideSet* sset, stk_classic::mesh::BulkData & bulk)
00162 {
00163   if (stk_classic::io::db_api_int_size(sset) == 4)
00164     process_surface_entity(sset, bulk, (int)0);
00165   else
00166     process_surface_entity(sset, bulk, (int64_t)0);
00167 }
00168 
00169 void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00170 {
00171   const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
00172   assert(node_blocks.size() == 1);
00173 
00174   Ioss::NodeBlock *nb = node_blocks[0];
00175 
00176   assert(nb->field_exists("mesh_model_coordinates"));
00177   Ioss::Field coordinates = nb->get_field("mesh_model_coordinates");
00178   int spatial_dim = coordinates.transformed_storage()->component_count();
00179 
00180   stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> & coord_field =
00181     fem_meta.declare_field<stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> >("coordinates");
00182 
00183   stk_classic::mesh::put_field( coord_field, fem_meta.node_rank(), fem_meta.universal_part(), spatial_dim);
00184   stk_classic::io::define_io_fields(nb, Ioss::Field::ATTRIBUTE, fem_meta.universal_part(), 0);
00185 }
00186 
00187 void process_nodeblocks(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00188 {
00189   // This must be called after the "process_element_blocks" call
00190   // since there may be nodes that exist in the database that are
00191   // not part of the analysis mesh due to subsetting of the element
00192   // blocks.
00193 
00194   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00195 
00196   const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
00197   assert(node_blocks.size() == 1);
00198 
00199   Ioss::NodeBlock *nb = node_blocks[0];
00200 
00201   std::vector<stk_classic::mesh::Entity*> nodes;
00202   stk_classic::io::get_entity_list(nb, fem_meta.node_rank(), bulk, nodes);
00203 
00204   stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> *coord_field =
00205     fem_meta.get_field<stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> >("coordinates");
00206 
00207   stk_classic::io::field_data_from_ioss(coord_field, nodes, nb, "mesh_model_coordinates");
00208 
00209   // Add all attributes as fields.
00210   // If the only attribute is 'attribute', then add it; otherwise the other attributes are the
00211   // named components of the 'attribute' field, so add them instead.
00212   Ioss::NameList names;
00213   nb->field_describe(Ioss::Field::ATTRIBUTE, &names);
00214   for(Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
00215     if(*I == "attribute" && names.size() > 1)
00216       continue;
00217     stk_classic::mesh::FieldBase *field = fem_meta.get_field<stk_classic::mesh::FieldBase> (*I);
00218     if (field)
00219       stk_classic::io::field_data_from_ioss(field, nodes, nb, *I);
00220   }
00221 }
00222 
00223 // ========================================================================
00224 void process_elementblocks(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00225 {
00226   const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
00227   stk_classic::io::default_part_processing(elem_blocks, fem_meta);
00228 }
00229 
00230 template <typename INT>
00231 void process_elementblocks(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, INT /*dummy*/)
00232 {
00233   const stk_classic::mesh::fem::FEMMetaData& fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00234 
00235   const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
00236   for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
00237       it != elem_blocks.end(); ++it) {
00238     Ioss::ElementBlock *entity = *it;
00239 
00240     if (stk_classic::io::include_entity(entity)) {
00241       const std::string &name = entity->name();
00242       stk_classic::mesh::Part* const part = fem_meta.get_part(name);
00243       assert(part != NULL);
00244 
00245       const CellTopologyData* cell_topo = stk_classic::io::get_cell_topology(*part);
00246       if (cell_topo == NULL) {
00247         std::ostringstream msg ;
00248         msg << " INTERNAL_ERROR: Part " << part->name() << " returned NULL from get_cell_topology()";
00249         throw std::runtime_error( msg.str() );
00250       }
00251 
00252       std::vector<INT> elem_ids ;
00253       std::vector<INT> connectivity ;
00254 
00255       entity->get_field_data("ids", elem_ids);
00256       entity->get_field_data("connectivity", connectivity);
00257 
00258       size_t element_count = elem_ids.size();
00259       int nodes_per_elem = cell_topo->node_count ;
00260 
00261       std::vector<stk_classic::mesh::EntityId> id_vec(nodes_per_elem);
00262       std::vector<stk_classic::mesh::Entity*> elements(element_count);
00263 
00264       for(size_t i=0; i<element_count; ++i) {
00265         INT *conn = &connectivity[i*nodes_per_elem];
00266         std::copy(&conn[0], &conn[0+nodes_per_elem], id_vec.begin());
00267         elements[i] = &stk_classic::mesh::fem::declare_element(bulk, *part, elem_ids[i], &id_vec[0]);
00268       }
00269 
00270       // Add all element attributes as fields.
00271       // If the only attribute is 'attribute', then add it; otherwise the other attributes are the
00272       // named components of the 'attribute' field, so add them instead.
00273       Ioss::NameList names;
00274       entity->field_describe(Ioss::Field::ATTRIBUTE, &names);
00275       for(Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
00276         if(*I == "attribute" && names.size() > 1)
00277           continue;
00278         stk_classic::mesh::FieldBase *field = fem_meta.get_field<stk_classic::mesh::FieldBase> (*I);
00279         if (field)
00280           stk_classic::io::field_data_from_ioss(field, elements, entity, *I);
00281       }
00282     }
00283   }
00284 }
00285 
00286 // ========================================================================
00287 // ========================================================================
00288 void process_nodesets(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00289 {
00290   const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
00291   stk_classic::io::default_part_processing(node_sets, fem_meta);
00292 
00293   stk_classic::mesh::Field<double> & distribution_factors_field =
00294     fem_meta.declare_field<stk_classic::mesh::Field<double> >("distribution_factors");
00295   stk_classic::io::set_field_role(distribution_factors_field, Ioss::Field::MESH);
00296 
00302   for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
00303       it != node_sets.end(); ++it) {
00304     Ioss::NodeSet *entity = *it;
00305 
00306     if (stk_classic::io::include_entity(entity)) {
00307       stk_classic::mesh::Part* const part = fem_meta.get_part(entity->name());
00308       assert(part != NULL);
00309       assert(entity->field_exists("distribution_factors"));
00310 
00311       stk_classic::mesh::put_field(distribution_factors_field, fem_meta.node_rank(), *part);
00312     }
00313   }
00314 }
00315 
00316 // ========================================================================
00317 // ========================================================================
00318 void process_sidesets(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00319 {
00320   const Ioss::SideSetContainer& side_sets = region.get_sidesets();
00321   stk_classic::io::default_part_processing(side_sets, fem_meta);
00322 
00323   for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
00324       it != side_sets.end(); ++it) {
00325     Ioss::SideSet *entity = *it;
00326 
00327     if (stk_classic::io::include_entity(entity)) {
00328       process_surface_entity(entity, fem_meta);
00329     }
00330   }
00331 }
00332 
00333 // ========================================================================
00334 template <typename INT>
00335 void process_nodesets(Ioss::Region &region, stk_classic::mesh::BulkData &bulk, INT /*dummy*/)
00336 {
00337   // Should only process nodes that have already been defined via the element
00338   // blocks connectivity lists.
00339   const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
00340   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00341 
00342   for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
00343       it != node_sets.end(); ++it) {
00344     Ioss::NodeSet *entity = *it;
00345 
00346     if (stk_classic::io::include_entity(entity)) {
00347       const std::string & name = entity->name();
00348       stk_classic::mesh::Part* const part = fem_meta.get_part(name);
00349       assert(part != NULL);
00350       stk_classic::mesh::PartVector add_parts( 1 , part );
00351 
00352       std::vector<INT> node_ids ;
00353       size_t node_count = entity->get_field_data("ids", node_ids);
00354 
00355       std::vector<stk_classic::mesh::Entity*> nodes(node_count);
00356       stk_classic::mesh::EntityRank n_rank = fem_meta.node_rank();
00357       for(size_t i=0; i<node_count; ++i) {
00358         nodes[i] = bulk.get_entity(n_rank, node_ids[i] );
00359         if (nodes[i] != NULL)
00360           bulk.declare_entity(n_rank, node_ids[i], add_parts );
00361       }
00362 
00363       stk_classic::mesh::Field<double> *df_field =
00364         fem_meta.get_field<stk_classic::mesh::Field<double> >("distribution_factors");
00365 
00366       if (df_field != NULL) {
00367         stk_classic::io::field_data_from_ioss(df_field, nodes, entity, "distribution_factors");
00368       }
00369 
00370       // Add all attributes as fields.
00371       // If the only attribute is 'attribute', then add it; otherwise the other attributes are the
00372       // named components of the 'attribute' field, so add them instead.
00373       Ioss::NameList names;
00374       entity->field_describe(Ioss::Field::ATTRIBUTE, &names);
00375       for(Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
00376         if(*I == "attribute" && names.size() > 1)
00377           continue;
00378         stk_classic::mesh::FieldBase *field = fem_meta.get_field<stk_classic::mesh::FieldBase> (*I);
00379         if (field)
00380           stk_classic::io::field_data_from_ioss(field, nodes, entity, *I);
00381       }
00382     }
00383   }
00384 }
00385 
00386 // ========================================================================
00387 void process_sidesets(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00388 {
00389   const Ioss::SideSetContainer& side_sets = region.get_sidesets();
00390 
00391   for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
00392       it != side_sets.end(); ++it) {
00393     Ioss::SideSet *entity = *it;
00394 
00395     if (stk_classic::io::include_entity(entity)) {
00396       process_surface_entity(entity, bulk);
00397     }
00398   }
00399 }
00400 
00401 // ========================================================================
00402 void put_field_data(stk_classic::mesh::BulkData &bulk, stk_classic::mesh::Part &part,
00403                     stk_classic::mesh::EntityRank part_type,
00404                     Ioss::GroupingEntity *io_entity,
00405                     Ioss::Field::RoleType filter_role,
00406         const stk_classic::mesh::Selector *anded_selector=NULL)
00407 {
00408   std::vector<stk_classic::mesh::Entity*> entities;
00409   if (io_entity->type() == Ioss::SIDEBLOCK) {
00410     // Temporary Kluge to handle sideblocks which contain internally generated sides
00411     // where the "ids" field on the io_entity doesn't work to get the correct side...
00412     // NOTE: Could use this method for all entity types, but then need to correctly 
00413     // specify whether shared entities are included/excluded (See IossBridge version).
00414     size_t num_sides = get_entities(part, bulk, entities, anded_selector);
00415     if (num_sides != (size_t)io_entity->get_property("entity_count").get_int()) {
00416       std::ostringstream msg ;
00417       msg << " INTERNAL_ERROR: Number of sides on part " << part.name() << " (" << num_sides
00418     << ") does not match number of sides in the associated Ioss SideBlock named "
00419     << io_entity->name() << " (" << io_entity->get_property("entity_count").get_int()
00420     << ").";
00421         throw std::runtime_error( msg.str() );
00422     }
00423   } else {
00424     stk_classic::io::get_entity_list(io_entity, part_type, bulk, entities);
00425   }
00426 
00427   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00428   const std::vector<stk_classic::mesh::FieldBase*> &fields = fem_meta.get_fields();
00429 
00430   std::vector<stk_classic::mesh::FieldBase *>::const_iterator I = fields.begin();
00431   while (I != fields.end()) {
00432     const stk_classic::mesh::FieldBase *f = *I; ++I;
00433     stk_classic::io::field_data_to_ioss(f, entities, io_entity, f->name(), filter_role);
00434   }
00435 }
00436 
00437 void internal_process_output_request(stk_classic::io::MeshData &mesh_data,
00438                                      stk_classic::mesh::BulkData &bulk,
00439                                      int step,
00440                                      const std::set<const stk_classic::mesh::Part*> &exclude)
00441 {
00442   Ioss::Region *region = mesh_data.m_output_region;
00443   region->begin_state(step);
00444   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00445 
00446   // Special processing for nodeblock (all nodes in model)...
00447   put_field_data(bulk, fem_meta.universal_part(), fem_meta.node_rank(),
00448                  region->get_node_blocks()[0], Ioss::Field::Field::TRANSIENT,
00449      mesh_data.m_anded_selector);
00450 
00451   // Now handle all non-nodeblock parts...
00452   const stk_classic::mesh::PartVector & all_parts = fem_meta.get_parts();
00453   for ( stk_classic::mesh::PartVector::const_iterator
00454           ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
00455 
00456     stk_classic::mesh::Part * const part = *ip;
00457 
00458     // Check whether this part should be output to results database.
00459     if (stk_classic::io::is_part_io_part(*part) && !exclude.count(part)) {
00460       // Get Ioss::GroupingEntity corresponding to this part...
00461       Ioss::GroupingEntity *entity = region->get_entity(part->name());
00462       if (entity != NULL && entity->type() != Ioss::SIDESET) {
00463         put_field_data(bulk, *part, stk_classic::io::part_primary_entity_rank(*part),
00464                        entity, Ioss::Field::Field::TRANSIENT,
00465            mesh_data.m_anded_selector);
00466       }
00467     }
00468   }
00469   region->end_state(step);
00470 }
00471 
00472 namespace stk_classic {
00473 namespace io {
00474 
00475 MeshData::~MeshData()
00476 {
00477   delete m_input_region;
00478   delete m_output_region;
00479 }
00480 
00481 void show_mesh_help()
00482 {
00483   std::cerr << "Options are:\n"
00484             << "\n"
00485             << "filename -- specify the name of the file from which to read the\n"
00486             << "            mesh file. If the --directory option is specified, it will be\n"
00487             << "            prepended to the filename unless the filename specifies an absolute path.\n"
00488             << "\n"
00489             << "gen:NxMxL -- internally generate a hex mesh of size N by M by L\n"
00490             << "             intervals. See 'Generated Options' below for more options.\n"
00491             << "\n"
00492             << "Generated Options:\n"
00493             << "shell:xXyYzZ\n"
00494             << "The argument specifies whether there is a shell block\n"
00495             << "at the location. 'x' is minX, 'X' is maxX, etc.\n"
00496             << "\n"
00497             << "help -- no argument, shows valid options\n"
00498             << "\n"
00499             << "show -- no argument, prints out a summary of the settings used to\n"
00500             << "generate the mesh. The output will look similar to:\n"
00501             << "    \"10x12x8|shell:xX|bbox:-10,-10,-10,10,10,10|show\"\n"
00502             << "\n"
00503             << "    Mesh Parameters:\n"
00504             << "\tIntervals: 10 by 12 by 8\n"
00505             << "\tX = 2       * (0..10) + -10     Range: -10 <= X <= 10\n"
00506             << "\tY = 1.66667 * (0..12) + -10     Range: -10 <= Y <= 10\n"
00507             << "\tZ = 2.5     * (0..8)  + -10     Range: -10 <= Z <= 10\n"
00508             << "\tNode Count (total)    = 1287\n"
00509             << "\tElement Count (total) = 1152\n"
00510             << "\tBlock Count           = 3\n"
00511             << "\n"
00512             << "shell:xXyYzZ \n"
00513             << "which specifies whether there is a shell block at that\n"
00514             << "location. 'x' is minimum x face, 'X' is maximum x face,\n"
00515             << "similarly for y and z.  Note that the argument string is a\n"
00516             << "single multicharacter string.  You can add multiple shell blocks\n"
00517             << "to a face, for example, shell:xxx would add three layered shell\n"
00518             << "blocks on the minimum x face.  An error is output if a non\n"
00519             << "xXyYzZ character is found, but execution continues.\n"
00520             << "\n"
00521             << "zdecomp:n0 n1,n2,...,n#proc-1\n"
00522             << "which are the number of intervals in the z direction for each\n"
00523             << "processor in a pallel run.  If this option is specified, then\n"
00524             << "the total number of intervals in the z direction is the sum of\n"
00525             << "the n0, n1, ... An interval count must be specified for each\n"
00526             << "processor.  If this option is not specified, then the number of\n"
00527             << "intervals on each processor in the z direction is numZ/numProc\n"
00528             << "with the extras added to the lower numbered processors.\n"
00529             << "\n"
00530             << "scale:xs,ys,zs\n"
00531             << "which are the scale factors in the x, y, and z directions. All\n"
00532             << "three must be specified if this option is present.\n"
00533             << "\n"
00534             << "- offset -- argument = xoff, yoff, zoff which are the offsets in the\n"
00535             << "x, y, and z directions.  All three must be specified if this option\n"
00536             << "is present.\n"
00537             << "\n"
00538             << "- bbox -- argument = xmin, ymin, zmin, xmax, ymax, zmax\n"
00539             << "which specify the lower left and upper right corners of\n"
00540             << "the bounding box for the generated mesh.  This will\n"
00541             << "calculate the scale and offset which will fit the mesh in\n"
00542             << "the specified box.  All calculations are based on the currently\n"
00543             << "active interval settings. If scale or offset or zdecomp\n"
00544             << "specified later in the option list, you may not get the\n"
00545             << "desired bounding box.\n"
00546             << "\n"
00547             << "- rotate -- argument = axis,angle,axis,angle,...\n"
00548             << "where axis is 'x', 'y', or 'z' and angle is the rotation angle in\n"
00549             << "degrees. Multiple rotations are cumulative. The composite rotation\n"
00550             << "matrix is applied at the time the coordinates are retrieved after\n"
00551             << "scaling and offset are applied.\n"
00552             << "\n"
00553             << "The unrotated coordinate of a node at grid location i,j,k is:\n"
00554             << "\n"
00555             << "\tx = x_scale * i + x_off,\n"
00556             << "\ty = z_scale * j + y_off,\n"
00557             << "\tz = z_scale * k + z_off,\n"
00558             << "\n"
00559             << "The extent of the unrotated mesh will be:\n"
00560             << "\n"
00561             << "\tx_off <= x <= x_scale * numX + x_off\n"
00562             << "\ty_off <= y <= y_scale * numY + y_off\n"
00563             << "\tz_off <= z <= z_scale * numZ + z_off\n"
00564             << "\n"
00565             << "If an unrecognized option is specified, an error message will be\n"
00566             << "output and execution will continue.\n"
00567             << "\n"
00568             << "An example of valid input is:\n"
00569             << "\n"
00570             << "\t\"10x20x40|scale:1,0.5,0.25|offset:-5,-5,-5|shell:xX\"\n"
00571             << "\n"
00572             << "\n"
00573             << "This would create a mesh with 10 intervals in x, 20 in y, 40 in z\n"
00574             << "The mesh would be centered on 0,0,0 with a range of 10 in each\n"
00575             << "direction. There would be a shell layer on the min and max\n"
00576             << "x faces.\n"
00577             << "\n"
00578             << "NOTE: All options are processed in the order they appear in\n"
00579             << "the parameters string (except rotate which is applied at the\n"
00580             << "time the coordinates are generated/retrieved)\n"
00581             << "\n";
00582 }
00583 
00584 void create_input_mesh(const std::string &mesh_type,
00585                        const std::string &mesh_filename,
00586                        stk_classic::ParallelMachine comm,
00587                        stk_classic::mesh::fem::FEMMetaData &fem_meta,
00588                        stk_classic::io::MeshData &mesh_data,
00589                        bool lower_case_variable_names)
00590 {
00591   Ioss::Region *in_region = mesh_data.m_input_region;
00592   if (in_region == NULL) {
00593   // If in_region is NULL, then open the file;
00594   // If in_region is non-NULL, then user has given us a valid Ioss::Region that
00595   // should be used.
00596   Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(mesh_type, mesh_filename,
00597                                                     Ioss::READ_MODEL, comm,
00598                                                     mesh_data.m_property_manager);
00599 
00600         // set up the casing for variable names
00601         dbi->set_lower_case_variable_names(lower_case_variable_names);
00602 
00603   if (dbi == NULL || !dbi->ok()) {
00604     std::cerr  << "ERROR: Could not open database '" << mesh_filename
00605                  << "' of type '" << mesh_type << "'\n";
00606     Ioss::NameList db_types;
00607     Ioss::IOFactory::describe(&db_types);
00608     std::cerr << "\nSupported database types:\n\t";
00609     for (Ioss::NameList::const_iterator IF = db_types.begin(); IF != db_types.end(); ++IF) {
00610       std::cerr << *IF << "  ";
00611     }
00612     std::cerr << "\n\n";
00613   }
00614 
00615   // NOTE: 'in_region' owns 'dbi' pointer at this time...
00616   in_region = new Ioss::Region(dbi, "input_model");
00617   mesh_data.m_input_region = in_region;
00618   }
00619 
00620   size_t spatial_dimension = in_region->get_property("spatial_dimension").get_int();
00621   initialize_spatial_dimension(fem_meta, spatial_dimension, stk_classic::mesh::fem::entity_rank_names(spatial_dimension));
00622 
00623   process_elementblocks(*in_region, fem_meta);
00624   process_nodeblocks(*in_region,    fem_meta);
00625   process_sidesets(*in_region,      fem_meta);
00626   process_nodesets(*in_region,      fem_meta);
00627 }
00628 
00629 void create_input_mesh(const std::string &mesh_type,
00630                        const std::string &mesh_filename,
00631                        stk_classic::ParallelMachine comm,
00632                        stk_classic::mesh::fem::FEMMetaData &fem_meta,
00633                        stk_classic::io::MeshData &mesh_data,
00634                        const std::vector<std::string>& names_to_add,
00635                        bool lower_case_variable_names)
00636 {
00637   Ioss::Region *in_region = mesh_data.m_input_region;
00638   if (in_region == NULL) {
00639   // If in_region is NULL, then open the file;
00640   // If in_region is non-NULL, then user has given us a valid Ioss::Region that
00641   // should be used.
00642   Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(mesh_type, mesh_filename,
00643                                                     Ioss::READ_MODEL, comm,
00644                                                     mesh_data.m_property_manager);
00645 
00646         // set up the casing for variable names
00647         dbi->set_lower_case_variable_names(lower_case_variable_names);
00648 
00649   if (dbi == NULL || !dbi->ok()) {
00650     std::cerr  << "ERROR: Could not open database '" << mesh_filename
00651                  << "' of type '" << mesh_type << "'\n";
00652     Ioss::NameList db_types;
00653     Ioss::IOFactory::describe(&db_types);
00654     std::cerr << "\nSupported database types:\n\t";
00655     for (Ioss::NameList::const_iterator IF = db_types.begin(); IF != db_types.end(); ++IF) {
00656       std::cerr << *IF << "  ";
00657     }
00658     std::cerr << "\n\n";
00659   }
00660 
00661   // NOTE: 'in_region' owns 'dbi' pointer at this time...
00662   in_region = new Ioss::Region(dbi, "input_model");
00663   mesh_data.m_input_region = in_region;
00664   }
00665 
00666   size_t spatial_dimension = in_region->get_property("spatial_dimension").get_int();
00667 
00668   std::vector<std::string> entity_rank_names = stk_classic::mesh::fem::entity_rank_names(spatial_dimension);
00669 
00670   for(std::size_t i = 0; i < names_to_add.size(); i++)
00671     entity_rank_names.push_back(names_to_add[i]);
00672 
00673   initialize_spatial_dimension(fem_meta, spatial_dimension, entity_rank_names);
00674 
00675   process_elementblocks(*in_region, fem_meta);
00676   process_nodeblocks(*in_region,    fem_meta);
00677   process_sidesets(*in_region,      fem_meta);
00678   process_nodesets(*in_region,      fem_meta);
00679 }
00680 
00681 
00682 void create_output_mesh(const std::string &filename,
00683                         stk_classic::ParallelMachine comm,
00684                         stk_classic::mesh::BulkData &bulk_data,
00685                         MeshData &mesh_data,
00686                        bool lower_case_variable_names)
00687 {
00688   Ioss::Region *out_region = NULL;
00689 
00690   std::string out_filename = filename;
00691   if (filename.empty()) {
00692   out_filename = "default_output_mesh";
00693   } else {
00694   // These filenames may be coming from the generated options which
00695   // may have forms similar to: "2x2x1|size:.05|height:-0.1,1"
00696   // Strip the name at the first "+:|," character:
00697   std::vector<std::string> tokens;
00698   stk_classic::util::tokenize(out_filename, "+|:,", tokens);
00699   out_filename = tokens[0];
00700   }
00701 
00702   Ioss::DatabaseIO *dbo = Ioss::IOFactory::create("exodusII", out_filename,
00703                                                   Ioss::WRITE_RESULTS,
00704                                                   comm, mesh_data.m_property_manager);
00705   // set up the casing for variable names
00706   dbo->set_lower_case_variable_names(lower_case_variable_names);
00707 
00708   if (dbo == NULL || !dbo->ok()) {
00709   std::cerr << "ERROR: Could not open results database '" << out_filename
00710               << "' of type 'exodusII'\n";
00711   std::exit(EXIT_FAILURE);
00712   }
00713 
00714   // NOTE: 'out_region' owns 'dbo' pointer at this time...
00715   out_region = new Ioss::Region(dbo, "results_output");
00716 
00717   stk_classic::io::define_output_db(*out_region, bulk_data, mesh_data.m_input_region, mesh_data.m_anded_selector);
00718   stk_classic::io::write_output_db(*out_region,  bulk_data, mesh_data.m_anded_selector);
00719   mesh_data.m_output_region = out_region;
00720 }
00721 
00722 // ========================================================================
00723 int process_output_request(MeshData &mesh_data,
00724                            stk_classic::mesh::BulkData &bulk,
00725                            double time,
00726                            const std::set<const stk_classic::mesh::Part*> &exclude)
00727 {
00728   Ioss::Region *region = mesh_data.m_output_region;
00729   region->begin_mode(Ioss::STATE_TRANSIENT);
00730 
00731   int out_step = region->add_state(time);
00732   internal_process_output_request(mesh_data, bulk, out_step,exclude);
00733 
00734   region->end_mode(Ioss::STATE_TRANSIENT);
00735 
00736   return out_step;
00737 }
00738 
00739 // ========================================================================
00740 void populate_bulk_data(stk_classic::mesh::BulkData &bulk_data,
00741                         MeshData &mesh_data)
00742 {
00743   Ioss::Region *region = mesh_data.m_input_region;
00744 
00745   if (region) {
00746 
00747     bulk_data.modification_begin();
00748     process_mesh_bulk_data(region, bulk_data);
00749     bulk_data.modification_end();
00750 
00751   } else {
00752   std::cerr << "INTERNAL ERROR: Mesh Input Region pointer is NULL in populate_bulk_data.\n";
00753   std::exit(EXIT_FAILURE);
00754   }
00755 }
00756 
00757 // ========================================================================
00758 void process_mesh_bulk_data(Ioss::Region *region, stk_classic::mesh::BulkData &bulk_data)
00759 {
00760     bool ints64bit = db_api_int_size(region) == 8;
00761     if (ints64bit) {
00762       int64_t zero = 0;
00763       process_elementblocks(*region, bulk_data, zero);
00764       process_nodeblocks(*region,    bulk_data);
00765       process_nodesets(*region,      bulk_data, zero);
00766       process_sidesets(*region,      bulk_data);
00767     } else {
00768       int zero = 0;
00769       process_elementblocks(*region, bulk_data, zero);
00770       process_nodeblocks(*region,    bulk_data);
00771       process_nodesets(*region,      bulk_data, zero);
00772       process_sidesets(*region,      bulk_data);
00773     }
00774 }
00775 
00776 namespace {
00777 // ========================================================================
00778 // Transfer transient field data from mesh file for io_entity to
00779 // the corresponding stk_mesh entities If there is a stk_mesh
00780 // field with the same name as the database field.
00781 // Assumes that mesh is positioned at the correct state for reading.
00782 void internal_process_input_request(Ioss::GroupingEntity *io_entity,
00783                                     stk_classic::mesh::EntityRank entity_rank,
00784                                     stk_classic::mesh::BulkData &bulk)
00785 {
00786   assert(io_entity != NULL);
00787   std::vector<stk_classic::mesh::Entity*> entity_list;
00788   stk_classic::io::get_entity_list(io_entity, entity_rank, bulk, entity_list);
00789 
00790   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00791 
00792   Ioss::NameList names;
00793   io_entity->field_describe(Ioss::Field::TRANSIENT, &names);
00794   for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
00795     stk_classic::mesh::FieldBase *field = fem_meta.get_field<stk_classic::mesh::FieldBase>(*I);
00796     if (field) {
00797       stk_classic::io::field_data_from_ioss(field, entity_list, io_entity, *I);
00798     }
00799   }
00800 }
00801 
00802 void input_nodeblock_fields(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00803 {
00804   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00805   const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
00806   assert(node_blocks.size() == 1);
00807 
00808   Ioss::NodeBlock *nb = node_blocks[0];
00809   internal_process_input_request(nb, fem_meta.node_rank(), bulk);
00810 }
00811 
00812 void input_elementblock_fields(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00813 {
00814   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00815   const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
00816   for(size_t i=0; i < elem_blocks.size(); i++) {
00817     if (stk_classic::io::include_entity(elem_blocks[i])) {
00818       internal_process_input_request(elem_blocks[i], fem_meta.element_rank(), bulk);
00819     }
00820   }
00821 }
00822 
00823 void input_nodeset_fields(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00824 {
00825   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00826   const Ioss::NodeSetContainer& nodesets = region.get_nodesets();
00827   for(size_t i=0; i < nodesets.size(); i++) {
00828     if (stk_classic::io::include_entity(nodesets[i])) {
00829       internal_process_input_request(nodesets[i], fem_meta.node_rank(), bulk);
00830     }
00831   }
00832 }
00833 
00834 void input_sideset_fields(Ioss::Region &region, stk_classic::mesh::BulkData &bulk)
00835 {
00836   const stk_classic::mesh::fem::FEMMetaData &fem_meta = stk_classic::mesh::fem::FEMMetaData::get(bulk);
00837   if (fem_meta.spatial_dimension() <= fem_meta.side_rank())
00838     return;
00839 
00840   const Ioss::SideSetContainer& side_sets = region.get_sidesets();
00841   for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
00842       it != side_sets.end(); ++it) {
00843     Ioss::SideSet *entity = *it;
00844     if (stk_classic::io::include_entity(entity)) {
00845       const Ioss::SideBlockContainer& blocks = entity->get_side_blocks();
00846       for(size_t i=0; i < blocks.size(); i++) {
00847         if (stk_classic::io::include_entity(blocks[i])) {
00848           internal_process_input_request(blocks[i], fem_meta.side_rank(), bulk);
00849         }
00850       }
00851     }
00852   }
00853 }
00854 
00855 void define_input_nodeblock_fields(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00856 {
00857   const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
00858   assert(node_blocks.size() == 1);
00859 
00860   Ioss::NodeBlock *nb = node_blocks[0];
00861   stk_classic::io::define_io_fields(nb, Ioss::Field::TRANSIENT,
00862                             fem_meta.universal_part(), fem_meta.node_rank());
00863 }
00864 
00865 void define_input_elementblock_fields(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00866 {
00867   const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
00868   for(size_t i=0; i < elem_blocks.size(); i++) {
00869     if (stk_classic::io::include_entity(elem_blocks[i])) {
00870       stk_classic::mesh::Part* const part = fem_meta.get_part(elem_blocks[i]->name());
00871       assert(part != NULL);
00872       stk_classic::io::define_io_fields(elem_blocks[i], Ioss::Field::TRANSIENT,
00873                                 *part, part_primary_entity_rank(*part));
00874     }
00875   }
00876 }
00877 
00878 void define_input_nodeset_fields(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00879 {
00880   const Ioss::NodeSetContainer& nodesets = region.get_nodesets();
00881   for(size_t i=0; i < nodesets.size(); i++) {
00882     if (stk_classic::io::include_entity(nodesets[i])) {
00883       stk_classic::mesh::Part* const part = fem_meta.get_part(nodesets[i]->name());
00884       assert(part != NULL);
00885       stk_classic::io::define_io_fields(nodesets[i], Ioss::Field::TRANSIENT,
00886                                 *part, part_primary_entity_rank(*part));
00887     }
00888   }
00889 }
00890 
00891 void define_input_sideset_fields(Ioss::Region &region, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00892 {
00893   if (fem_meta.spatial_dimension() <= fem_meta.side_rank())
00894     return;
00895 
00896   const Ioss::SideSetContainer& side_sets = region.get_sidesets();
00897   for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
00898       it != side_sets.end(); ++it) {
00899     Ioss::SideSet *entity = *it;
00900     if (stk_classic::io::include_entity(entity)) {
00901       const Ioss::SideBlockContainer& blocks = entity->get_side_blocks();
00902       for(size_t i=0; i < blocks.size(); i++) {
00903         if (stk_classic::io::include_entity(blocks[i])) {
00904           stk_classic::mesh::Part* const part = fem_meta.get_part(blocks[i]->name());
00905           assert(part != NULL);
00906           stk_classic::io::define_io_fields(blocks[i], Ioss::Field::TRANSIENT,
00907                                     *part, part_primary_entity_rank(*part));
00908         }
00909       }
00910     }
00911   }
00912 }
00913 
00914 }
00915 
00916 // ========================================================================
00917 // Iterate over all Ioss entities in the input mesh database and
00918 // define a stk_field for all transient fields found.  The stk
00919 // field will have the same name as the field on the database.
00920 //
00921 // Note that all fields found on the database will have a
00922 // corresponding stk field defined.  If you want just a selected
00923 // subset of the defined fields, you will need to define the
00924 // fields manually.
00925 //
00926 // To populate the stk field with data from the database, call
00927 // process_input_request().
00928 void define_input_fields(MeshData &mesh_data, stk_classic::mesh::fem::FEMMetaData &fem_meta)
00929 {
00930   Ioss::Region *region = mesh_data.m_input_region;
00931   if (region) {
00932   define_input_nodeblock_fields(*region, fem_meta);
00933   define_input_elementblock_fields(*region, fem_meta);
00934   define_input_nodeset_fields(*region, fem_meta);
00935   define_input_sideset_fields(*region, fem_meta);
00936   } else {
00937   std::cerr << "INTERNAL ERROR: Mesh Input Region pointer is NULL in process_input_request.\n";
00938   std::exit(EXIT_FAILURE);
00939   }
00940 }
00941 
00942 // ========================================================================
00943 // Iterate over all fields defined in the stk mesh data structure.
00944 // If the field has the io_attribute set, then define that field
00945 // on the corresponding io entity on the output mesh database.
00946 // The database field will have the same name as the stk field.
00947 //
00948 // To export the data to the database, call
00949 // process_output_request().
00950 
00951 void define_output_fields(const MeshData &mesh_data, const stk_classic::mesh::fem::FEMMetaData &fem_meta,
00952                           bool add_all_fields)
00953 {
00954   Ioss::Region *region = mesh_data.m_output_region;
00955   if (region) {
00956   region->begin_mode(Ioss::STATE_DEFINE_TRANSIENT);
00957 
00958   // Special processing for nodeblock (all nodes in model)...
00959   stk_classic::io::ioss_add_fields(fem_meta.universal_part(), fem_meta.node_rank(),
00960                              region->get_node_blocks()[0],
00961                              Ioss::Field::TRANSIENT, add_all_fields);
00962 
00963   const stk_classic::mesh::PartVector & all_parts = fem_meta.get_parts();
00964   for ( stk_classic::mesh::PartVector::const_iterator
00965             ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {
00966 
00967     stk_classic::mesh::Part * const part = *ip;
00968 
00969     // Check whether this part should be output to results database.
00970     if (stk_classic::io::is_part_io_part(*part)) {
00971       // Get Ioss::GroupingEntity corresponding to this part...
00972       Ioss::GroupingEntity *entity = region->get_entity(part->name());
00973       if (entity != NULL) {
00974         stk_classic::io::ioss_add_fields(*part, part_primary_entity_rank(*part),
00975                                    entity, Ioss::Field::TRANSIENT, add_all_fields);
00976       }
00977     }
00978   }
00979   region->end_mode(Ioss::STATE_DEFINE_TRANSIENT);
00980   } else {
00981   std::cerr << "INTERNAL ERROR: Mesh Input Region pointer is NULL in process_input_request.\n";
00982   std::exit(EXIT_FAILURE);
00983   }
00984 }
00985 // ========================================================================
00986 void process_input_request(MeshData &mesh_data, stk_classic::mesh::BulkData &bulk, double time)
00987 {
00988   // Find the step on the database with time closest to the requested time...
00989   Ioss::Region *region = mesh_data.m_input_region;
00990   int step_count = region->get_property("state_count").get_int();
00991   double delta_min = 1.0e30;
00992   int    step_min  = 0;
00993   for (int istep = 0; istep < step_count; istep++) {
00994   double state_time = region->get_state_time(istep+1);
00995   double delta = state_time - time;
00996   if (delta < 0.0) delta = -delta;
00997   if (delta < delta_min) {
00998     delta_min = delta;
00999     step_min  = istep;
01000     if (delta == 0.0) break;
01001   }
01002   }
01003   // Exodus steps are 1-based;
01004   process_input_request(mesh_data, bulk, step_min+1);
01005 }
01006 
01007 void process_input_request(MeshData &mesh_data,
01008                            stk_classic::mesh::BulkData &bulk,
01009                            int step)
01010 {
01011   if (step <= 0)
01012   return;
01013 
01014   Ioss::Region *region = mesh_data.m_input_region;
01015   if (region) {
01016   bulk.modification_begin();
01017 
01018   input_mesh_fields(region, bulk, step);
01019 
01020   bulk.modification_end();
01021 
01022   } else {
01023   std::cerr << "INTERNAL ERROR: Mesh Input Region pointer is NULL in process_input_request.\n";
01024   std::exit(EXIT_FAILURE);
01025   }
01026 }
01027 
01028 void input_mesh_fields(Ioss::Region *region, stk_classic::mesh::BulkData &bulk,
01029                            double time)
01030 {
01031   // Find the step on the database with time closest to the requested time...
01032   int step_count = region->get_property("state_count").get_int();
01033   double delta_min = 1.0e30;
01034   int    step_min  = 0;
01035   for (int istep = 0; istep < step_count; istep++) {
01036   double state_time = region->get_state_time(istep+1);
01037   double delta = state_time - time;
01038   if (delta < 0.0) delta = -delta;
01039   if (delta < delta_min) {
01040     delta_min = delta;
01041     step_min  = istep;
01042     if (delta == 0.0) break;
01043   }
01044   }
01045   // Exodus steps are 1-based;
01046   input_mesh_fields(region, bulk, step_min+1);
01047 }
01048 
01049 void input_mesh_fields(Ioss::Region *region, stk_classic::mesh::BulkData &bulk,
01050                            int step)
01051 {
01052   // Pick which time index to read into solution field.
01053   region->begin_state(step);
01054 
01055   input_nodeblock_fields(*region, bulk);
01056   input_elementblock_fields(*region, bulk);
01057   input_nodeset_fields(*region, bulk);
01058   input_sideset_fields(*region, bulk);
01059 
01060   region->end_state(step);
01061 }
01062 
01063 // ========================================================================
01064 template <typename INT>
01065 void get_element_block_sizes(MeshData &mesh_data,
01066                              std::vector<INT>& el_blocks)
01067 {
01068   Ioss::Region *io = mesh_data.m_input_region;
01069   const Ioss::ElementBlockContainer& elem_blocks = io->get_element_blocks();
01070   for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); it != elem_blocks.end(); ++it) {
01071     Ioss::ElementBlock *entity = *it;
01072     if (stk_classic::io::include_entity(entity)) {
01073       el_blocks.push_back(entity->get_property("entity_count").get_int());
01074     }
01075   }
01076 }
01077 template void get_element_block_sizes(MeshData &mesh_data, std::vector<int>& el_blocks);
01078 template void get_element_block_sizes(MeshData &mesh_data, std::vector<int64_t>& el_blocks);
01079 } // namespace io
01080 } // namespace stk_classic
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines