Exemple #1
0
EFAFragment3D::EFAFragment3D(EFAElement3D * host,
                             bool create_faces,
                             const EFAElement3D * from_host,
                             unsigned int frag_id)
  : EFAFragment(), _host_elem(host)
{
  if (create_faces)
  {
    if (!from_host)
      EFAError("EFAfragment3D constructor must have a from_host to copy from");
    if (frag_id == std::numeric_limits<unsigned int>::max()) // copy the from_host itself
    {
      for (unsigned int i = 0; i < from_host->numFaces(); ++i)
        _faces.push_back(new EFAFace(*from_host->getFace(i)));
    }
    else
    {
      if (frag_id > from_host->numFragments() - 1)
        EFAError("In EFAfragment3D constructor fragment_copy_index out of bounds");
      for (unsigned int i = 0; i < from_host->getFragment(frag_id)->numFaces(); ++i)
        _faces.push_back(new EFAFace(*from_host->getFragmentFace(frag_id, i)));
    }
    findFacesAdjacentToFaces(); // IMPORTANT
  }
}
void
ElementFragmentAlgorithm::addElemEdgeIntersection(unsigned int elemid,
                                                  unsigned int edgeid,
                                                  double position)
{
  // this method is called when we are marking cut edges
  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
  if (eit == _elements.end())
    EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");

  EFAElement2D * curr_elem = dynamic_cast<EFAElement2D *>(eit->second);
  if (!curr_elem)
    EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
  curr_elem->addEdgeCut(edgeid, position, NULL, _embedded_nodes, true);
}
bool
ElementFragmentAlgorithm::addFragEdgeIntersection(unsigned int elemid,
                                                  unsigned int frag_edge_id,
                                                  double position)
{
  // N.B. this method must be called after addEdgeIntersection
  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
  if (eit == _elements.end())
    EFAError("Could not find element with id: ", elemid, " in addFragEdgeIntersection");

  EFAElement2D * elem = dynamic_cast<EFAElement2D *>(eit->second);
  if (!elem)
    EFAError("addFragEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
  return elem->addFragmentEdgeCut(frag_edge_id, position, _embedded_nodes);
}
Exemple #4
0
EFANode *
EFAElement::getGlobalNodeFromLocalNode(const EFANode * local_node) const
{
  //Given a local node, find the global node corresponding to that node
  if (local_node->category() != EFANode::N_CATEGORY_LOCAL_INDEX)
    EFAError("In getGlobalNodeFromLocalNode node passed in is not local");

  EFANode * global_node = _nodes[local_node->id()];

  if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
      global_node->category() != EFANode::N_CATEGORY_TEMP)
    EFAError("In getGlobalNodeFromLocalNode, the node stored by the element is not global");

  return global_node;
}
Exemple #5
0
EFAFace *
EFAFragment3D::getFace(unsigned int face_id) const
{
  if (face_id > _faces.size() - 1)
    EFAError("in EFAfragment3D::get_face, index out of bounds");
  return _faces[face_id];
}
EFAElement *
ElementFragmentAlgorithm::add2DElement(std::vector<unsigned int> quad, unsigned int id)
{
  unsigned int num_nodes = quad.size();

  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
  if (mit != _elements.end())
    EFAError("In add2DElement element with id: ", id, " already exists");

  EFAElement2D * newElem = new EFAElement2D(id, num_nodes);
  _elements.insert(std::make_pair(id, newElem));

  for (unsigned int j = 0; j < num_nodes; ++j)
  {
    EFANode * currNode = NULL;
    std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quad[j]);
    if (mit == _permanent_nodes.end())
    {
      currNode = new EFANode(quad[j], EFANode::N_CATEGORY_PERMANENT);
      _permanent_nodes.insert(std::make_pair(quad[j], currNode));
    }
    else
      currNode = mit->second;

    newElem->setNode(j, currNode);
    _inverse_connectivity[currNode].insert(newElem);
  }
  newElem->createEdges();
  return newElem;
}
EFAElement *
ElementFragmentAlgorithm::getElemByID(unsigned int id)
{
  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
  if (mit == _elements.end())
    EFAError("in getElemByID() could not find element: ", id);
  return mit->second;
}
Exemple #8
0
EFAElement*
EFAElement::getChild(unsigned int child_id) const
{
  if (child_id < _children.size())
    return _children[child_id];
  else
    EFAError("child_id out of bounds");
}
Exemple #9
0
unsigned int
EFAElement::getCrackTipNeighbor(unsigned int index) const
{
  if (index < _crack_tip_neighbors.size())
    return _crack_tip_neighbors[index];
  else
    EFAError("in getCrackTipNeighbor index out of bounds");
}
Exemple #10
0
unsigned int
EFAFragment3D::getFaceID(EFAFace * face) const
{
  for (unsigned int i = 0; i < _faces.size(); ++i)
    if (_faces[i] == face)
      return i;
  EFAError("face not found in get_face_id()");
  return 99999;
}
void
ElementFragmentAlgorithm::addElemFaceIntersection(unsigned int elemid,
                                                  unsigned int faceid,
                                                  std::vector<unsigned int> edgeid,
                                                  std::vector<double> position)
{
  // this method is called when we are marking cut edges
  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
  if (eit == _elements.end())
    EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");

  EFAElement3D * curr_elem = dynamic_cast<EFAElement3D *>(eit->second);
  if (!curr_elem)
    EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");

  // add cuts to two face edges at the same time
  curr_elem->addFaceEdgeCut(faceid, edgeid[0], position[0], NULL, _embedded_nodes, true, true);
  curr_elem->addFaceEdgeCut(faceid, edgeid[1], position[1], NULL, _embedded_nodes, true, true);
}
Exemple #12
0
void
EFAFragment3D::removeInvalidEmbeddedNodes(std::map<unsigned int, EFANode *> & EmbeddedNodes)
{
  // N.B. this method is only called before we update fragments
  // N.B. an embedded node is valid IF at least one of its host faces is exterior and has more than
  // 1 cuts
  // TODO: the invalid cases are generalized from 2D. The method may need improvements in 3D
  if (hasFaceWithOneCut())
  {
    // build a local inverse map for all emb cut nodes in this fragment
    std::map<EFANode *, std::vector<EFAFace *>> emb_inverse_map;
    for (unsigned int i = 0; i < _faces.size(); ++i)
    {
      for (unsigned int j = 0; j < _faces[i]->numEdges(); ++j)
      {
        if (_faces[i]->getEdge(j)->hasIntersection())
        {
          EFANode * emb_node = _faces[i]->getEdge(j)->getEmbeddedNode(0);
          emb_inverse_map[emb_node].push_back(_faces[i]);
        }
      } // i
    }   // j

    // find all invalid embedded nodes
    std::vector<EFANode *> invalid_emb;
    std::map<EFANode *, std::vector<EFAFace *>>::iterator it;
    for (it = emb_inverse_map.begin(); it != emb_inverse_map.end(); ++it)
    {
      EFANode * emb_node = it->first;
      std::vector<EFAFace *> & emb_faces = it->second;
      if (emb_faces.size() != 2)
        EFAError("one embedded node must be owned by 2 faces");
      unsigned int counter = 0;
      for (unsigned int i = 0; i < emb_faces.size(); ++i)
      {
        unsigned int face_id = getFaceID(emb_faces[i]);
        if (!isFaceInterior(face_id) && emb_faces[i]->hasIntersection())
          counter += 1; // count the appropriate emb's faces
      }
      if (counter == 0)
        invalid_emb.push_back(emb_node);
    }

    // delete all invalid emb nodes
    for (unsigned int i = 0; i < invalid_emb.size(); ++i)
    {
      Efa::deleteFromMap(EmbeddedNodes, invalid_emb[i]);
      _host_elem->removeEmbeddedNode(invalid_emb[i], true); // also remove from neighbors
    }                                                       // i
  }
}
Exemple #13
0
EFANode *
EFAElement::createLocalNodeFromGlobalNode(const EFANode * global_node) const
{
  //Given a global node, create a new local node
  if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
      global_node->category() != EFANode::N_CATEGORY_TEMP)
    EFAError("In createLocalNodeFromGlobalNode node is not global");

  EFANode * new_local_node = NULL;
  unsigned int inode = 0;
  for (; inode < _nodes.size(); ++inode)
  {
    if (_nodes[inode] == global_node)
    {
      new_local_node = new EFANode(inode, EFANode::N_CATEGORY_LOCAL_INDEX);
      break;
    }
  }
  if (!new_local_node)
    EFAError("In createLocalNodeFromGlobalNode could not find global node");

  return new_local_node;
}
Exemple #14
0
bool
EFAFragment3D::isThirdInteriorFace(unsigned int face_id) const
{
  bool is_third_cut = false;
  if (!_host_elem)
    EFAError("in isThirdInteriorFace fragment must have host elem");

  for (unsigned int i = 0; i < _host_elem->numInteriorNodes(); ++i)
  {
    if (_faces[face_id]->containsNode(_host_elem->getInteriorNode(i)->getNode()))
    {
      is_third_cut = true;
      break;
    }
  }
  return is_third_cut;
}
Exemple #15
0
unsigned int
EFAElement::getLocalNodeIndex(EFANode * node) const
{
  unsigned int local_node_id = 99999;
  bool found_local_node = false;
  for (unsigned int i = 0; i < _num_nodes; ++i)
  {
    if (_nodes[i] == node)
    {
      found_local_node = true;
      local_node_id = i;
      break;
    }
  }
  if (!found_local_node)
    EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
  return local_node_id;
}
Exemple #16
0
void
EFAFragment3D::combine_tip_faces()
{
  if (!_host_elem)
    EFAError("In combine_tip_faces() the frag must have host_elem");

  for (unsigned int i = 0; i < _host_elem->numFaces(); ++i)
  {
    std::vector<unsigned int> frag_tip_face_id;
    for (unsigned int j = 0; j < _faces.size(); ++j)
    {
      if (_host_elem->getFace(i)->containsFace(_faces[j]))
        frag_tip_face_id.push_back(j);
    }
    if (frag_tip_face_id.size() == 2) // combine the two frag faces on this elem face
      combine_two_faces(frag_tip_face_id[0], frag_tip_face_id[1], _host_elem->getFace(i));
  }
  // TODO: may need to combine other frag faces that have tip edges
}
void
ElementFragmentAlgorithm::clearAncestry()
{
  _inverse_connectivity.clear();
  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
  {
    if (!Efa::deleteFromMap(_elements, _parent_elements[i]))
      EFAError("Attempted to delete parent element: ",
               _parent_elements[i]->id(),
               " from _elements, but couldn't find it");
  }
  _parent_elements.clear();

  std::map<unsigned int, EFAElement *>::iterator eit;
  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
  {
    EFAElement * curr_elem = eit->second;
    curr_elem->clearParentAndChildren();
    for (unsigned int j = 0; j < curr_elem->numNodes(); j++)
    {
      EFANode * curr_node = curr_elem->getNode(j);
      _inverse_connectivity[curr_node].insert(curr_elem);
    }
  }

  std::map<unsigned int, EFANode *>::iterator mit;
  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
    mit->second->removeParent();

  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
  {
    delete mit->second;
    mit->second = NULL;
  }
  _temp_nodes.clear();

  _new_nodes.clear();
  _child_elements.clear();

  // TODO: Sanity check to make sure that there are no nodes that are not connected
  //      to an element -- there shouldn't be any
}
Exemple #18
0
bool
EFAFragment3D::isFaceInterior(unsigned int face_id) const
{
  if (!_host_elem)
    EFAError("in isFaceInterior() fragment must have host elem");

  bool face_in_elem_face = false;
  for (unsigned int i = 0; i < _host_elem->numFaces(); ++i)
  {
    if (_host_elem->getFace(i)->containsFace(_faces[face_id]))
    {
      face_in_elem_face = true;
      break;
    }
  }
  if (!face_in_elem_face)
    return true; // yes, is interior
  else
    return false;
}
void
ElementFragmentAlgorithm::clearPotentialIsolatedNodes()
{
  // Collect all parent nodes that will be isolated
  std::map<EFANode *, std::vector<EFANode *>> isolate_parent_to_child;
  for (unsigned int i = 0; i < _new_nodes.size(); ++i)
  {
    EFANode * parent_node = _new_nodes[i]->parent();
    if (!parent_node)
      EFAError("a new permanent node must have a parent node!");
    bool isParentNodeInNewElem = false;
    for (unsigned int j = 0; j < _child_elements.size(); ++j)
    {
      if (_child_elements[j]->containsNode(parent_node))
      {
        isParentNodeInNewElem = true;
        break;
      }
    }
    if (!isParentNodeInNewElem)
      isolate_parent_to_child[parent_node].push_back(_new_nodes[i]);
  }

  // For each isolated parent node, pick one of its child new node
  // Then, switch that child with its parent for all new elems
  std::map<EFANode *, std::vector<EFANode *>>::iterator mit;
  for (mit = isolate_parent_to_child.begin(); mit != isolate_parent_to_child.end(); ++mit)
  {
    EFANode * parent_node = mit->first;
    EFANode * child_node = (mit->second)[0]; // need to discard it and swap it back to its parent
    for (unsigned int i = 0; i < _child_elements.size(); ++i)
    {
      if (_child_elements[i]->containsNode(child_node))
        _child_elements[i]->switchNode(parent_node, child_node, true);
    }
    _new_nodes.erase(std::remove(_new_nodes.begin(), _new_nodes.end(), child_node),
                     _new_nodes.end());
    Efa::deleteFromMap(_permanent_nodes, child_node);
  }
}
Exemple #20
0
bool
EFAFragment3D::isConnected(EFAFragment* other_fragment) const
{
  bool is_connected = false;
  EFAFragment3D* other_frag3d = dynamic_cast<EFAFragment3D*>(other_fragment);
  if (!other_frag3d)
    EFAError("in isConnected other_fragment is not of type EFAfragement3D");

  for (unsigned int i = 0; i < _faces.size(); ++i)
  {
    for (unsigned int j = 0; j < other_frag3d->numFaces(); ++j)
    {
      if (_faces[i]->equivalent(other_frag3d->_faces[j]))
      {
        is_connected = true;
        break;
      }
    }
    if (is_connected) break;
  } // i
  return is_connected;
}
unsigned int
ElementFragmentAlgorithm::add2DElements(std::vector<std::vector<unsigned int>> & quads)
{
  unsigned int first_id = 0;
  unsigned int num_nodes = quads[0].size();

  if (quads.size() == 0)
    EFAError("add2DElements called with empty vector of quads");

  for (unsigned int i = 0; i < quads.size(); ++i)
  {
    unsigned int new_elem_id = Efa::getNewID(_elements);
    EFAElement2D * newElem = new EFAElement2D(new_elem_id, num_nodes);
    _elements.insert(std::make_pair(new_elem_id, newElem));

    if (i == 0)
      first_id = new_elem_id;

    for (unsigned int j = 0; j < num_nodes; ++j)
    {
      EFANode * currNode = NULL;
      std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quads[i][j]);
      if (mit == _permanent_nodes.end())
      {
        currNode = new EFANode(quads[i][j], EFANode::N_CATEGORY_PERMANENT);
        _permanent_nodes.insert(std::make_pair(quads[i][j], currNode));
      }
      else
        currNode = mit->second;

      newElem->setNode(j, currNode);
      _inverse_connectivity[currNode].insert(newElem);
    }
    newElem->createEdges();
  }
  return first_id;
}
Exemple #22
0
void
EFAElement::mergeNodes(EFANode* &childNode, EFANode* &childOfNeighborNode, EFAElement* childOfNeighborElem,
                       std::map<unsigned int, EFANode*> &PermanentNodes, std::map<unsigned int, EFANode*> &TempNodes)
{
  // Important: this must be run only on child elements that were just created
  if (!_parent)
    EFAError("no getParent element for child element " << _id << " in mergeNodes");

  EFAElement* childElem = this;
  if (childNode != childOfNeighborNode)
  {
    if (childNode->category() == EFANode::N_CATEGORY_PERMANENT)
    {
      if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
      {
        if (childOfNeighborNode->parent() == childNode) // merge into childNode
        {
          childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
          if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode))
          {
            EFAError("Attempted to delete node: " << childOfNeighborNode->id()
                     << " from PermanentNodes, but couldn't find it");
          }
          childOfNeighborNode = childNode;
        }
        else if (childNode->parent() == childOfNeighborNode) // merge into childOfNeighborNode
        {
        childElem->switchNode(childOfNeighborNode, childNode, true);
          if (!Efa::deleteFromMap(PermanentNodes, childNode))
          {
            EFAError("Attempted to delete node: " << childNode->id()
                     << " from PermanentNodes, but couldn't find it");
          }
          childNode = childOfNeighborNode;
        }
        else if (childNode->parent() != NULL && childNode->parent() == childOfNeighborNode->parent())
        {
          // merge into childNode if both nodes are child permanent
          childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
          if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode)) // delete childOfNeighborNode
          {
            EFAError("Attempted to delete node: " << childOfNeighborNode->id()
                     << " from PermanentNodes, but couldn't find it");
          }
          childOfNeighborNode = childNode;
        }
        else
        {
          EFAError("Attempting to merge nodes: " << childNode->id() << " and "
                   << childOfNeighborNode->id() << " but both are permanent themselves");
        }
      }
      else
      {
        if (childOfNeighborNode->parent() != childNode &&
            childOfNeighborNode->parent() != childNode->parent())
        {
          EFAError("Attempting to merge nodes " << childOfNeighborNode->idCatString() << " and "
                   << childNode->idCatString() << " but neither the 2nd node nor its parent is parent of the 1st");
        }
        childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
        if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
          EFAError("Attempted to delete node: " << childOfNeighborNode->id() << " from TempNodes, but couldn't find it");
        childOfNeighborNode = childNode;
      }
    }
    else if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
    {
      if (childNode->parent() != childOfNeighborNode &&
          childNode->parent() != childOfNeighborNode->parent())
      {
        EFAError("Attempting to merge nodes " << childNode->id() << " and "
                 << childOfNeighborNode->id() << " but neither the 2nd node nor its parent is parent of the 1st");
      }
      childElem->switchNode(childOfNeighborNode, childNode, true);
      if (!Efa::deleteFromMap(TempNodes, childNode))
        EFAError("Attempted to delete node: " << childNode->id() << " from TempNodes, but couldn't find it");
      childNode = childOfNeighborNode;
    }
    else //both nodes are temporary -- create new permanent node and delete temporary nodes
    {
      unsigned int new_node_id = Efa::getNewID(PermanentNodes);
      EFANode* newNode = new EFANode(new_node_id,EFANode::N_CATEGORY_PERMANENT,childNode->parent());
      PermanentNodes.insert(std::make_pair(new_node_id,newNode));

      childOfNeighborElem->switchNode(newNode, childOfNeighborNode, true);
      childElem->switchNode(newNode, childNode, true);

      if (childNode->parent() != childOfNeighborNode->parent())
      {
        EFAError("Attempting to merge nodes " << childNode->id() << " and "
                 << childOfNeighborNode->id() << " but they don't share a common parent");
      }

      if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
        EFAError("Attempted to delete node: " << childOfNeighborNode->id() << " from TempNodes, but couldn't find it");
      if (!Efa::deleteFromMap(TempNodes, childNode))
        EFAError("Attempted to delete node: " << childNode->id() << " from TempNodes, but couldn't find it");
      childOfNeighborNode = newNode;
      childNode = newNode;
    }
  }
}