diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp index 544b8d237276904d7bc9abd2dbec52e4d585f314..aaa9e9a125f12a9eb29a2f8d9ce1f098b050233c 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp +++ b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp @@ -85,103 +85,131 @@ void NodeWiseMeshPartitioner::readMetisData(const std::string& file_name_base) std::remove(fname_eparts.c_str()); } -void NodeWiseMeshPartitioner::partitionByMETIS( - const bool is_mixed_high_order_linear_elems) +void NodeWiseMeshPartitioner::findNonGhostNodesInPartition( + std::size_t const part_id, + const bool is_mixed_high_order_linear_elems, + std::vector<MeshLib::Node*>& extra_nodes) { std::vector<MeshLib::Node*> const& nodes = _mesh->getNodes(); - for (std::size_t part_id = 0; part_id < _partitions.size(); part_id++) + auto& partition = _partitions[part_id]; + // -- Extra nodes for high order elements + for (std::size_t i = 0; i < _mesh->getNumberOfNodes(); i++) { - auto& partition = _partitions[part_id]; - - INFO("Processing partition: %d", part_id); - - // Find non-ghost nodes in this partition - // -- Extra nodes for high order elements - std::vector<MeshLib::Node*> extra_nodes; - for (std::size_t i = 0; i < _mesh->getNumberOfNodes(); i++) + if (_nodes_partition_ids[i] == part_id) { - if (_nodes_partition_ids[i] == part_id) - { - if (is_mixed_high_order_linear_elems) - { // TODO: Test it once there is a case - if (i < _mesh->getNumberOfBaseNodes()) - partition.nodes.push_back(nodes[i]); - else - extra_nodes.push_back(nodes[i]); - } - else - { + if (is_mixed_high_order_linear_elems) + { // TODO: Test it once there is a case + if (i < _mesh->getNumberOfBaseNodes()) partition.nodes.push_back(nodes[i]); - } + else + extra_nodes.push_back(nodes[i]); + } + else + { + partition.nodes.push_back(nodes[i]); } } - partition.number_of_non_ghost_base_nodes = partition.nodes.size(); - partition.number_of_non_ghost_nodes = - partition.number_of_non_ghost_base_nodes + extra_nodes.size(); + } + partition.number_of_non_ghost_base_nodes = partition.nodes.size(); + partition.number_of_non_ghost_nodes = + partition.number_of_non_ghost_base_nodes + extra_nodes.size(); +} - // Find elements that belong to this partition - std::vector<MeshLib::Element*> const& elements = _mesh->getElements(); - for (std::size_t elem_id = 0; elem_id < elements.size(); elem_id++) - { - const auto* elem = elements[elem_id]; - if (_elements_status[elem_id]) - continue; +void NodeWiseMeshPartitioner::findElementsInPartition( + std::size_t const part_id, const bool is_mixed_high_order_linear_elems) +{ + auto& partition = _partitions[part_id]; + std::vector<MeshLib::Element*> const& elements = _mesh->getElements(); + for (std::size_t elem_id = 0; elem_id < elements.size(); elem_id++) + { + const auto* elem = elements[elem_id]; + if (_elements_status[elem_id]) + continue; - std::size_t non_ghost_node_number = 0; - for (unsigned i = 0; i < elem->getNumberOfNodes(); i++) + std::size_t non_ghost_node_number = 0; + for (unsigned i = 0; i < elem->getNumberOfNodes(); i++) + { + if (_nodes_partition_ids[elem->getNodeIndex(i)] == part_id) { - if (_nodes_partition_ids[elem->getNodeIndex(i)] == part_id) - { - non_ghost_node_number++; - } + non_ghost_node_number++; } + } - if (non_ghost_node_number == 0) - continue; + if (non_ghost_node_number == 0) + continue; - if (non_ghost_node_number == elem->getNumberOfNodes()) - { - partition.regular_elements.push_back(elem); - _elements_status[elem_id] = true; - } - else - { - partition.ghost_elements.push_back(elem); - } + if (non_ghost_node_number == elem->getNumberOfNodes()) + { + partition.regular_elements.push_back(elem); + _elements_status[elem_id] = true; + } + else + { + partition.ghost_elements.push_back(elem); } + } +} - // Find the ghost nodes of this partition - std::vector<bool> nodes_reserved(_mesh->getNumberOfNodes(), false); - for (const auto* ghost_elem : partition.ghost_elements) +void NodeWiseMeshPartitioner::findGhostNodesInPartition( + std::size_t const part_id, + const bool is_mixed_high_order_linear_elems, + std::vector<MeshLib::Node*>& extra_nodes) +{ + auto& partition = _partitions[part_id]; + std::vector<MeshLib::Node*> const& nodes = _mesh->getNodes(); + std::vector<bool> nodes_reserved(_mesh->getNumberOfNodes(), false); + for (const auto* ghost_elem : partition.ghost_elements) + { + for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++) { - for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++) - { - const unsigned node_id = ghost_elem->getNodeIndex(i); - if (nodes_reserved[node_id]) - continue; + const unsigned node_id = ghost_elem->getNodeIndex(i); + if (nodes_reserved[node_id]) + continue; - if (_nodes_partition_ids[node_id] != part_id) + if (_nodes_partition_ids[node_id] != part_id) + { + if (is_mixed_high_order_linear_elems) { - if (is_mixed_high_order_linear_elems) - { - if (node_id < _mesh->getNumberOfBaseNodes()) - partition.nodes.push_back(nodes[node_id]); - else - extra_nodes.push_back(nodes[node_id]); - } - else - { + if (node_id < _mesh->getNumberOfBaseNodes()) partition.nodes.push_back(nodes[node_id]); - } - nodes_reserved[node_id] = true; + else + extra_nodes.push_back(nodes[node_id]); } + else + { + partition.nodes.push_back(nodes[node_id]); + } + nodes_reserved[node_id] = true; } } - partition.number_of_base_nodes = partition.nodes.size(); + } +} - if (is_mixed_high_order_linear_elems) - partition.nodes.insert(partition.nodes.end(), extra_nodes.begin(), - extra_nodes.end()); +void NodeWiseMeshPartitioner::processPartition(std::size_t const part_id, + const bool is_mixed_high_order_linear_elems) +{ + std::vector<MeshLib::Node*> extra_nodes; + findNonGhostNodesInPartition(part_id, is_mixed_high_order_linear_elems, + extra_nodes); + + findElementsInPartition(part_id, is_mixed_high_order_linear_elems); + findGhostNodesInPartition(part_id, is_mixed_high_order_linear_elems, + extra_nodes); + auto& partition = _partitions[part_id]; + partition.number_of_base_nodes = partition.nodes.size(); + + if (is_mixed_high_order_linear_elems) + partition.nodes.insert(partition.nodes.end(), extra_nodes.begin(), + extra_nodes.end()); +} + +void NodeWiseMeshPartitioner::partitionByMETIS( + const bool is_mixed_high_order_linear_elems) +{ + for (std::size_t part_id = 0; part_id < _partitions.size(); part_id++) + { + INFO("Processing partition: %d", part_id); + processPartition(part_id, is_mixed_high_order_linear_elems); } renumberNodeIndices(is_mixed_high_order_linear_elems); diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h index 66fbb920623aa1da6faa5c53058d475b3e596e14..6c42f31a75fa3281ded4280432596c87ea346fc3 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h +++ b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.h @@ -130,6 +130,32 @@ private: void writePropertiesBinary(std::string const& file_name_base) const; + /// 1 copy pointers to nodes belonging to the partition part_id + /// 2 collect non-linear element nodes belonging to the partition part_id in + /// extra_nodes + void findNonGhostNodesInPartition( + std::size_t const part_id, + const bool is_mixed_high_order_linear_elems, + std::vector<MeshLib::Node*>& extra_nodes); + + /// 1 find elements belonging to the partition part_id: + /// fills vector partition.regular_elements + /// 2 find ghost elements belonging to the partition part_id + /// fills vector partition.ghost_elements + void findElementsInPartition(std::size_t const part_id, + const bool is_mixed_high_order_linear_elems); + + /// Prerequisite: the ghost elements has to be found (using + /// findElementsInPartition). + /// Finds ghost nodes and non-linear element ghost nodes by walking over + /// ghost elements. + void findGhostNodesInPartition(std::size_t const part_id, + const bool is_mixed_high_order_linear_elems, + std::vector<MeshLib::Node*>& extra_nodes); + + void processPartition(std::size_t const part_id, + const bool is_mixed_high_order_linear_elems); + template <typename T> void writePropertyVectorValuesBinary( std::ostream& os, MeshLib::PropertyVector<T> const& pv) const