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."); } } }
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; }
/// 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; }
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; }
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 } } } } } } }
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); }
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; }
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; } }
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) ; }
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; }
/** * 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; }