예제 #1
0
/**
 * Save a patch of nodes that are close to each of the slave nodes to speed the search algorithm
 * TODO: This needs to be updated at some point in time.  If the hits into this data structure approach "the end"
 * then it may be time to update
 */
void
NearestNodeThread::operator() (const NodeIdRange & range)
{
  for (NodeIdRange::const_iterator nd = range.begin() ; nd != range.end(); ++nd)
  {
    dof_id_type node_id = *nd;

    const Node & node = _mesh.node(node_id);

    const Node * closest_node = NULL;
    Real closest_distance = std::numeric_limits<Real>::max();

    const std::vector<dof_id_type> & neighbor_nodes = _neighbor_nodes[node_id];

    unsigned int n_neighbor_nodes = neighbor_nodes.size();

    for (unsigned int k=0; k<n_neighbor_nodes; k++)
    {
      const Node * cur_node = &_mesh.node(neighbor_nodes[k]);
      Real distance = ((*cur_node) - node).size();

      if (distance < closest_distance)
      {
        Real patch_percentage = static_cast<Real>(k) / static_cast<Real>(n_neighbor_nodes);

        // Save off the maximum we had to go through the patch to find the closes node
        if (patch_percentage > _max_patch_percentage)
          _max_patch_percentage = patch_percentage;

        closest_distance = distance;
        closest_node = cur_node;
      }
    }

    if (closest_distance == std::numeric_limits<Real>::max())
      mooseError("Unable to find nearest node!");

    NearestNodeLocator::NearestNodeInfo & info = _nearest_node_info[node.id()];

    info._nearest_node = closest_node;
    info._distance = closest_distance;
  }
}
예제 #2
0
    void NodeIdRangeTests::TestSubtractRanges(NodeIdRange const & range, vector<NodeIdRange> const & excludes)
    {
        vector<NodeIdRange> result;

        range.Subtract(excludes, result);
        Trace.WriteInfo(TraceRangeTest, "Range {0} exclude {1} returned {2}",
            range, excludes, result);

        LargeInteger overlapSize = LargeInteger::Zero;
        for (size_t i = 0; i < result.size(); i++)
        {
            VERIFY_IS_TRUE(!result[i].IsEmpty);
            VERIFY_IS_TRUE(range.Contains(result[i]));

            for (size_t j = 0; j < excludes.size(); j++)
            {
                VERIFY_IS_TRUE(result[i].Disjoint(excludes[j]));
            }

            overlapSize = overlapSize + GetOverlapSize(range, result[i]);
        }

        for (size_t i = 0; i + 1 < result.size(); i++)
        {
            for (size_t j = i + 1; j < result.size(); j++)
            {
                VERIFY_IS_TRUE(result[i].Disjoint(result[j]));
            }
        }

        for (size_t i = 0; i < excludes.size(); i++)
        {
            overlapSize = overlapSize + GetOverlapSize(range, excludes[i]);
        }

        VERIFY_IS_TRUE(GetRangeSize(range) == overlapSize);
    }
예제 #3
0
    void NodeIdRangeTests::TestSubtract(NodeIdRange const & range, NodeIdRange const & exclude)
    {
        NodeIdRange range1, range2;
        range.Subtract(exclude, range1, range2);

        Trace.WriteInfo(TraceRangeTest, "Range {0} exclude {1} returned {2} and {3}",
            range, exclude, range1, range2);

        if (!range1.IsEmpty)
        {
            VERIFY_IS_TRUE(range.Contains(range1) && exclude.Disjoint(range1));
            if (!range2.IsEmpty)
            {
                VERIFY_IS_TRUE(range1.Disjoint(range2) && !range1.IsSuccAdjacent(range2) && !range1.IsPredAdjacent(range2));
            }
        }

        if (!range2.IsEmpty)
        {
            VERIFY_IS_TRUE((range2.IsEmpty || range.Contains(range2)) && exclude.Disjoint(range2));
        }

        VERIFY_IS_TRUE(GetRangeSize(range) == GetOverlapSize(range, exclude) + GetRangeSize(range1) + GetRangeSize(range2));
    }
예제 #4
0
/**
 * Save a patch of nodes that are close to each of the slave nodes to speed the search algorithm
 * TODO: This needs to be updated at some point in time.  If the hits into this data structure approach "the end"
 * then it may be time to update
 */
void
SlaveNeighborhoodThread::operator() (const NodeIdRange & range)
{
  processor_id_type processor_id = _mesh.processor_id();

  for (NodeIdRange::const_iterator nd = range.begin() ; nd != range.end(); ++nd)
  {
    unsigned int node_id = *nd;

    const Node & node = *_mesh.nodePtr(node_id);

    std::priority_queue<std::pair<unsigned int, Real>, std::vector<std::pair<unsigned int, Real> >, ComparePair> neighbors;

    unsigned int n_master_nodes = _trial_master_nodes.size();

    // Get a list, in descending order of distance, of master nodes in relation to this node
    for (unsigned int k=0; k<n_master_nodes; k++)
    {
      unsigned int master_id = _trial_master_nodes[k];
      const Node * cur_node = &_mesh.node(master_id);
      Real distance = ((*cur_node) - node).size();

      neighbors.push(std::make_pair(master_id, distance));
    }

    std::vector<unsigned int> neighbor_nodes;

    unsigned int patch_size = std::min(_patch_size, static_cast<unsigned int>(neighbors.size()));
    neighbor_nodes.resize(patch_size);

    // Grab the closest "patch_size" worth of nodes to save off
    for (unsigned int t=0; t<patch_size; t++)
    {
      std::pair<unsigned int, Real> neighbor_info = neighbors.top();
      neighbors.pop();

      neighbor_nodes[t] = neighbor_info.first;
    }

    /**
     * Now see if _this_ processor needs to keep track of this slave and it's neighbors
     * We're going to see if this processor owns the slave, any of the neighborhood nodes
     * or any of the elements connected to either set.  If it does then we're going to ghost
     * all of the elements connected to the slave node and the neighborhood nodes to this processor.
     * This is a very conservative approach that we might revisit later.
     */

    bool need_to_track = false;

    if (_mesh.node(node_id).processor_id() == processor_id)
      need_to_track = true;
    else
    {
      { // See if we own any of the elements connected to the slave node
        const std::vector<unsigned int> & elems_connected_to_node = _node_to_elem_map[node_id];

        for (unsigned int elem_id_it=0; elem_id_it < elems_connected_to_node.size(); elem_id_it++)
          if (_mesh.elem(elems_connected_to_node[elem_id_it])->processor_id() == processor_id)
          {
            need_to_track = true;
            break; // Break out of element loop
          }
      }

      if (!need_to_track)
      { // Now check the neighbor nodes to see if we own any of them
        for (unsigned int neighbor_it=0; neighbor_it < neighbor_nodes.size(); neighbor_it++)
        {
          unsigned int neighbor_node_id = neighbor_nodes[neighbor_it];

          if (_mesh.node(neighbor_node_id).processor_id() == processor_id)
            need_to_track = true;
          else // Now see if we own any of the elements connected to the neighbor nodes
          {
            const std::vector<unsigned int> & elems_connected_to_node = _node_to_elem_map[neighbor_node_id];

            for (unsigned int elem_id_it=0; elem_id_it < elems_connected_to_node.size(); elem_id_it++)
              if (_mesh.elem(elems_connected_to_node[elem_id_it])->processor_id() == processor_id)
              {
                need_to_track = true;
                break; // Break out of element loop
              }
          }

          if (need_to_track)
            break; // Breaking out of neighbor loop
        }
      }
    }

    if (need_to_track)
    {
      // Add this node as a slave node to search in the future
      _slave_nodes.push_back(node_id);

      // Set it's neighbors
      _neighbor_nodes[node_id] = neighbor_nodes;

      { // Add the elements connected to the slave node to the ghosted list
        const std::vector<unsigned int> & elems_connected_to_node = _node_to_elem_map[node_id];

        for (unsigned int elem_id_it=0; elem_id_it < elems_connected_to_node.size(); elem_id_it++)
          _ghosted_elems.insert(elems_connected_to_node[elem_id_it]);
      }

      // Now add elements connected to the neighbor nodes to the ghosted list
      for (unsigned int neighbor_it=0; neighbor_it < neighbor_nodes.size(); neighbor_it++)
      {
        const std::vector<unsigned int> & elems_connected_to_node = _node_to_elem_map[neighbor_nodes[neighbor_it]];

        for (unsigned int elem_id_it=0; elem_id_it < elems_connected_to_node.size(); elem_id_it++)
          _ghosted_elems.insert(elems_connected_to_node[elem_id_it]);
      }
    }
  }
}