Пример #1
0
    void Refiner::removeChildElements(SetOfEntities& children_to_be_removed)
    {
      const unsigned FAMILY_TREE_RANK = m_eMesh.element_rank() + 1u;
      for(SetOfEntities::iterator child_it = children_to_be_removed.begin();
          child_it != children_to_be_removed.end(); ++child_it)
        {
          stk::mesh::Entity *child = *child_it;

          if (m_eMesh.isGhostElement(*child))
          {
              throw std::logic_error("Refiner::removeChildElements couldn't remove element, Ghost is true.");
          }
          if ( ! m_eMesh.get_bulk_data()->destroy_entity( child ) )
            {
              CellTopology cell_topo(stk::percept::PerceptMesh::get_cell_topology(*child));

              //const mesh::PairIterRelation elem_relations = child->relations(child->entity_rank()+1);
              const mesh::PairIterRelation child_to_ft_relations = child->relations(FAMILY_TREE_RANK);
#if DEBUG_UNREF
              std::cout << "tmp Refiner::unrefineTheseElements couldn't remove element  cell= " << cell_topo.getName() << std::endl;
              std::cout << "tmp child_to_ft_relations.size() = " << child_to_ft_relations.size() << std::endl;
              //std::cout << "tmp ft_id loc, outerloop= " << child_to_family_tree_relations[0].entity()->identifier() << " " << family_tree_id << std::endl;

              m_eMesh.print_entity(std::cout, *child);
#endif

              throw std::logic_error("Refiner::unrefineTheseElements couldn't remove element, destroy_entity returned false.");
            }
        }
    }
Пример #2
0
    void Refiner::
    getDeletedNodes(NodeSetType& deleted_nodes, const NodeSetType& kept_nodes, ElementUnrefineCollection& elements_to_unref)
    {
      // mark deleted nodes (nodes in list of elements_to_unref
      for (ElementUnrefineCollection::iterator u_iter = elements_to_unref.begin();
           u_iter != elements_to_unref.end(); ++u_iter)
        {
          stk::mesh::Entity * element = *u_iter;


          if (!m_eMesh.isGhostElement(*element))
          //if (m_eMesh.isChildElement(*element) && !m_eMesh.isGhostElement(*element))
          {
            const mesh::PairIterRelation elem_nodes = element->relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

            for (unsigned inode=0; inode < elem_nodes.size(); inode++)
              {
                stk::mesh::Entity *node = elem_nodes[inode].entity();
                bool in_kept_nodes_set = kept_nodes.find( node ) != kept_nodes.end();
                if (!in_kept_nodes_set)
                  {
                    deleted_nodes.insert(node);
#if DEBUG_UNREF
                    std::cout << "tmp deleted node: " << *node << " ";
                    m_eMesh.print_entity(std::cout, *node);
#endif
                  }
              }
          }
        }
      if (DEBUG_UNREF_1) std::cout << "tmp kept_nodes size= " << kept_nodes.size() << " deleted_nodes size= " << deleted_nodes.size() << std::endl;

    }
Пример #3
0
    /// return true if topology is bad
    bool TopologyVerifier::isTopologyBad( mesh::Entity  &elem)
    {
      const CellTopologyData * const top = stk::percept::PerceptMesh::get_cell_topology(elem);

      const mesh::PairIterRelation elem_nodes = elem.relations( stk::mesh::fem::FEMMetaData::NODE_RANK );

#if 0
      std::cout << "top->node_count = " << top->node_count << "\n";
      std::cout << "elem_nodes.size() = " << elem_nodes.size() << "\n";
      std::cout.flush();
#endif

      for (unsigned j = 0; j < elem_nodes.size()-1; j++)
        {
          mesh::Entity & node = * elem_nodes[ j ].entity();

          for ( unsigned i = j+1 ; i < top->node_count ; ++i ) {
            {
              mesh::Entity & nodei = * elem_nodes[ i ].entity();
              if (node.identifier() == nodei.identifier())
                {
                  return true;
                }
            }
          }
        }
      return false;
    }
Пример #4
0
    ElementUnrefineCollection TestLocalRefinerTri_N_2::buildTestUnrefineList()
    {
      ElementUnrefineCollection elements_to_unref;

      const vector<stk_classic::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

      for ( vector<stk_classic::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k ) 
        {
          //if (removePartSelector(**k)) 
          {
            stk_classic::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
              {
                stk_classic::mesh::Entity& element = bucket[ientity];

                // FIXME
                // skip elements that are already a parent (if there's no family tree yet, it's not a parent, so avoid throwing an error is isParentElement)
                const bool check_for_family_tree = false;  
                bool isParent = m_eMesh.isParentElement(element, check_for_family_tree);
              
                if (isParent)
                  continue;
                
                const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK);

                if (elem_nodes.size() && m_eMesh.isChildWithoutNieces(element, false) )
                  {
                    bool found = true;
                    for (unsigned inode=0; inode < elem_nodes.size(); inode++)
                      {
                        stk_classic::mesh::Entity *node = elem_nodes[inode].entity();
                        double *coord = stk_classic::mesh::field_data( *m_eMesh.get_coordinates_field(), *node );
                        if (coord[0] > 2.1 || coord[1] > 2.1)
                          {
                            found = false;
                            break;
                          }
                      }
                    if (found)
                      {
                        elements_to_unref.insert(&element);
                        //std::cout << "tmp element id= " << element.identifier() << " ";
                        //m_eMesh.print_entity(std::cout, element);
                      }
                  }
              }
          }
        }

      return elements_to_unref;
    }
    ElementUnrefineCollection TestLocalRefinerTri_N_1::buildTestUnrefineList()
    {
      ElementUnrefineCollection elements_to_unref;

      const vector<stk::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

      for ( vector<stk::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k ) 
        {
          //if (removePartSelector(**k)) 
          {
            stk::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
              {
                stk::mesh::Entity& element = bucket[ientity];
#if 0
                // add ghost elements here, but skip them in Refiner::unrefineTheseElements
                bool elementIsGhost = m_eMesh.isGhostElement(element);
                if (elementIsGhost)
                  continue;
#endif
                
                const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

                if (elem_nodes.size() && m_eMesh.isChildElement(element, false))
                  {
                    bool found = true;
                    for (unsigned inode=0; inode < elem_nodes.size(); inode++)
                      {
                        stk::mesh::Entity *node = elem_nodes[inode].entity();
                        double *coord = stk::mesh::field_data( *m_eMesh.get_coordinates_field(), *node );
                        if (coord[0] > 2.1 || coord[1] > 2.1)
                          {
                            found = false;
                            break;
                          }
                      }
                    if (found)
                      {
                        elements_to_unref.insert(&element);
                        //std::cout << "tmp element id= " << element.identifier() << " ";
                        //m_eMesh.print_entity(std::cout, element);
                      }
                  }
              }
          }
        }

      return elements_to_unref;
    }
Пример #6
0
    void Refiner::
    getKeptNodes(NodeSetType& kept_nodes, ElementUnrefineCollection& elements_to_unref)
    {
      bool doTest=true;

      // mark kept nodes
      const vector<stk::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

      for ( vector<stk::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k )
        {
          //if (removePartSelector(**k))
          {
            stk::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
              {
                stk::mesh::Entity& element = bucket[ientity];

                const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

                //if (m_eMesh.isLeafElement(element) && !m_eMesh.isGhostElement(element))
                if (!doTest || (elem_nodes.size() && m_eMesh.isLeafElement(element)) )
                  {
                    bool in_unref_set = elements_to_unref.find( &element ) != elements_to_unref.end();
                    //bool isGhostElement = m_eMesh.isGhostElement(element);
                    //if (!in_unref_set && !isGhostElement)
                    if (!in_unref_set)
                      {
                        for (unsigned inode=0; inode < elem_nodes.size(); inode++)
                          {
                            stk::mesh::Entity *node = elem_nodes[inode].entity();
                            kept_nodes.insert(node);
#if DEBUG_UNREF
                            std::cout << "tmp kept node: " << *node << " ";
                            m_eMesh.print_entity(std::cout, *node);
#endif

                          }
                      }
                  }
              }
          }
        }


    }
Пример #7
0
    void
    Refiner::
    unrefineAll()
    {
      ElementUnrefineCollection elements_to_unref;

      const vector<stk::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

      for ( vector<stk::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k )
        {
          //if (removePartSelector(**k))
          {
            stk::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
              {
                stk::mesh::Entity& element = bucket[ientity];
                // FIXME
                // skip elements that are already a parent (if there's no family tree yet, it's not a parent, so avoid throwing an error in isParentElement)
                const bool check_for_family_tree = false;  
                bool isParent = m_eMesh.isParentElement(element, check_for_family_tree);
              
                if (isParent)
                  continue;

                const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

                if (elem_nodes.size() && (m_eMesh.hasFamilyTree(element) && m_eMesh.isChildWithoutNieces(element, false) ) )
                  {
                    bool elementIsGhost = m_eMesh.isGhostElement(element);

                    if (!elementIsGhost)
                      {
                        elements_to_unref.insert(&element);
                      }
                  }
              }
          }
        }
      unrefineTheseElements(elements_to_unref);
    }
Пример #8
0
ElementUnrefineCollection IEdgeAdapter::buildUnrefineList()
{
    ElementUnrefineCollection elements_to_unref;

    const vector<stk::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

    for ( vector<stk::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k )
    {
        {
            stk::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
            {
                stk::mesh::Entity& element = bucket[ientity];

                // FIXME
                // skip elements that are already a parent (if there's no family tree yet, it's not a parent, so avoid throwing an error is isParentElement)
                const bool check_for_family_tree = false;
                bool isParent = m_eMesh.isParentElement(element, check_for_family_tree);

                if (isParent)
                    continue;

                const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

                if (elem_nodes.size() && m_eMesh.isChildWithoutNieces(element, false))
                {
                    int markInfo = markUnrefine(element);
                    if (markInfo & DO_UNREFINE)
                    {
                        elements_to_unref.insert(&element);
                        //std::cout << "tmp unref element id= " << element.identifier() << std::endl;
                        //m_eMesh.print_entity(std::cout, element);
                    }
                }
            }
        }
    }

    return elements_to_unref;
}
Пример #9
0
namespace adapt {

//========================================================================================================================
//========================================================================================================================
//========================================================================================================================
/**
 * An IEdgeAdapter is an abstract base class for derived classes that are required to overload the mark method,
 *    which provides info such as the element the edge belongs to, which edge ordinal it is, the nodes of the edge
 *    and the edge coordinates.
 */
class IEdgeAdapter : public IAdapter
{
public:
    IEdgeAdapter(percept::PerceptMesh& eMesh, UniformRefinerPatternBase & bp, stk::mesh::FieldBase *proc_rank_field=0);

    /// can be overriden
    virtual ElementUnrefineCollection  buildUnrefineList();

protected:

    /// Client supplies these methods - given an element, which edge, and the nodes on the edge, return instruction on what to do to the edge,
    ///    DO_NOTHING (nothing), DO_REFINE (refine), DO_UNREFINE

    virtual int mark(const stk::mesh::Entity& element, unsigned which_edge, stk::mesh::Entity & node0, stk::mesh::Entity & node1,
                     double *coord0, double *coord1, std::vector<int>* existing_edge_marks) = 0;

    /// This convenience method calls mark and if all edges are marked for unrefine, it returns -1 to unrefine the element.
    /// This method can be overriden to allow for an "element-based" determination that doesn't need to visit edges.
    virtual int markUnrefine(const stk::mesh::Entity& element);

    virtual void
    refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk::mesh::Entity& element,
                      vector<NeededEntityType>& needed_entity_ranks);


};

IEdgeAdapter::IEdgeAdapter(percept::PerceptMesh& eMesh, UniformRefinerPatternBase &  bp, stk::mesh::FieldBase *proc_rank_field) :
    IAdapter(eMesh, bp, proc_rank_field)
{
}

void IEdgeAdapter::
refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk::mesh::Entity& element,
                  vector<NeededEntityType>& needed_entity_ranks)
{
    const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element);

    CellTopology cell_topo(cell_topo_data);
    const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

    VectorFieldType* coordField = m_eMesh.get_coordinates_field();

    for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++)
    {
        unsigned numSubDimNeededEntities = 0;
        stk::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first;

        if (needed_entity_rank == m_eMesh.edge_rank())
        {
            numSubDimNeededEntities = cell_topo_data->edge_count;
        }
        else if (needed_entity_rank == m_eMesh.face_rank())
        {
            numSubDimNeededEntities = cell_topo_data->side_count;
            throw std::runtime_error("IEdgeAdapter::apply can't use IEdgeAdapter for RefinerPatterns that require face nodes");
        }
        else if (needed_entity_rank == m_eMesh.element_rank())
        {
            numSubDimNeededEntities = 1;
            throw std::runtime_error("IEdgeAdapter::apply can't use IEdgeAdapter for RefinerPatterns that require volume nodes");
        }

        // see how many edges are already marked
        int num_marked=0;
        std::vector<int> edge_marks(numSubDimNeededEntities,0);
        if (needed_entity_rank == m_eMesh.edge_rank())
        {
            for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++)
            {
                bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd);
                if (!is_empty)
                {
                    edge_marks[iSubDimOrd] = 1;
                    ++num_marked;
                }
            }
        }

        for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++)
        {
            if (needed_entity_rank == m_eMesh.edge_rank())
            {
                stk::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity();
                stk::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity();
                double * const coord0 = stk::mesh::field_data( *coordField , node0 );
                double * const coord1 = stk::mesh::field_data( *coordField , node1 );


                int markInfo = mark(element, iSubDimOrd, node0, node1, coord0, coord1, &edge_marks);

                bool needNodes = (DO_REFINE & markInfo);
                {
                    (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, needNodes);
                }
            }

        } // iSubDimOrd
    } // ineed_ent
}

int IEdgeAdapter::markUnrefine(const stk::mesh::Entity& element)
{
    const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element);

    CellTopology cell_topo(cell_topo_data);
    const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

    VectorFieldType* coordField = m_eMesh.get_coordinates_field();

    unsigned numSubDimNeededEntities = 0;
    numSubDimNeededEntities = cell_topo_data->edge_count;

    bool unrefAllEdges = true;
    for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++)
    {
        stk::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity();
        stk::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity();
        double * const coord0 = stk::mesh::field_data( *coordField , node0 );
        double * const coord1 = stk::mesh::field_data( *coordField , node1 );

        int markInfo = mark(element, iSubDimOrd, node0, node1, coord0, coord1, 0);
        bool do_unref = markInfo & DO_UNREFINE;
        if (!do_unref)
        {
            unrefAllEdges = false;
            break;
        }
    }
    if (unrefAllEdges)
        return -1;
    else
        return 0;
}

ElementUnrefineCollection IEdgeAdapter::buildUnrefineList()
{
    ElementUnrefineCollection elements_to_unref;

    const vector<stk::mesh::Bucket*> & buckets = m_eMesh.get_bulk_data()->buckets( m_eMesh.element_rank() );

    for ( vector<stk::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k )
    {
        {
            stk::mesh::Bucket & bucket = **k ;

            const unsigned num_entity_in_bucket = bucket.size();
            for (unsigned ientity = 0; ientity < num_entity_in_bucket; ientity++)
            {
                stk::mesh::Entity& element = bucket[ientity];

                // FIXME
                // skip elements that are already a parent (if there's no family tree yet, it's not a parent, so avoid throwing an error is isParentElement)
                const bool check_for_family_tree = false;
                bool isParent = m_eMesh.isParentElement(element, check_for_family_tree);

                if (isParent)
                    continue;

                const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);

                if (elem_nodes.size() && m_eMesh.isChildWithoutNieces(element, false))
                {
                    int markInfo = markUnrefine(element);
                    if (markInfo & DO_UNREFINE)
                    {
                        elements_to_unref.insert(&element);
                        //std::cout << "tmp unref element id= " << element.identifier() << std::endl;
                        //m_eMesh.print_entity(std::cout, element);
                    }
                }
            }
        }
    }

    return elements_to_unref;
}


}
Пример #10
0
unsigned
Albany::STKDiscretization::determine_local_side_id( const stk::mesh::Entity & elem , stk::mesh::Entity & side ) {

  using namespace stk;

  const CellTopologyData * const elem_top = mesh::fem::get_cell_topology( elem ).getCellTopologyData();

  const mesh::PairIterRelation elem_nodes = elem.relations( mesh::fem::FEMMetaData::NODE_RANK );
  const mesh::PairIterRelation side_nodes = side.relations( mesh::fem::FEMMetaData::NODE_RANK );

  int side_id = -1 ;

  if(elem_nodes.size() == 0 || side_nodes.size() == 0){ // Node relations are not present, look at elem->face

    int elem_rank = elem.entity_rank();
    const mesh::PairIterRelation elem_sides = elem.relations( elem_rank - 1);

    for ( unsigned i = 0 ; i < elem_sides.size() ; ++i ) {

      const stk::mesh::Entity & elem_side = *elem_sides[i].entity();

      if(elem_side.identifier() == side.identifier()){ // Found the local side in the element

         side_id = static_cast<int>(i);

         return side_id;

      }

    }

    if ( side_id < 0 ) {
      std::ostringstream msg ;
      msg << "determine_local_side_id( " ;
      msg << elem_top->name ;
      msg << " , Element[ " ;
      msg << elem.identifier();
      msg << " ]{" ;
      for ( unsigned i = 0 ; i < elem_sides.size() ; ++i ) {
        msg << " " << elem_sides[i].entity()->identifier();
      }
      msg << " } , Side[ " ;
      msg << side.identifier();
      msg << " ] ) FAILED" ;
      throw std::runtime_error( msg.str() );
    }

  }
  else { // Conventional elem->node - side->node connectivity present

    for ( unsigned i = 0 ; side_id == -1 && i < elem_top->side_count ; ++i ) {
      const CellTopologyData & side_top = * elem_top->side[i].topology ;
      const unsigned     * side_map =   elem_top->side[i].node ;

      if ( side_nodes.size() == side_top.node_count ) {

        side_id = i ;

        for ( unsigned j = 0 ;
              side_id == static_cast<int>(i) && j < side_top.node_count ; ++j ) {

          mesh::Entity * const elem_node = elem_nodes[ side_map[j] ].entity();

          bool found = false ;

          for ( unsigned k = 0 ; ! found && k < side_top.node_count ; ++k ) {
            found = elem_node == side_nodes[k].entity();
          }

          if ( ! found ) { side_id = -1 ; }
        }
      }
    }

    if ( side_id < 0 ) {
      std::ostringstream msg ;
      msg << "determine_local_side_id( " ;
      msg << elem_top->name ;
      msg << " , Element[ " ;
      msg << elem.identifier();
      msg << " ]{" ;
      for ( unsigned i = 0 ; i < elem_nodes.size() ; ++i ) {
        msg << " " << elem_nodes[i].entity()->identifier();
      }
      msg << " } , Side[ " ;
      msg << side.identifier();
      msg << " ]{" ;
      for ( unsigned i = 0 ; i < side_nodes.size() ; ++i ) {
        msg << " " << side_nodes[i].entity()->identifier();
      }
      msg << " } ) FAILED" ;
      throw std::runtime_error( msg.str() );
    }
  }

  return static_cast<unsigned>(side_id) ;
}
Пример #11
0
    void Refiner::
    filterUnrefSet(ElementUnrefineCollection& elements_to_unref)
    {
      int print_filter_info = DEBUG_UNREF_1;
      if (print_filter_info)  std::cout << "P["<< m_eMesh.get_rank() << "] filterUnrefSet: initial set size = " << elements_to_unref.size() << std::endl;
      
      const unsigned FAMILY_TREE_RANK = m_eMesh.element_rank() + 1u;
      ElementUnrefineCollection elements_to_unref_copy;

      typedef std::set<stk::mesh::Entity *> SetOfEntities;

      int num_is_parent = 0;
      int num_elem_nodes_0 = 0;
      int num_has_nieces = 0;

      for (ElementUnrefineCollection::iterator u_iter = elements_to_unref.begin();
           u_iter != elements_to_unref.end(); ++u_iter)
        {
          stk::mesh::Entity& element = **u_iter;
          
          const bool check_for_family_tree = false;  
          bool isParent = m_eMesh.isParentElement(element, check_for_family_tree);

          if (isParent)
            {
              ++num_is_parent;
              continue;
            }

          const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
          int elem_nodes_size = elem_nodes.size();
          bool has_no_nieces = m_eMesh.hasFamilyTree(element) && m_eMesh.isChildWithoutNieces(element, false);

          if (!elem_nodes_size) num_elem_nodes_0++;
          if (!has_no_nieces) num_has_nieces++;
          if (elem_nodes_size && has_no_nieces)
            {
              stk::mesh::PairIterRelation child_to_family_tree_relations = element.relations(FAMILY_TREE_RANK);

              // look for level 0 only - these are children with no children
              unsigned child_ft_level_0 = m_eMesh.getFamilyTreeRelationIndex(FAMILY_TREE_LEVEL_0, element);

              stk::mesh::Entity *family_tree = child_to_family_tree_relations[child_ft_level_0].entity();
              stk::mesh::PairIterRelation family_tree_relations = family_tree->relations(m_eMesh.element_rank());
              if (family_tree_relations.size() == 0)
                {
                  throw std::logic_error("Refiner::filterUnrefSet family_tree_relations.size() == 0");
                }

              SetOfEntities side_elem_set;

              bool all_siblings_in_unref_set = true;
              bool all_side_sets_ok = true;

              for (unsigned ichild=1; ichild < family_tree_relations.size(); ichild++)
                {
                  stk::mesh::Entity *child = family_tree_relations[ichild].entity();
                  if (m_eMesh.isParentElement(*child))
                    {
                      throw std::logic_error("Refiner::filterUnrefSet isParentElement not expected");
                    }
                  bool in_unref_set = elements_to_unref.find(child) != elements_to_unref.end();
                  if (!in_unref_set)
                    {
                      all_siblings_in_unref_set = false;
                      break;
                    }

                  {
                    mesh::PairIterRelation side_relations = child->relations(m_eMesh.side_rank());
                    for (unsigned jside = 0; jside < side_relations.size(); jside++)
                      {
                        stk::mesh::Entity * side_element = side_relations[jside].entity();
                        side_elem_set.insert(side_element);

                        if (0)
                        {
                            stk::mesh::PairIterRelation side_elem_to_family_tree_relations = side_element->relations(FAMILY_TREE_RANK);
                            stk::mesh::Entity *side_elem_family_tree_0 = side_elem_to_family_tree_relations[0].entity();
                            std::cout << "side_elem_family_tree_0= " << side_elem_family_tree_0 << std::endl;
                        }

                        // FIXME if (!m_eMesh.hasFamilyTree(*side_element) || !m_eMesh.isChildWithoutNieces(*side_element))
                        if (m_eMesh.hasFamilyTree(*side_element) && !m_eMesh.isChildWithoutNieces(*side_element))
                          {
                            //std::cout << "error 35" << std::endl;
                            all_side_sets_ok=false;
                            break;
                          }
                      }
                  }
                }

              if (all_side_sets_ok)
                {
                  for (unsigned ichild=1; ichild < family_tree_relations.size(); ichild++)
                    {
                      stk::mesh::Entity *child = family_tree_relations[ichild].entity();

                      {
                        mesh::PairIterRelation side_relations = child->relations(m_eMesh.side_rank());
                        for (unsigned jside = 0; jside < side_relations.size(); jside++)
                          {
                            stk::mesh::Entity * side_element = side_relations[jside].entity();
                            //side_elem_set.insert(side_element);

                            if (!m_eMesh.hasFamilyTree(*side_element)) continue;

                            stk::mesh::PairIterRelation side_elem_to_family_tree_relations = side_element->relations(FAMILY_TREE_RANK);

                            // look for level 0 only - these are children with no children
                            unsigned side_elem_ft_level_0 = m_eMesh.getFamilyTreeRelationIndex(FAMILY_TREE_LEVEL_0, *side_element);

                            stk::mesh::Entity *side_elem_family_tree = side_elem_to_family_tree_relations[side_elem_ft_level_0].entity();
                            stk::mesh::PairIterRelation side_elem_family_tree_relations = side_elem_family_tree->relations(m_eMesh.side_rank());
                            for (unsigned ise_child=1; ise_child < side_elem_family_tree_relations.size(); ise_child++)
                              {
                                stk::mesh::Entity *se_sibling = side_elem_family_tree_relations[ise_child].entity();
                                bool in_set = (side_elem_set.find(se_sibling) != side_elem_set.end());
                                if (!in_set)
                                  {
                                    all_side_sets_ok = false;
                                    break;
                                  }
                              }
                          }
                      }
                    }
                }

              if (all_siblings_in_unref_set && all_side_sets_ok)
                {
                  for (unsigned ichild=1; ichild < family_tree_relations.size(); ichild++)
                    {
                      stk::mesh::Entity *child = family_tree_relations[ichild].entity();
                      elements_to_unref_copy.insert(child);
                    }
                }
            }
        }
      if (print_filter_info) std::cout << "tmp filterUnrefSet::elements_to_unref.size = " << elements_to_unref.size() 
                                       << " filtered size= " << elements_to_unref_copy.size() 
                                       << " num_has_nieces= " << num_has_nieces
                                       << " num_elem_nodes_0= " << num_elem_nodes_0
                                       << " num_is_parent= " << num_is_parent
                                       << std::endl;
      elements_to_unref = elements_to_unref_copy;
    }
Пример #12
0
    /**
     * Algorithm:
     *   1. for each element, loop over its edges, for each edge's node, loop over elements attached to node
     *   1a.   for each neighboring element, check if current edge is invalid
     */
    bool TopologyVerifier::isTopologyBad(stk::mesh::BulkData& bulk) //, stk::mesh::Part& mesh_part )
    {
      const stk::mesh::fem::FEMMetaData& meta = stk::mesh::fem::FEMMetaData::get(bulk);

      stk::mesh::Field<double, stk::mesh::Cartesian> *coord_field =
        meta.get_field<stk::mesh::Field<double, stk::mesh::Cartesian> >("coordinates");

      //mesh::Selector select_owned( meta_data.locally_owned_part() );

      const std::vector<mesh::Bucket*> & buckets = bulk.buckets(meta.element_rank() );

      for ( std::vector<mesh::Bucket *>::const_iterator ik = buckets.begin() ; ik != buckets.end() ; ++ik )
        {
          // if ( select_owned( **ik ) ) {...

          const mesh::Bucket & bucket = **ik ;

          // Number of elems in this bucket of elems and elem field data
          const unsigned number_elems = bucket.size();

          double * elem_node_data = field_data( *coord_field , bucket.begin() );
          //double * elem_centroid_data = field_data( elem_centroid_field , bucket.begin() );

          // FIXME
          if (0) { elem_node_data[0]++;}

#if 1
          const CellTopologyData * const bucket_cell_topo = stk::percept::PerceptMesh::get_cell_topology(bucket);
          int bucket_shardsId = ShardsInterfaceTable::s_singleton.lookupShardsId(bucket_cell_topo->name);
#endif

          //if (0) { std::cout << bucket_cell_topo->name; }
          if (0) { std::cout << "bucket_shardsId= " << bucket_shardsId << " name= " << bucket_cell_topo->name <<  std::endl; }

          if (0) { std::cout << "number_elems= " << number_elems << std::endl;}

          for ( unsigned i = 0 ; i < number_elems ; ++i)
            {
              mesh::Entity & elem = bucket[i] ;
              bool isDuplicateNode = isTopologyBad(elem);
              if (isDuplicateNode)
                {
                  std::cout << "duplicate node found: elem = " << elem << std::endl;
                  return true;
                }
              if (0) std::cout << "elemOfBucket= " << elem << std::endl;
              const mesh::PairIterRelation elem_nodes = elem.relations( stk::mesh::fem::FEMMetaData::NODE_RANK );

              //const CellTopologyData * const cell_topo = stk::percept::PerceptMesh::get_cell_topology(elem);
              const CellTopologyData * const cell_topo = stk::percept::PerceptMesh::get_cell_topology(elem);
              int shardsId = ShardsInterfaceTable::s_singleton.lookupShardsId(cell_topo->name);
              if (0) { std::cout << "shardsId= " << shardsId << " name= " << cell_topo->name <<  std::endl; }

              for (unsigned iedgeOrd = 0; iedgeOrd < cell_topo->edge_count; iedgeOrd++)
                {
                  //const CellTopologyData_Subcell& edge =

                  unsigned in0 = cell_topo->edge[iedgeOrd].node[0];
                  unsigned in1 = cell_topo->edge[iedgeOrd].node[1];

                  MyEdge<unsigned> potential_bad_edge(elem_nodes[in0].entity()->identifier(), elem_nodes[in1].entity()->identifier());
                  //if (potential_bad_edge.getId0() == 3 && potential_bad_edge.getId1() == 6)
                  if (0) std::cout << "potential_bad_edge: " << potential_bad_edge.getId0() << " " << potential_bad_edge.getId1() << std::endl;
                }
              for (unsigned iedgeOrd = 0; iedgeOrd < cell_topo->edge_count; iedgeOrd++)
                {
                  //const CellTopologyData_Subcell& edge =

                  unsigned in0 = cell_topo->edge[iedgeOrd].node[0];
                  unsigned in1 = cell_topo->edge[iedgeOrd].node[1];

                  MyEdge<unsigned> potential_bad_edge(elem_nodes[in0].entity()->identifier(), elem_nodes[in1].entity()->identifier());
                  //if (potential_bad_edge.getId0() == 3 && potential_bad_edge.getId1() == 6)
                  if (0) std::cout << "potential_bad_edge: " << potential_bad_edge.getId0() << " " << potential_bad_edge.getId1() << std::endl;

                  if (0 && MyEdge<unsigned>(3,6) == potential_bad_edge)
                    {
                      std::cout << "bad edge" << std::endl;
                    }

                  for (unsigned inodeOnPotBadEdge = 0; inodeOnPotBadEdge < 2; inodeOnPotBadEdge++)
                    {
                      unsigned inodeOnPotBadEdgeInElem = cell_topo->edge[iedgeOrd].node[inodeOnPotBadEdge];

                      const mesh::PairIterRelation node_elems = elem_nodes[inodeOnPotBadEdgeInElem].entity()->relations( meta.element_rank() );
                      unsigned num_elems_on_node = node_elems.size();

                      for (unsigned iele = 0; iele < num_elems_on_node; iele++)
                        {
                          mesh::Entity & elemOnNode = *node_elems[iele].entity();
                          const mesh::PairIterRelation elemOnNode_nodes = elemOnNode.relations( stk::mesh::fem::FEMMetaData::NODE_RANK );

                          const CellTopologyData * const local_cell_topo = stk::percept::PerceptMesh::get_cell_topology(elemOnNode);
                          int local_shardsId = ShardsInterfaceTable::s_singleton.lookupShardsId(local_cell_topo->name);
                          //if (1) { std::cout << "shardsId= " << shardsId << " name= " << cell_topo->name <<  std::endl; }

                          if (0) std::cout << "elemOnNode= " << elemOnNode << std::endl;
                          unsigned num_invalid_edges = m_invalid_edge_set[local_shardsId].size();
                          if (0) { std::cout << num_invalid_edges; }
                          for (invalid_edge_set_type::iterator inv_edge = m_invalid_edge_set[local_shardsId].begin();
                               inv_edge != m_invalid_edge_set[local_shardsId].end(); inv_edge++)
                            {
                              MyEdge<unsigned> globalIdInvEdge( elemOnNode_nodes[ (*inv_edge).getId0()].entity()->identifier(),
                                                                elemOnNode_nodes[ (*inv_edge).getId1()].entity()->identifier() );

                              if (0) std::cout << "globalIdInvEdge: " << globalIdInvEdge.getId0() << " " << globalIdInvEdge.getId1() << std::endl;
                              if(potential_bad_edge == globalIdInvEdge)
                                {
                                  return true;
                                }
                            }
                        }
                    }
                }


            }
        }
      return false;
    }