/** This is the common base class portion of the virtual fn and is
    insufficient on its own; derived implementations should explicitly
    invoke (or reimplement) this base class contribution. */
void Approximation::build()
{
  if (approxRep)
    approxRep->build();
  else {
    size_t num_curr_pts = approxData.size();
    int ms = min_points(true); // account for anchor point & buildDataOrder
    if (num_curr_pts < ms) {
      Cerr << "\nError: not enough samples to build approximation.  "
	   << "Construction of this approximation\n       requires at least "
	   << ms << " samples for " << sharedDataRep->numVars << " variables.  "
	   << "Only " << num_curr_pts << " samples were provided." << std::endl;
      abort_handler(-1);
    }
  }
}
Exemplo n.º 2
0
void
GrainTracker::buildBoundingSpheres()
{
  // Don't track grains if the current simulation step is before the specified tracking step
  if (_t_step < _tracking_step)
    return;

  MeshBase & mesh = _mesh.getMesh();

  unsigned long total_node_count = 0;
  for (unsigned int map_num = 0; map_num < _maps_size; ++map_num)
  {
    /**
     * Create a pair of vectors of real values that is 3 (for the x,y,z components) times
     * the length of the current _bubble_sets length. Each processor will update the
     * vector for the nodes that it owns (parallel_mesh case).  Then a parallel exchange
     * will all for the global min/maxs of each bubble.
     */
    std::vector<Real> min_points(_bubble_sets[map_num].size()*3,  std::numeric_limits<Real>::max());
    std::vector<Real> max_points(_bubble_sets[map_num].size()*3, -std::numeric_limits<Real>::max());

    unsigned int set_counter = 0;
    for (std::list<BubbleData>::const_iterator it1 = _bubble_sets[map_num].begin();
         it1 != _bubble_sets[map_num].end(); ++it1)
    {
      total_node_count += it1->_entity_ids.size();

      // Find the min/max of our bounding box to calculate our bounding sphere
      for (std::set<dof_id_type>::iterator it2 = it1->_entity_ids.begin(); it2 != it1->_entity_ids.end(); ++it2)
      {
        Point point;
        Point * p_ptr = NULL;
        if (_is_elemental)
        {
          Elem *elem = mesh.query_elem(*it2);
          if (elem)
          {
            point = elem->centroid();
            p_ptr = &point;
          }
        }
        else
          p_ptr = mesh.query_node_ptr(*it2);
        if (p_ptr)
          for (unsigned int i = 0; i < mesh.spatial_dimension(); ++i)
          {
            min_points[set_counter*3+i] = std::min(min_points[set_counter*3+i], (*p_ptr)(i));
            max_points[set_counter*3+i] = std::max(max_points[set_counter*3+i], (*p_ptr)(i));
          }
      }

      ++set_counter;
    }

    _communicator.min(min_points);
    _communicator.max(max_points);

    set_counter = 0;
    for (std::list<BubbleData>::const_iterator it1 = _bubble_sets[map_num].begin();
         it1 != _bubble_sets[map_num].end(); ++it1)
    {
      Point min(min_points[set_counter*3], min_points[set_counter*3+1], min_points[set_counter*3+2]);
      Point max(max_points[set_counter*3], max_points[set_counter*3+1], max_points[set_counter*3+2]);

      // Calulate our bounding sphere
      Point center(min + ((max - min) / 2.0));

      // The radius is the different between the outer edge of the "bounding box"
      // and the center plus the "hull buffer" value
      Real radius = (max - center).size() + _hull_buffer;

      unsigned int some_node_id = *(it1->_entity_ids.begin());
      _bounding_spheres[map_num].push_back(new BoundingSphereInfo(some_node_id, center, radius));

      ++set_counter;
    }
  }
}