Esempio n. 1
0
  void build_reverse_node_map(Ioss::Region &global,
			      RegionVector &part_mesh,
			      std::vector<INT> &global_node_map,
			      std::vector<INT> &local_node_map)
  {
    // Instead of using <set> and <map>, consider using a sorted vector...
    // Append all local node maps to the global node map.
    // Sort the global node map
    // Remove duplicates.
    // Position within map is now the map...
    // When building the local-part node to global id, use binary_search...

    size_t part_count = part_mesh.size();

    // Global node map and count.
    std::vector<std::vector<int> > global_nodes(part_count);

    size_t tot_size = 0;
    for (size_t p = 0; p < part_count; p++) {
      Ioss::NodeBlock *nb = part_mesh[p]->get_node_blocks()[0];
      size_t loc_size = nb->get_property("entity_count").get_int();
      tot_size += loc_size;
      global_nodes[p].resize(loc_size);
    }
    global_node_map.resize(tot_size);

    size_t offset = 0;
    bool any_omitted_nodes = false;
    for (size_t p = 0; p < part_count; p++) {
      Ioss::NodeBlock *nb = part_mesh[p]->get_node_blocks()[0];
      nb->get_field_data("ids", global_nodes[p]);

      // If there are any omitted element blocks for this part, set
      // the global id of any nodes that are only connected to omitted
      // element blocks to 0.
      bool has_omissions = part_mesh[p]->get_property("block_omission_count").get_int() > 0;
      if (has_omissions) {
	std::vector<char> node_status;
	nb->get_field_data("node_connectivity_status", node_status);
	for (size_t i=0; i < node_status.size(); i++) {
	  if (node_status[i] == 1) {
	    any_omitted_nodes = true;
	    global_nodes[p][i] = 0;
	  }
	}
      }

      std::copy(global_nodes[p].begin(), global_nodes[p].end(), &global_node_map[offset]);
      offset += global_nodes[p].size();
    }

    // Now, sort the global_node_map array and remove duplicates...
    uniqify(global_node_map);

    // If any omitted nodes, remove them from the global_node_map.
    // The id will be 0
    if (any_omitted_nodes) {
      typename std::vector<INT>::iterator pos = std::remove(global_node_map.begin(),
						   global_node_map.end(), 0);
      global_node_map.erase(pos, global_node_map.end());
    }

    size_t output_node_count = global_node_map.size();

    // See whether the node numbers are contiguous.  If so, we can map
    // the nodes back to their original location. Since the nodes are
    // sorted and there are no duplicates, we just need to see if the id
    // at global_node_map.size() == global_node_map.size();
    size_t max_id = global_node_map[output_node_count-1];

    bool is_contiguous = max_id == output_node_count;
    std::cerr  << "Node map " << (is_contiguous ? "is" : "is not") << " contiguous.\n";

    // Create the map that maps from a local part node to the
    // global map. This combines the mapping local part node to
    // 'global id' and then 'global id' to global position. The
    // mapping is now a direct lookup instead of a lookup followed by
    // a reverse map.
    typedef typename std::vector<INT>::iterator V_INT_iterator;
    V_INT_iterator cur_pos = global_node_map.begin();
    for (size_t p = 0; p < part_count; p++) {
      size_t noffset = part_mesh[p]->get_property("node_offset").get_int();
      size_t node_count = global_nodes[p].size();
      for (size_t i = 0; i < node_count; i++) {
	INT global_node = global_nodes[p][i];

	if (global_node > 0) {
	if (cur_pos == global_node_map.end() || *cur_pos != global_node) {
	  std::pair<V_INT_iterator, V_INT_iterator> iter = std::equal_range(global_node_map.begin(),
									    global_node_map.end(),
									    global_node);
	  if (iter.first == iter.second) {
	    INT n = global_node;
	    std::cerr << n << "\n";
	    SMART_ASSERT(iter.first != iter.second);
	  }
	  cur_pos = iter.first;
	}
	size_t nodal_value = cur_pos - global_node_map.begin();
	local_node_map[noffset+i] = nodal_value;
	++cur_pos;
	} else {
	  local_node_map[noffset+i] = -1;
	}
      }				
    }
    
    // Update the nodal ids to give a unique, non-repeating set.  If contiguous, then
    // there is nothing to do.  If not contiguous, then need to determine if there are any
    // repeats (id reuse) and if so, generate a new id for the repeated uses.
    if (!is_contiguous) {
      bool repeat_found = false;
      INT id_last = global_node_map[0];
      for (size_t i=1; i < output_node_count; i++) {
	if (global_node_map[i] == id_last) {
	  global_node_map[i] = ++max_id;
	  repeat_found = true;
	} else {
	  id_last = global_node_map[i];
	}
      }
      if (repeat_found) {
	std::cerr  << "Duplicate node ids were found. Their ids have been renumbered to remove duplicates.\n";
      }
    }
  }
Esempio n. 2
0
 constant_estimator(std::string name) {
   name = uniqify(name);
 }