inline stk::mesh::Entity get_face_between_element_ids(stk::mesh::ElemElemGraph& graph, stk::mesh::BulkData& bulkData, stk::mesh::EntityId elem1Id, stk::mesh::EntityId elem2Id) { stk::mesh::Entity elem1 = bulkData.get_entity(stk::topology::ELEM_RANK, elem1Id); stk::mesh::Entity elem2 = bulkData.get_entity(stk::topology::ELEM_RANK, elem2Id); bool isElem1LocallyOwnedAndValid = bulkData.is_valid(elem1) && bulkData.bucket(elem1).owned(); bool isElem2LocallyOwnedAndValid = bulkData.is_valid(elem2) && bulkData.bucket(elem2).owned(); stk::mesh::Entity face_between_elem1_and_elem2; if(isElem1LocallyOwnedAndValid && isElem2LocallyOwnedAndValid) { int side = graph.get_side_from_element1_to_locally_owned_element2(elem1, elem2); EXPECT_TRUE(side != -1); face_between_elem1_and_elem2 = stk::mesh::impl::get_side_for_element(bulkData, elem1, side); } else if(isElem1LocallyOwnedAndValid) { int side = graph.get_side_from_element1_to_remote_element2(elem1, elem2Id); EXPECT_TRUE(side != -1); face_between_elem1_and_elem2 = stk::mesh::impl::get_side_for_element(bulkData, elem1, side); } else if(isElem2LocallyOwnedAndValid) { int side = graph.get_side_from_element1_to_remote_element2(elem2, elem1Id); EXPECT_TRUE(side != -1); face_between_elem1_and_elem2 = stk::mesh::impl::get_side_for_element(bulkData, elem2, side); } return face_between_elem1_and_elem2; }
// ======================================================================== void process_surface_entity(const Ioss::SideSet* sset , stk::mesh::BulkData & bulk) { assert(sset->type() == Ioss::SIDESET); const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); const stk::mesh::EntityRank element_rank = stk::topology::ELEMENT_RANK; int block_count = sset->block_count(); for (int i=0; i < block_count; i++) { Ioss::SideBlock *block = sset->get_block(i); if (stk::io::include_entity(block)) { std::vector<int> side_ids ; std::vector<int> elem_side ; stk::mesh::Part * const side_block_part = meta.get_part(block->name()); stk::mesh::EntityRank side_rank = side_block_part->primary_entity_rank(); block->get_field_data("ids", side_ids); block->get_field_data("element_side", elem_side); assert(side_ids.size() * 2 == elem_side.size()); stk::mesh::PartVector add_parts( 1 , side_block_part ); size_t side_count = side_ids.size(); std::vector<stk::mesh::Entity> sides(side_count); for(size_t is=0; is<side_count; ++is) { stk::mesh::Entity const elem = bulk.get_entity(element_rank, elem_side[is*2]); // If NULL, then the element was probably assigned to an // element block that appears in the database, but was // subsetted out of the analysis mesh. Only process if // non-null. if (bulk.is_valid(elem)) { // Ioss uses 1-based side ordinal, stk::mesh uses 0-based. // Hence the '-1' in the following line. int side_ordinal = elem_side[is*2+1] - 1 ; stk::mesh::Entity side = stk::mesh::Entity(); if (side_rank == 2) { side = stk::mesh::declare_element_side(bulk, side_ids[is], elem, side_ordinal); } else { side = stk::mesh::declare_element_edge(bulk, side_ids[is], elem, side_ordinal); } bulk.change_entity_parts( side, add_parts ); sides[is] = side; } else { sides[is] = stk::mesh::Entity(); } } const stk::mesh::FieldBase *df_field = stk::io::get_distribution_factor_field(*side_block_part); if (df_field != NULL) { stk::io::field_data_from_ioss(bulk, df_field, sides, block, "distribution_factors"); } } } }
stk::mesh::Entity create_side_and_add_to_shared_entity_list(stk::mesh::Entity element, stk::mesh::EntityRank side_rank, const stk::mesh::EntityVector& nodes, const stk::mesh::shared_entity_type &shared_entity_other_proc, stk::mesh::BulkData& bulkData, std::vector<stk::mesh::shared_entity_type>& shared_entities_this_proc, int other_proc_id, stk::mesh::Part& root_topo_part) { stk::mesh::Entity side = stk::unit_test_util::declare_element_to_sub_topology_with_nodes(bulkData, element, nodes, shared_entity_other_proc.global_key.id(), side_rank, root_topo_part); ThrowRequireWithSierraHelpMsg(bulkData.is_valid(side)); add_side_to_shared_entities(side, shared_entities_this_proc, shared_entity_other_proc, other_proc_id); return side; }
void convert_elem_sides_pairs_into_sideset(const stk::mesh::BulkData& bulk, const std::vector<int>& elem_side, stk::mesh::SideSet& sideset) { for(size_t is=0; is<elem_side.size() / 2; ++is) { stk::mesh::Entity const elem = bulk.get_entity(stk::topology::ELEMENT_RANK, elem_side[is*2]); if (bulk.is_valid(elem)) sideset.push_back(add_elem_side_pair(elem, elem_side[is*2+1])); } }
inline void test_num_faces_on_this_element(const stk::mesh::BulkData& bulkData, stk::mesh::EntityId id, size_t gold_num_faces_this_elem) { stk::mesh::Entity element = bulkData.get_entity(stk::topology::ELEM_RANK, id); if(bulkData.is_valid(element)) { unsigned num_faces_this_elem = bulkData.num_faces(element); EXPECT_EQ(gold_num_faces_this_elem, num_faces_this_elem); } }
void performNodalMeshReduction( stk::mesh::Part &samplePart, stk::mesh::BulkData& bulkData) { const stk::mesh::MetaData &metaData = stk::mesh::MetaData::get(bulkData); std::vector<stk::mesh::Entity> sampleNodes; stk::mesh::get_selected_entities(samplePart, bulkData.buckets(stk::topology::NODE_RANK), sampleNodes); const stk::mesh::Selector locallyOwned = stk::mesh::MetaData::get(bulkData).locally_owned_part(); std::vector<stk::mesh::Entity> relatedEntities; typedef std::vector<stk::mesh::Entity>::const_iterator EntityIterator; for (EntityIterator it(sampleNodes.begin()), it_end(sampleNodes.end()); it != it_end; ++it) { for (stk::mesh::EntityRank r = stk::topology::NODE_RANK; r < metaData.entity_rank_count(); ++r) { stk::mesh::Entity const* relations = bulkData.begin(*it, r); const int num_rels = bulkData.num_connectivity(*it, r); for (int i = 0; i < num_rels; ++i) { stk::mesh::Entity relatedEntity = relations[i]; if (bulkData.is_valid(relatedEntity) && locallyOwned(bulkData.bucket(relatedEntity))) { relatedEntities.push_back(relatedEntity); } } } } std::sort(relatedEntities.begin(), relatedEntities.end(), stk::mesh::EntityLess(bulkData)); relatedEntities.erase( std::unique(relatedEntities.begin(), relatedEntities.end()), relatedEntities.end()); std::vector<stk::mesh::Entity> sampleClosure; stk::mesh::find_closure(bulkData, relatedEntities, sampleClosure); // Keep only the closure, remove the rest, by decreasing entityRanks { const stk::mesh::Selector ownedOrShared = metaData.locally_owned_part() | metaData.globally_shared_part(); EntityIterator allKeepersEnd(sampleClosure.end()); const EntityIterator allKeepersBegin(sampleClosure.begin()); for (size_t candidateRankCount = metaData.entity_rank_count(); candidateRankCount > 0; --candidateRankCount) { const stk::mesh::EntityRank candidateRank = static_cast<stk::mesh::EntityRank>(candidateRankCount - 1); const EntityIterator keepersBegin = std::lower_bound(allKeepersBegin, allKeepersEnd, stk::mesh::EntityKey(candidateRank, 0), stk::mesh::EntityLess(bulkData)); const EntityIterator keepersEnd = allKeepersEnd; std::vector<stk::mesh::Entity> candidates; stk::mesh::get_selected_entities(ownedOrShared, bulkData.buckets(candidateRank), candidates); { BulkModification modification(bulkData); std::set_difference(candidates.begin(), candidates.end(), keepersBegin.base(), keepersEnd.base(), EntityDestructor(modification), stk::mesh::EntityLess(bulkData)); } allKeepersEnd = keepersBegin; } } }
stk::mesh::GraphEdge unpack_edge(stk::CommSparse& comm, const stk::mesh::BulkData& bulkData, const ElemElemGraph& graph, int proc_id) { stk::mesh::EntityId id1 = 0, id2 = 0; unsigned side1 = 0, side2 = 0; comm.recv_buffer(proc_id).unpack<stk::mesh::EntityId>(id1); comm.recv_buffer(proc_id).unpack<unsigned>(side1); comm.recv_buffer(proc_id).unpack<stk::mesh::EntityId>(id2); comm.recv_buffer(proc_id).unpack<unsigned>(side2); stk::mesh::Entity element = bulkData.get_entity(stk::topology::ELEM_RANK, id2); ThrowRequireWithSierraHelpMsg(bulkData.is_valid(element)); stk::mesh::impl::LocalId localId2 = graph.get_local_element_id(element); stk::mesh::GraphEdge edge(localId2, side2, -id1, side1); return edge; }
void addNodesToPart( const Teuchos::ArrayView<const stk::mesh::EntityId> &nodeIds, stk::mesh::Part &samplePart, stk::mesh::BulkData& bulkData) { const stk::mesh::PartVector samplePartVec(1, &samplePart); const stk::mesh::Selector locallyOwned = stk::mesh::MetaData::get(bulkData).locally_owned_part(); BulkModification mod(bulkData); typedef Teuchos::ArrayView<const stk::mesh::EntityId>::const_iterator Iter; for (Iter it = nodeIds.begin(), it_end = nodeIds.end(); it != it_end; ++it) { stk::mesh::Entity node = bulkData.get_entity(stk::topology::NODE_RANK, *it); if (bulkData.is_valid(node) && locallyOwned(bulkData.bucket(node))) { bulkData.change_entity_parts(node, samplePartVec); } } }
// ======================================================================== void process_nodesets(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { // Should only process nodes that have already been defined via the element // blocks connectivity lists. const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); it != node_sets.end(); ++it) { Ioss::NodeSet *entity = *it; if (stk::io::include_entity(entity)) { const std::string & name = entity->name(); const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); stk::mesh::Part* const part = meta.get_part(name); STKIORequire(part != NULL); stk::mesh::PartVector add_parts( 1 , part ); std::vector<int> node_ids ; int node_count = entity->get_field_data("ids", node_ids); std::vector<stk::mesh::Entity> nodes(node_count); for(int i=0; i<node_count; ++i) { nodes[i] = bulk.get_entity( stk::topology::NODE_RANK, node_ids[i] ); if (bulk.is_valid(nodes[i])) { bulk.declare_entity(stk::topology::NODE_RANK, node_ids[i], add_parts ); } } /** \todo REFACTOR Application would probably store this field * (and others) somewhere after the declaration instead of * looking it up each time it is needed. */ stk::mesh::Field<double> *df_field = meta.get_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors"); if (df_field != NULL) { stk::io::field_data_from_ioss(bulk, df_field, nodes, entity, "distribution_factors"); } } } }
inline size_t get_number_sides_in_sideset(const stk::mesh::BulkData& bulk, int sideset_id, stk::mesh::Selector selector, stk::topology stk_element_topology, const stk::mesh::BucketVector& buckets) { if (bulk.has_sideset_data()) { selector &= ( bulk.mesh_meta_data().locally_owned_part() | bulk.mesh_meta_data().globally_shared_part()); size_t num_sides = 0; const stk::mesh::SideSet& sset = bulk.get_sideset_data(sideset_id); for(const stk::mesh::SideSetEntry& elem_and_side : sset) { stk::mesh::Entity element = elem_and_side.element; stk::mesh::Entity side = stk::mesh::get_side_entity_for_elem_side_pair(bulk, element, elem_and_side.side); if(bulk.is_valid(side)) { if(selector(bulk.bucket(side))) { if(stk_element_topology == stk::topology::INVALID_TOPOLOGY || stk_element_topology == bulk.bucket(element).topology()) { ++num_sides; } } } } return num_sides; } else { selector &= bulk.mesh_meta_data().locally_owned_part(); return count_selected_entities(selector, buckets); } }
void fill_element_and_side_ids(Ioss::GroupingEntity & io, stk::mesh::Part * const part, const stk::mesh::BulkData & bulk_data, stk::topology stk_element_topology, const stk::mesh::Selector *subset_selector, stk::mesh::EntityVector &sides, std::vector<INT>& elem_side_ids) { if (bulk_data.has_sideset_data()) { const stk::mesh::SideSet& sset = bulk_data.get_sideset_data(part->id()); size_t num_sides = sset.size(); elem_side_ids.reserve(num_sides*2); stk::mesh::Selector selector = *part & ( bulk_data.mesh_meta_data().locally_owned_part() | bulk_data.mesh_meta_data().globally_shared_part() ); if(subset_selector) selector &= *subset_selector; for(size_t i=0;i<sset.size();++i) { stk::mesh::Entity element = sset[i].element; stk::mesh::EntityId elemId = bulk_data.identifier(element); int zero_based_side_ord = sset[i].side; stk::mesh::Entity side = stk::mesh::get_side_entity_for_elem_id_side_pair_of_rank(bulk_data, elemId, zero_based_side_ord, bulk_data.mesh_meta_data().side_rank()); if(bulk_data.is_valid(side)) { if(selector(bulk_data.bucket(side))) { if(bulk_data.bucket(element).topology() == stk_element_topology) { elem_side_ids.push_back(elemId); elem_side_ids.push_back(zero_based_side_ord+1); sides.push_back(side); } } } } } else { const stk::mesh::MetaData & meta_data = stk::mesh::MetaData::get(*part); stk::mesh::EntityRank type = part_primary_entity_rank(*part); size_t num_sides = get_entities(*part, type, bulk_data, sides, false, subset_selector); elem_side_ids.reserve(num_sides * 2); stk::mesh::EntityRank elem_rank = stk::topology::ELEMENT_RANK; for(size_t i = 0; i < num_sides; ++i) { std::vector<stk::mesh::Entity> side; side.push_back(sides[i]); std::vector<stk::mesh::Entity> side_elements; std::vector<stk::mesh::Entity> side_nodes(bulk_data.begin_nodes(sides[i]), bulk_data.end_nodes(sides[i])); get_entities_through_relations(bulk_data, side_nodes, elem_rank, side_elements); const size_t num_side_elem = side_elements.size(); std::sort(side_elements.begin(), side_elements.end(), stk::mesh::EntityLess(bulk_data)); stk::mesh::Entity suitable_elem = stk::mesh::Entity(); stk::mesh::ConnectivityOrdinal suitable_ordinal = stk::mesh::INVALID_CONNECTIVITY_ORDINAL; for(size_t j = 0; j < num_side_elem; ++j) { const stk::mesh::Entity elem = side_elements[j]; const stk::mesh::Bucket &elemBucket = bulk_data.bucket(elem); const bool isSelectingEverything = subset_selector == NULL; const bool isElementBeingOutput = (isSelectingEverything || (*subset_selector)(elemBucket)) && elemBucket.member(meta_data.locally_owned_part()); if(isElementBeingOutput) { const stk::mesh::Entity * elem_sides = bulk_data.begin(elem, type); stk::mesh::ConnectivityOrdinal const * side_ordinal = bulk_data.begin_ordinals(elem, type); const size_t num_elem_sides = bulk_data.num_connectivity(elem, type); for(size_t k = 0; k < num_elem_sides; ++k) { if(elem_sides[k] == side[0]) { suitable_elem = elem; suitable_ordinal = side_ordinal[k]; break; } } } } if(!bulk_data.is_valid(suitable_elem)) { std::ostringstream oss; oss << "ERROR, no suitable element found"; throw std::runtime_error(oss.str()); } elem_side_ids.push_back(bulk_data.identifier(suitable_elem)); elem_side_ids.push_back(suitable_ordinal + 1); // Ioss is 1-based, mesh is 0-based. } } }
void fixup_ghosted_to_shared_nodes(stk::mesh::BulkData & bulk) { stk::mesh::EntityVector ghosted_nodes_that_are_now_shared; find_ghosted_nodes_that_need_to_be_shared(bulk, ghosted_nodes_that_are_now_shared); stk::CommSparse comm(bulk.parallel()); for (int phase=0;phase<2;++phase) { for (size_t i = 0; i < ghosted_nodes_that_are_now_shared.size(); ++i) { stk::mesh::Entity node = ghosted_nodes_that_are_now_shared[i]; int proc = bulk.parallel_owner_rank(node); comm.send_buffer(proc).pack<stk::mesh::EntityKey>(bulk.entity_key(node)); } if (phase == 0 ) { comm.allocate_buffers(); } else { comm.communicate(); } } stk::mesh::EntityVector sharedNodes; for (int process=0;process<bulk.parallel_size();++process) { while(comm.recv_buffer(process).remaining()) { stk::mesh::EntityKey key; comm.recv_buffer(process).unpack<stk::mesh::EntityKey>(key); stk::mesh::Entity entity = bulk.get_entity(key); if ( bulk.state(entity) != stk::mesh::Deleted && bulk.is_valid(entity) ) { bulk.add_node_sharing(entity, process); sharedNodes.push_back(entity); } } } ///////////////////////// stk::CommSparse commSecondStage(bulk.parallel()); for (int phase=0;phase<2;++phase) { for (size_t i=0;i<sharedNodes.size();++i) { std::vector<int> procs; stk::mesh::EntityKey key = bulk.entity_key(sharedNodes[i]); bulk.comm_shared_procs(key, procs); for (size_t j=0;j<procs.size();++j) { if ( procs[j] != bulk.parallel_rank() ) { commSecondStage.send_buffer(procs[j]).pack<int>(bulk.parallel_rank()).pack<stk::mesh::EntityKey>(key); for (size_t k=0;k<procs.size();++k) { commSecondStage.send_buffer(procs[j]).pack<int>(procs[k]).pack<stk::mesh::EntityKey>(key); } } } } if (phase == 0 ) { commSecondStage.allocate_buffers(); } else { commSecondStage.communicate(); } } for (int proc_that_sent_message=0;proc_that_sent_message<bulk.parallel_size();++proc_that_sent_message) { if ( proc_that_sent_message == bulk.parallel_rank() ) continue; while(commSecondStage.recv_buffer(proc_that_sent_message).remaining()) { stk::mesh::EntityKey key; int sharingProc; commSecondStage.recv_buffer(proc_that_sent_message).unpack<int>(sharingProc).unpack<stk::mesh::EntityKey>(key); if ( sharingProc != bulk.parallel_rank() ) { stk::mesh::Entity entity = bulk.get_entity(key); if ( bulk.state(entity) != stk::mesh::Deleted && bulk.is_valid(entity) && !bulk.in_shared(key, sharingProc) ) { bulk.add_node_sharing(entity, sharingProc); } } } } }