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

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

        if (stk::io::include_entity(entity)) {
            const std::string &name = entity->name();
            const stk::mesh::MetaData& meta = 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);

            }
        }
    }
}
Example #2
0
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;
    }
  }
}