// ======================================================================== 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 generate_element_ids(RegionVector &part_mesh, const std::vector<INT> &local_element_map, std::vector<INT> &global_element_map) { // Follow same logic as 'build_local_element_map' to ensure elements // are processed in same order. // Many models do not use the element number map at all, so they // will have a 1..numel map. If all parts have that, then we don't // want to do any fancy duplicate removal and other processing, just // output a 1..numel map for the output mesh... We still generate // the global_element_map, but check whether any of the part blocks // have a non-1..numel map... bool has_map = false; size_t offset = 0; for (size_t p = 0; p < part_mesh.size(); p++) { Ioss::ElementBlockContainer ebs = part_mesh[p]->get_element_blocks(); Ioss::ElementBlockContainer::const_iterator i = ebs.begin(); while (i != ebs.end()) { Ioss::ElementBlock *eb = *i++; INT num_elem = eb->get_property("entity_count").get_int(); if (!entity_is_omitted(eb)) { std::vector<INT> part_ids; eb->get_field_data("ids", part_ids); if (!has_map) { INT eb_offset = eb->get_offset(); for (INT j = 0; j < num_elem; j++) { if (part_ids[j] != eb_offset+j+1) { has_map = true; break; } } } for (INT j = 0; j < num_elem; j++) { INT gpos = local_element_map[offset+j]; if (gpos >= 0) global_element_map[gpos] = part_ids[j]; } } offset += num_elem; } } // Check for duplicates... // NOTE: Used to use an indexed sort here, but if there was a // duplicate id, it didnt really care whether part 1 or part N's // index came first which causes really screwy element maps. // Instead, lets sort a vector containing pairs of <id, index> where // the index will always? increase for increasing part numbers... std::vector<std::pair<INT,INT> > index(global_element_map.size()); for (size_t i=0; i < index.size(); i++) { index[i] = std::make_pair(global_element_map[i],(INT)i); } std::sort(index.begin(), index.end()); INT max_id = index[index.size()-1].first + 1; size_t beg = 0; for (size_t i=1; i < index.size(); i++) { if (index[beg].first == index[i].first) { // Duplicate found... Assign it a new id greater than any // existing id... (What happens if we exceed INT_MAX?) global_element_map[index[i].second] = max_id++; // Keep 'beg' the same in case multiple duplicate of this value. } else { beg = i; } } }