void extract_sideset_data_from_io(std::vector<IdAndSideSet> &sidesetData) { stk::mesh::BulkData &bulk = this->bulk_data(); Ioss::Region *region = m_input_files[m_active_mesh_index]->get_input_io_region().get(); for ( const Ioss::SideSet * sset : region->get_sidesets() ) add_ioss_sideset_to_stk_sideset_with_sideset_id(bulk, sset, sidesetData); }
void process_input_request(Ioss::Region ®ion, stk::mesh::BulkData &bulk, int step) { region.begin_state(step); // Special processing for nodeblock (all nodes in model)... const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); // ??? Get field data from nodeblock... get_field_data(bulk, meta.universal_part(), stk::topology::NODE_RANK, region.get_node_blocks()[0], Ioss::Field::TRANSIENT); const stk::mesh::PartVector & all_parts = meta.get_parts(); for ( stk::mesh::PartVector::const_iterator ip = all_parts.begin(); ip != all_parts.end(); ++ip ) { stk::mesh::Part * const part = *ip; const stk::mesh::EntityRank part_rank = part->primary_entity_rank(); // Check whether this part should be output to results database. if (stk::io::is_part_io_part(*part)) { // Get Ioss::GroupingEntity corresponding to this part... Ioss::GroupingEntity *entity = region.get_entity(part->name()); if (entity != NULL) { if (entity->type() == Ioss::SIDESET) { Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity); assert(sset != NULL); int block_count = sset->block_count(); for (int i=0; i < block_count; i++) { Ioss::SideBlock *side_block = sset->get_block(i); /// \todo REFACTOR Need filtering mechanism. get_field_data(bulk, *part, part_rank, side_block, Ioss::Field::TRANSIENT); } } else { get_field_data(bulk, *part, part_rank, entity, Ioss::Field::TRANSIENT); } } else { /// \todo IMPLEMENT handle error... Possibly an assert since /// I think the corresponding entity should always exist... } } } region.end_state(step); }
// ======================================================================== // Bulk Data // ======================================================================== void process_nodeblocks(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { // This must be called after the "process_element_blocks" call // since there may be nodes that exist in the database that are // not part of the analysis mesh due to subsetting of the element // blocks. const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks(); assert(node_blocks.size() == 1); Ioss::NodeBlock *nb = node_blocks[0]; std::vector<stk::mesh::Entity> nodes; stk::io::get_entity_list(nb, stk::topology::NODE_RANK, bulk, nodes); /** \todo REFACTOR Application would probably store this field * (and others) somewhere after the declaration instead of * looking it up each time it is needed. */ const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); stk::mesh::Field<double,stk::mesh::Cartesian> *coord_field = meta.get_field<stk::mesh::Field<double,stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates"); stk::io::field_data_from_ioss(bulk, coord_field, nodes, nb, "mesh_model_coordinates"); }
// ======================================================================== void process_elementblocks(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); it != elem_blocks.end(); ++it) { Ioss::ElementBlock *entity = *it; if (stk::io::include_entity(entity)) { const std::string &name = entity->name(); const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); stk::mesh::Part* const part = meta.get_part(name); STKIORequire(part != NULL); const stk::topology topo = part->topology(); if (topo == stk::topology::INVALID_TOPOLOGY) { std::ostringstream msg ; msg << " INTERNAL_ERROR: Part " << part->name() << " returned INVALID from get_topology()"; throw std::runtime_error( msg.str() ); } std::vector<int> elem_ids ; std::vector<int> connectivity ; entity->get_field_data("ids", elem_ids); entity->get_field_data("connectivity", connectivity); size_t element_count = elem_ids.size(); int nodes_per_elem = topo.num_nodes(); stk::mesh::EntityIdVector connectivity2(nodes_per_elem); std::vector<int>::const_iterator connBegin = connectivity.begin(); std::vector<stk::mesh::Entity> elements(element_count); for(size_t i=0; i<element_count; ++i, connBegin += nodes_per_elem) { std::copy(connBegin, connBegin + nodes_per_elem, connectivity2.begin()); elements[i] = stk::mesh::declare_element(bulk, *part, elem_ids[i], connectivity2); } // For this example, we are just taking all attribute fields // found on the io database and populating fields on the // corresponding mesh part. In practice, would probably be // selective about which attributes to use... Ioss::NameList names; entity->field_describe(Ioss::Field::ATTRIBUTE, &names); for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) { if (*I == "attribute" && names.size() > 1) continue; stk::mesh::FieldBase *field = meta.get_field<stk::mesh::FieldBase>(stk::topology::ELEMENT_RANK, *I); stk::io::field_data_from_ioss(bulk, field, elements, entity, *I); } } } }
// ======================================================================== void process_sidesets(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { const Ioss::SideSetContainer& side_sets = region.get_sidesets(); for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); it != side_sets.end(); ++it) { Ioss::SideSet *entity = *it; if (stk::io::include_entity(entity)) { process_surface_entity(entity, bulk); } } }
// ======================================================================== void process_sidesets(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const stk::mesh::EntityRank side_rank = meta.side_rank(); const Ioss::SideSetContainer& side_sets = region.get_sidesets(); stk::io::default_part_processing(side_sets, meta, side_rank); for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); it != side_sets.end(); ++it) { Ioss::SideSet *entity = *it; if (stk::io::include_entity(entity)) { process_surface_entity(entity, meta, side_rank); } } }
// ======================================================================== void process_nodesets(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { // Should only process nodes that have already been defined via the element // blocks connectivity lists. const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); it != node_sets.end(); ++it) { Ioss::NodeSet *entity = *it; if (stk::io::include_entity(entity)) { const std::string & name = entity->name(); const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); stk::mesh::Part* const part = meta.get_part(name); STKIORequire(part != NULL); stk::mesh::PartVector add_parts( 1 , part ); std::vector<int> node_ids ; int node_count = entity->get_field_data("ids", node_ids); std::vector<stk::mesh::Entity> nodes(node_count); for(int i=0; i<node_count; ++i) { nodes[i] = bulk.get_entity( stk::topology::NODE_RANK, node_ids[i] ); if (bulk.is_valid(nodes[i])) { bulk.declare_entity(stk::topology::NODE_RANK, node_ids[i], add_parts ); } } /** \todo REFACTOR Application would probably store this field * (and others) somewhere after the declaration instead of * looking it up each time it is needed. */ stk::mesh::Field<double> *df_field = meta.get_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors"); if (df_field != NULL) { stk::io::field_data_from_ioss(bulk, df_field, nodes, entity, "distribution_factors"); } } } }
// ======================================================================== void process_nodesets(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); stk::io::default_part_processing(node_sets, meta, stk::topology::NODE_RANK); /** \todo REFACTOR should "distribution_factor" be a default field * that is automatically declared on all objects that it exists * on as is done in current framework? */ stk::mesh::Field<double> & distribution_factors_field = meta.declare_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors"); /** \todo REFACTOR How to associate distribution_factors field * with the nodeset part if a node is a member of multiple * nodesets */ for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); it != node_sets.end(); ++it) { Ioss::NodeSet *entity = *it; if (stk::io::include_entity(entity)) { stk::mesh::Part* const part = meta.get_part(entity->name()); STKIORequire(part != NULL); STKIORequire(entity->field_exists("distribution_factors")); stk::mesh::put_field(distribution_factors_field, *part); /** \todo IMPLEMENT truly handle fields... For this case we * are just defining a field for each transient field that is * present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT, *part, part->primary_entity_rank() ) ; } } }
// ======================================================================== void process_elementblocks(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const stk::mesh::EntityRank element_rank = stk::topology::ELEMENT_RANK; const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); stk::io::default_part_processing(elem_blocks, meta, element_rank); // Parts were created above, now handle element block specific // information (topology, attributes, ...); for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); it != elem_blocks.end(); ++it) { Ioss::ElementBlock *entity = *it; if (stk::io::include_entity(entity)) { stk::mesh::Part* const part = meta.get_part(entity->name()); STKIORequire(part != NULL); const stk::mesh::EntityRank part_rank = part->primary_entity_rank(); // Element Block attributes (if any)... /** \todo IMPLEMENT truly handle attribute fields... For this * case we are just defining a field for each attribute field * that is present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE, *part, part_rank); /** \todo IMPLEMENT truly handle fields... For this case we * are just defining a field for each transient field that is * present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT, *part, part_rank); } } }
// ======================================================================== void process_nodeblocks(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks(); assert(node_blocks.size() == 1); Ioss::NodeBlock *nb = node_blocks[0]; assert(nb->field_exists("mesh_model_coordinates")); Ioss::Field coordinates = nb->get_field("mesh_model_coordinates"); int spatial_dim = coordinates.transformed_storage()->component_count(); stk::mesh::Field<double,stk::mesh::Cartesian> & coord_field = meta.declare_field<stk::mesh::Field<double,stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates"); stk::mesh::put_field( coord_field, meta.universal_part(), spatial_dim); /** \todo IMPLEMENT truly handle fields... For this case we are * just defining a field for each transient field that is present * in the mesh... */ stk::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk::topology::NODE_RANK); }
void Albany::IossSTKMeshStruct::setFieldAndBulkData( const Teuchos::RCP<const Epetra_Comm>& comm, const Teuchos::RCP<Teuchos::ParameterList>& params, const unsigned int neq_, const AbstractFieldContainer::FieldContainerRequirements& req, const Teuchos::RCP<Albany::StateInfoStruct>& sis, const unsigned int worksetSize) { this->SetupFieldData(comm, neq_, req, sis, worksetSize); *out << "IOSS-STK: number of node sets = " << nsPartVec.size() << std::endl; *out << "IOSS-STK: number of side sets = " << ssPartVec.size() << std::endl; metaData->commit(); // Restart index to read solution from exodus file. int index = params->get("Restart Index",-1); // Default to no restart double res_time = params->get<double>("Restart Time",-1.0); // Default to no restart Ioss::Region *region = mesh_data->m_input_region; /* * The following code block reads a single mesh on PE 0, then distributes the mesh across * the other processors. stk_rebalance is used, which requires Zoltan * * This code is only compiled if ALBANY_MPI and ALBANY_ZOLTAN are true */ #ifdef ALBANY_ZOLTAN // rebalance needs Zoltan if(useSerialMesh){ bulkData->modification_begin(); if(comm->MyPID() == 0){ // read in the mesh on PE 0 stk::io::process_mesh_bulk_data(region, *bulkData); // Read solution from exodus file. if (index >= 0) { // User has specified a time step to restart at *out << "Restart Index set, reading solution index : " << index << std::endl; stk::io::input_mesh_fields(region, *bulkData, index); m_restartDataTime = region->get_state_time(index); m_hasRestartSolution = true; } else if (res_time >= 0) { // User has specified a time to restart at *out << "Restart solution time set, reading solution time : " << res_time << std::endl; stk::io::input_mesh_fields(region, *bulkData, res_time); m_restartDataTime = res_time; m_hasRestartSolution = true; } else { *out << "Neither restart index or time are set. Not reading solution data from exodus file"<< std::endl; } } bulkData->modification_end(); } // End UseSerialMesh - reading mesh on PE 0 else #endif /* * The following code block reads a single mesh when Albany is compiled serially, or a * Nemspread fileset if ALBANY_MPI is true. * */ { // running in Serial or Parallel read from Nemspread files stk::io::populate_bulk_data(*bulkData, *mesh_data); if (!usePamgen) { // Read solution from exodus file. if (index >= 0) { // User has specified a time step to restart at *out << "Restart Index set, reading solution index : " << index << std::endl; stk::io::process_input_request(*mesh_data, *bulkData, index); m_restartDataTime = region->get_state_time(index); m_hasRestartSolution = true; } else if (res_time >= 0) { // User has specified a time to restart at *out << "Restart solution time set, reading solution time : " << res_time << std::endl; stk::io::process_input_request(*mesh_data, *bulkData, res_time); m_restartDataTime = res_time; m_hasRestartSolution = true; } else { *out << "Restart Index not set. Not reading solution from exodus (" << index << ")"<< std::endl; } } bulkData->modification_end(); } // End Parallel Read - or running in serial if(m_hasRestartSolution){ Teuchos::Array<std::string> default_field; default_field.push_back("solution"); Teuchos::Array<std::string> restart_fields = params->get<Teuchos::Array<std::string> >("Restart Fields", default_field); // Get the fields to be used for restart // See what state data was initialized from the stk::io request // This should be propagated into stk::io const Ioss::ElementBlockContainer& elem_blocks = region->get_element_blocks(); /* // Uncomment to print what fields are in the exodus file Ioss::NameList exo_fld_names; elem_blocks[0]->field_describe(&exo_fld_names); for(std::size_t i = 0; i < exo_fld_names.size(); i++){ *out << "Found field \"" << exo_fld_names[i] << "\" in exodus file" << std::endl; } */ for (std::size_t i=0; i<sis->size(); i++) { Albany::StateStruct& st = *((*sis)[i]); if(elem_blocks[0]->field_exists(st.name)) for(std::size_t j = 0; j < restart_fields.size(); j++) if(boost::iequals(st.name, restart_fields[j])){ *out << "Restarting from field \"" << st.name << "\" found in exodus file." << std::endl; st.restartDataAvailable = true; break; } } } // coordinates_field = metaData->get_field<VectorFieldType>(std::string("coordinates")); //#ifdef ALBANY_FELIX // surfaceHeight_field = metaData->get_field<ScalarFieldType>(std::string("surface height")); //#endif // Refine the mesh before starting the simulation if indicated uniformRefineMesh(comm); // Rebalance the mesh before starting the simulation if indicated rebalanceInitialMesh(comm); // Build additional mesh connectivity needed for mesh fracture (if indicated) computeAddlConnectivity(); }