void filter_out_invalid_solid_shell_connections(const stk::mesh::BulkData & mesh, const stk::mesh::Entity localElement, const unsigned sideOrdinal, std::vector<SideData> & connectedElementData) { stk::topology localElemTopology = mesh.bucket(localElement).topology(); if (localElemTopology.is_shell()) { std::vector<SideData> filteredConnectedElements; for (const SideData & connectedElem: connectedElementData) { if(mesh.identifier(localElement) != connectedElem.get_element_identifier()) { if(connectedElem.get_element_topology().is_shell()) add_shell_element_if_coincident(mesh, sideOrdinal, localElement, connectedElem, filteredConnectedElements); else add_solid_element_if_normals_oppose_to_shell(mesh, sideOrdinal, localElement, connectedElem, filteredConnectedElements); } } connectedElementData.swap(filteredConnectedElements); } else { add_shell_connections_to_this_solid_if_normals_oppose(mesh, localElement, sideOrdinal, connectedElementData); } }
inline void createBoundingBoxesForElementsInElementBlocks(const stk::mesh::BulkData &bulk, FlaotBoxVector& domainBoxes) { stk::mesh::EntityVector elements; stk::mesh::get_selected_entities(bulk.mesh_meta_data().locally_owned_part(), bulk.buckets(stk::topology::ELEM_RANK), elements); size_t numberBoundingBoxes = elements.size(); domainBoxes.resize(numberBoundingBoxes); stk::mesh::FieldBase const * coords = bulk.mesh_meta_data().coordinate_field(); std::vector<double> boxCoordinates(6); for(size_t i=0;i<elements.size();++i) { unsigned num_nodes = bulk.num_nodes(elements[i]); std::vector<double> coordinates(3*num_nodes,0); const stk::mesh::Entity* nodes = bulk.begin_nodes(elements[i]); for(unsigned j=0;j<num_nodes;++j) { double* data = static_cast<double*>(stk::mesh::field_data(*coords, nodes[j])); coordinates[3*j] = data[0]; coordinates[3*j+1] = data[1]; coordinates[3*j+2] = data[2]; } findBoundingBoxCoordinates(coordinates, boxCoordinates); unsigned id = bulk.identifier(elements[i]); Ident domainBoxId(id, bulk.parallel_rank()); domainBoxes[i] = std::make_pair(FloatBox(boxCoordinates[0], boxCoordinates[1], boxCoordinates[2], boxCoordinates[3], boxCoordinates[4], boxCoordinates[5]), domainBoxId); } }
void Vertices::fillVertexIds(const stk::mesh::BulkData& bulkData, const stk::mesh::EntityVector &entities) { mVertexIds.resize(entities.size(), 0); for(size_t i=0;i<entities.size();++i) mVertexIds[i] = bulkData.identifier(entities[i]); }
std::map<stk::mesh::EntityId, std::pair<stk::mesh::EntityId, int> > get_split_coincident_elements(stk::mesh::BulkData& bulkData) { stk::mesh::Selector sel = bulkData.mesh_meta_data().locally_owned_part(); ElemGraphForDiagnostics graph(bulkData, sel); const stk::mesh::impl::SparseGraph& coingraph = graph.get_coincident_graph(); std::map<stk::mesh::EntityId, std::pair<stk::mesh::EntityId, int> > badElements; for(const stk::mesh::impl::SparseGraph::value_type& extractedEdgesForElem : coingraph) { const std::vector<stk::mesh::GraphEdge>& coincidentEdgesForElem = extractedEdgesForElem.second; for(const stk::mesh::GraphEdge& edge : coincidentEdgesForElem) { if(edge.elem2 < 0) { stk::mesh::Entity entity = graph.get_entity(edge.elem1); stk::mesh::EntityId id = bulkData.identifier(entity); stk::mesh::impl::ParallelGraphInfo& par_info = graph.get_parallel_info(); stk::mesh::impl::ParallelGraphInfo::iterator iter = par_info.find(edge); ThrowRequireMsg(iter!=par_info.end(), "Program error. Contact [email protected] for support."); badElements[id] = std::make_pair(-edge.elem2, iter->second.m_other_proc); } } } return badElements; }
inline int get_side_between_elements(const stk::mesh::BulkData& bulkData, stk::mesh::ElemElemGraph& graph, stk::mesh::Entity elem1, stk::mesh::EntityId elem2Id) { size_t numConnected = graph.get_num_connected_elems(elem1); for(size_t i=0; i<numConnected; ++i) { stk::mesh::EntityId id = 0; int side = -1; if (graph.is_connected_elem_locally_owned(elem1, i)) { stk::mesh::impl::ElementViaSidePair elemViaSidePair = graph.get_connected_element_and_via_side(elem1, i); id = bulkData.identifier(elemViaSidePair.element); side = elemViaSidePair.side; } else { stk::mesh::impl::IdViaSidePair idViaSidePair = graph.get_connected_remote_id_and_via_side(elem1, i); id = idViaSidePair.id; side = idViaSidePair.side; } if (id == elem2Id) { return side; } } return -1; }
void pack_edge(stk::CommSparse &comm, const ElemElemGraph& graph, const stk::mesh::BulkData& bulkData, const stk::mesh::GraphEdge& edge, int other_proc) { stk::mesh::EntityId id1 = bulkData.identifier(graph.get_entity(edge.elem1())); unsigned side1 = edge.side1(); stk::mesh::EntityId id2 = -edge.elem2(); unsigned side2 = edge.side2(); comm.send_buffer(other_proc).pack<stk::mesh::EntityId>(id1); comm.send_buffer(other_proc).pack<unsigned>(side1); comm.send_buffer(other_proc).pack<stk::mesh::EntityId>(id2); comm.send_buffer(other_proc).pack<unsigned>(side2); }
void fill_sharing_data(stk::mesh::BulkData& bulkData, stk::mesh::ElemElemGraph &graph, const stk::mesh::EntityVector& sidesThatNeedFixing, std::vector<SideSharingData>& sideSharingDataThisProc, std::vector<stk::mesh::impl::IdViaSidePair>& idAndSides) { // Element 1, side 5: face 15 // Element 2, side 3: face 23 // Are these faces the same? Yes: delete face 23, then connect face 15 to element 2 with negative permutation const stk::mesh::PartOrdinal sharedOrd = bulkData.mesh_meta_data().globally_shared_part().mesh_meta_data_ordinal(); for(size_t i=0;i<sidesThatNeedFixing.size();++i) { stk::mesh::impl::ElementViaSidePair elementAndSide = get_element_and_side_ordinal(bulkData, sidesThatNeedFixing[i]); stk::mesh::impl::LocalId localElemId = graph.get_local_element_id(elementAndSide.element); for(const stk::mesh::GraphEdge& edge : graph.get_edges_for_element(localElemId)) { if(edge.side1() == elementAndSide.side && edge.elem2() < 0) { const stk::mesh::impl::ParallelInfo &pInfo = graph.get_parallel_info_for_graph_edge(edge); const stk::mesh::Entity* nodes = bulkData.begin_nodes(sidesThatNeedFixing[i]); unsigned numNodes = bulkData.num_nodes(sidesThatNeedFixing[i]); SideSharingData localTemp({bulkData.identifier(elementAndSide.element), elementAndSide.side}, sidesThatNeedFixing[i], pInfo.get_proc_rank_of_neighbor(), std::min(bulkData.parallel_rank(),pInfo.get_proc_rank_of_neighbor()), bulkData.identifier(sidesThatNeedFixing[i])); localTemp.sideNodes.resize(numNodes); for(unsigned j=0; j<numNodes; ++j) { localTemp.sideNodes[j] = bulkData.identifier(nodes[j]); } fill_part_ordinals_besides_owned_and_shared(bulkData.bucket(sidesThatNeedFixing[i]), sharedOrd, localTemp.partOrdinals); sideSharingDataThisProc.push_back(localTemp); stk::mesh::EntityId localId = -edge.elem2(); idAndSides.push_back({localId, edge.side2()}); } } } }
bool bucket_part_memberships_match(const stk::mesh::BulkData& bulk, stk::EnvData& env_data) { int numGlobalDiffs = bucket_counts_match(bulk, env_data); if(numGlobalDiffs > 0) { for(size_t irank = 0; irank < bulk.mesh_meta_data().entity_rank_count(); ++irank) { stk::CommSparse comm(env_data.m_worldComm); stk::CommBuffer &buff = stk::diff::get_comm_buffer_for_destination_proc(comm); stk::mesh::EntityRank rank = static_cast<stk::mesh::EntityRank>(irank); stk::mesh::EntityVector entities; stk::mesh::get_entities(bulk, rank, entities); for(int iphase = 0; iphase < 2; ++iphase) { for(size_t i=0;i<entities.size();++i) { const stk::mesh::PartVector& parts = bulk.bucket(entities[i]).supersets(); std::string part_names_for_entity = create_string_from_parts(parts); std::string string_to_send; if(irank != 1 && irank != 2) { string_to_send = std::to_string(bulk.identifier(entities[i])) + " " + part_names_for_entity; } else { string_to_send = part_names_for_entity; } stk::diff::pack_string(buff, string_to_send); } stk::diff::allocate_or_communicate(iphase, comm); } } } for(size_t irank = 0; irank < bulk.mesh_meta_data().entity_rank_count(); ++irank) { stk::CommSparse comm(env_data.m_worldComm); stk::mesh::EntityRank rank = static_cast<stk::mesh::EntityRank>(irank); const stk::mesh::BucketVector& buckets = bulk.buckets(rank); for(int iphase = 0; iphase < 2; ++iphase) { pack_buckets_parts(buckets, stk::diff::get_comm_buffer_for_destination_proc(comm)); stk::diff::allocate_or_communicate(iphase, comm); } } numGlobalDiffs += get_global_bucket_part_membership_differences(env_data.m_worldComm, 0); return numGlobalDiffs == 0; }
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 pack_selected_value_for_par_info(stk::CommSparse &comm, int procRank, const stk::mesh::BulkData& bulkData, stk::mesh::Entity local_element, stk::mesh::Selector sel) { if(sel(bulkData.bucket(local_element))) comm.send_buffer(procRank).pack<int64_t>(bulkData.identifier(local_element)); }