Esempio n. 1
0
void
FeatureFloodCount::flood(const DofObject * dof_object, unsigned long current_idx, FeatureData * feature)
{
  if (dof_object == nullptr)
    return;

  // Retrieve the id of the current entity
  auto entity_id = dof_object->id();

  // Has this entity already been marked? - if so move along
  if (_entities_visited[current_idx].find(entity_id) != _entities_visited[current_idx].end())
    return;

  // Mark this entity as visited
  _entities_visited[current_idx][entity_id] = true;

  // Determine which threshold to use based on whether this is an established region
  auto threshold = feature ? _step_connecting_threshold : _step_threshold;

  // Get the value of the current variable for the current entity
  Real entity_value;
  if (_is_elemental)
  {
    const Elem * elem = static_cast<const Elem *>(dof_object);
    std::vector<Point> centroid(1, elem->centroid());
    _subproblem.reinitElemPhys(elem, centroid, 0);
    entity_value = _vars[current_idx]->sln()[0];
  }
  else
    entity_value = _vars[current_idx]->getNodalValue(*static_cast<const Node *>(dof_object));

  // This node hasn't been marked, is it in a feature?  We must respect
  // the user-selected value of _use_less_than_threshold_comparison.
  if (_use_less_than_threshold_comparison && (entity_value < threshold))
    return;

  if (!_use_less_than_threshold_comparison && (entity_value > threshold))
    return;

  /**
   * If we reach this point (i.e. we haven't returned early from this routine),
   * we've found a new mesh entity that's part of a feature.
   */
  auto map_num = _single_map_mode ? decltype(current_idx)(0) : current_idx;

  // New Feature (we need to create it and add it to our data structure)
  if (!feature)
    _partial_feature_sets[map_num].emplace_back(current_idx);

  // Get a handle to the feature we will update (always the last feature in the data structure)
  feature = &_partial_feature_sets[map_num].back();

  // Insert the current entity into the local ids map
  feature->_local_ids.insert(entity_id);

  if (_is_elemental)
    visitElementalNeighbors(static_cast<const Elem *>(dof_object), current_idx, feature, /*expand_halos_only =*/false);
  else
    visitNodalNeighbors(static_cast<const Node *>(dof_object), current_idx, feature, /*expand_halos_only =*/false);
}
Esempio n. 2
0
void
GrainTracker::expandHalos()
{
  processor_id_type n_procs = _app.n_processors();

  for (unsigned int map_num = 0; map_num < _maps_size; ++map_num)
    for (processor_id_type rank = 0; rank < n_procs; ++rank)
      for (std::vector<FeatureData>::iterator it = _partial_feature_sets[rank][map_num].begin();
           it != _partial_feature_sets[rank][map_num].end(); ++it)
      {
        FeatureData & feature = *it;

        for (unsigned int halo_level = 1; halo_level < _halo_level; ++halo_level)
        {
          /**
           * Create a copy of the halo set so that as we insert new ids into the
           * set we don't continue to iterate on those new ids.
           */
          std::set<dof_id_type> orig_halo_ids(feature._halo_ids);

          for (std::set<dof_id_type>::iterator entity_it = orig_halo_ids.begin();
               entity_it != orig_halo_ids.end(); ++entity_it)
          {
            if (_is_elemental)
              visitElementalNeighbors(_mesh.elemPtr(*entity_it), feature._var_idx, &feature, /*recurse =*/false);
            else
              visitNodalNeighbors(_mesh.nodePtr(*entity_it), feature._var_idx, &feature, /*recurse =*/false);
          }
        }
      }
}
Esempio n. 3
0
void
FeatureFloodCount::flood(const DofObject * dof_object, std::size_t current_index, FeatureData * feature)
{
  if (dof_object == nullptr)
    return;

  // Retrieve the id of the current entity
  auto entity_id = dof_object->id();

  // Has this entity already been marked? - if so move along
  if (_entities_visited[current_index].find(entity_id) != _entities_visited[current_index].end())
    return;

  // See if the current entity either starts a new feature or continues an existing feature
  auto new_id = invalid_id;  // Writable reference to hold an optional id;
  if (!isNewFeatureOrConnectedRegion(dof_object, current_index, feature, new_id))
    return;

  /**
   * If we reach this point (i.e. we haven't returned early from this routine),
   * we've found a new mesh entity that's part of a feature. We need to mark
   * the entity as visited at this point (and not before!) to avoid infinite
   * recursion. If you mark the node too early you risk not coloring in a whole
   * feature any time a "connecting threshold" is used since we may have
   * already visited this entity earlier but it was in-between two thresholds.
   */
  _entities_visited[current_index][entity_id] = true;

  auto map_num = _single_map_mode ? decltype(current_index)(0) : current_index;

  // New Feature (we need to create it and add it to our data structure)
  if (!feature)
  {
    _partial_feature_sets[map_num].emplace_back(current_index, _feature_count++, processor_id());

    // Get a handle to the feature we will update (always the last feature in the data structure)
    feature = &_partial_feature_sets[map_num].back();

    // If new_id is valid, we'll set it in the feature here.
    if (new_id != invalid_id)
      feature->_id = new_id;
  }

  // Insert the current entity into the local ids map
  feature->_local_ids.insert(entity_id);

  /**
   * See if this particular entity cell contributes to the centroid calculation. We
   * only deal with elemental floods and only count it if it's owned by the current
   * processor to avoid skewing the result.
   */
  if (_is_elemental && processor_id() == dof_object->processor_id())
  {
    const Elem * elem = static_cast<const Elem *>(dof_object);

    // Keep track of how many elements participate in the centroid averaging
    feature->_vol_count++;

    // Sum the centroid values for now, we'll average them later
    feature->_centroid += elem->centroid();

    // Does the volume intersect the boundary?
    if (_all_boundary_entity_ids.find(elem->id()) != _all_boundary_entity_ids.end())
      feature->_intersects_boundary = true;
  }

  if (_is_elemental)
    visitElementalNeighbors(static_cast<const Elem *>(dof_object), current_index, feature, /*expand_halos_only =*/false);
  else
    visitNodalNeighbors(static_cast<const Node *>(dof_object), current_index, feature, /*expand_halos_only =*/false);
}