diff --git a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp index 09113a3fac8dc7acbb57499a1aed0acf5237c031..942465c2f06d662f19d32810194423eaadb75bd6 100644 --- a/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp +++ b/Applications/Utils/ModelPreparation/PartitionMesh/NodeWiseMeshPartitioner.cpp @@ -23,28 +23,13 @@ #include "BaseLib/Logging.h" #include "IntegrationPointDataTools.h" #include "MeshLib/Elements/Elements.h" +#include "MeshLib/IO/NodeData.h" #include "MeshLib/IO/VtkIO/VtuInterface.h" #include "MeshLib/MeshEnums.h" #include "MeshLib/Utils/IntegrationPointWriter.h" namespace ApplicationUtils { -struct NodeStruct -{ - NodeStruct(NodeWiseMeshPartitioner::IntegerType const id_, - double const x_, - double const y_, - double const z_) - : id(id_), x(x_), y(y_), z(z_) - { - } - - NodeWiseMeshPartitioner::IntegerType id; - double x; - double y; - double z; -}; - std::size_t Partition::numberOfMeshItems( MeshLib::MeshItemType const item_type) const { @@ -68,7 +53,7 @@ std::size_t Partition::numberOfMeshItems( std::ostream& Partition::writeNodes( std::ostream& os, std::vector<std::size_t> const& global_node_ids) const { - std::vector<NodeStruct> nodes_buffer; + std::vector<MeshLib::IO::NodeData> nodes_buffer; nodes_buffer.reserve(nodes.size()); for (const auto* node : nodes) @@ -78,7 +63,7 @@ std::ostream& Partition::writeNodes( coords[1], coords[2]); } return os.write(reinterpret_cast<const char*>(nodes_buffer.data()), - sizeof(NodeStruct) * nodes_buffer.size()); + sizeof(MeshLib::IO::NodeData) * nodes_buffer.size()); } /// Calculate the total number of integer variables of an element vector. Each @@ -1008,7 +993,7 @@ ConfigOffsets incrementConfigOffsets(ConfigOffsets const& oldConfig, { return { static_cast<long>(oldConfig.node_rank_offset + - offsets.node * sizeof(NodeStruct)), + offsets.node * sizeof(MeshLib::IO::NodeData)), // Offset the ending entry of the element integer variables of // the non-ghost elements of this partition in the vector of elem_info. static_cast<long>(oldConfig.element_rank_offset + diff --git a/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.cpp b/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.cpp index 97289c4842bd4ac61e509595cec46a15bb6a5c7f..211f7fc5e7a65c1a17fa4e201fc89a40a567f266 100644 --- a/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.cpp +++ b/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.cpp @@ -163,7 +163,7 @@ MeshLib::NodePartitionedMesh* NodePartitionedMeshReader::readMesh( //---------------------------------------------------------------------------------- // Read Nodes - std::vector<NodeData> nodes(_mesh_info.nodes); + std::vector<NodeData> nodes(_mesh_info.number_of_nodes); if (!readDataFromFile(fname_header + "nod" + fname_num_p_ext, static_cast<MPI_Offset>(_mesh_info.offset[2]), @@ -176,21 +176,22 @@ MeshLib::NodePartitionedMesh* NodePartitionedMeshReader::readMesh( //---------------------------------------------------------------------------------- // Read non-ghost elements - std::vector<unsigned long> elem_data(_mesh_info.regular_elements + + std::vector<unsigned long> elem_data(_mesh_info.number_of_regular_elements + _mesh_info.offset[0]); if (!readDataFromFile(fname_header + "ele" + fname_num_p_ext, static_cast<MPI_Offset>(_mesh_info.offset[3]), MPI_LONG, elem_data)) return nullptr; - std::vector<MeshLib::Element*> mesh_elems(_mesh_info.regular_elements + - _mesh_info.ghost_elements); + std::vector<MeshLib::Element*> mesh_elems( + _mesh_info.number_of_regular_elements + + _mesh_info.number_of_ghost_elements); setElements(mesh_nodes, elem_data, mesh_elems); //---------------------------------------------------------------------------------- // Read ghost element - std::vector<unsigned long> ghost_elem_data(_mesh_info.ghost_elements + - _mesh_info.offset[1]); + std::vector<unsigned long> ghost_elem_data( + _mesh_info.number_of_ghost_elements + _mesh_info.offset[1]); if (!readDataFromFile(fname_header + "ele_g" + fname_num_p_ext, static_cast<MPI_Offset>(_mesh_info.offset[4]), @@ -408,44 +409,47 @@ MeshLib::NodePartitionedMesh* NodePartitionedMeshReader::newMesh( std::vector<MeshLib::Element*> const& mesh_elems, MeshLib::Properties const& properties) const { - std::vector<std::size_t> gathered_n_active_base_nodes(_mpi_comm_size); + std::vector<std::size_t> gathered_n_regular_base_nodes(_mpi_comm_size); - MPI_Allgather(&_mesh_info.active_base_nodes, + MPI_Allgather(&_mesh_info.number_of_regular_base_nodes, 1, MPI_UNSIGNED_LONG, - gathered_n_active_base_nodes.data(), + gathered_n_regular_base_nodes.data(), 1, MPI_UNSIGNED_LONG, _mpi_comm); - std::vector<std::size_t> n_active_base_nodes_at_rank; - n_active_base_nodes_at_rank.push_back(0); - std::partial_sum(begin(gathered_n_active_base_nodes), - end(gathered_n_active_base_nodes), - back_inserter(n_active_base_nodes_at_rank)); - - std::vector<std::size_t> gathered_n_active_high_order_nodes(_mpi_comm_size); - std::size_t const n_active_high_order_nodes = - _mesh_info.active_nodes - _mesh_info.active_base_nodes; - MPI_Allgather(&n_active_high_order_nodes, + std::vector<std::size_t> n_regular_base_nodes_at_rank; + n_regular_base_nodes_at_rank.push_back(0); + std::partial_sum(begin(gathered_n_regular_base_nodes), + end(gathered_n_regular_base_nodes), + back_inserter(n_regular_base_nodes_at_rank)); + + std::vector<std::size_t> gathered_n_regular_high_order_nodes( + _mpi_comm_size); + std::size_t const n_regular_high_order_nodes = + _mesh_info.number_of_regular_nodes - + _mesh_info.number_of_regular_base_nodes; + MPI_Allgather(&n_regular_high_order_nodes, 1, MPI_UNSIGNED_LONG, - gathered_n_active_high_order_nodes.data(), + gathered_n_regular_high_order_nodes.data(), 1, MPI_UNSIGNED_LONG, _mpi_comm); - std::vector<std::size_t> n_active_high_order_nodes_at_rank; - n_active_high_order_nodes_at_rank.push_back(0); - std::partial_sum(begin(gathered_n_active_high_order_nodes), - end(gathered_n_active_high_order_nodes), - back_inserter(n_active_high_order_nodes_at_rank)); + std::vector<std::size_t> n_regular_high_order_nodes_at_rank; + n_regular_high_order_nodes_at_rank.push_back(0); + std::partial_sum(begin(gathered_n_regular_high_order_nodes), + end(gathered_n_regular_high_order_nodes), + back_inserter(n_regular_high_order_nodes_at_rank)); return new MeshLib::NodePartitionedMesh( mesh_name, mesh_nodes, glb_node_ids, mesh_elems, properties, - _mesh_info.global_base_nodes, _mesh_info.global_nodes, - _mesh_info.active_nodes, std::move(n_active_base_nodes_at_rank), - std::move(n_active_high_order_nodes_at_rank)); + _mesh_info.number_of_global_base_nodes, + _mesh_info.number_of_global_nodes, _mesh_info.number_of_regular_nodes, + std::move(n_regular_base_nodes_at_rank), + std::move(n_regular_high_order_nodes_at_rank)); } void NodePartitionedMeshReader::setNodes( @@ -453,8 +457,8 @@ void NodePartitionedMeshReader::setNodes( std::vector<MeshLib::Node*>& mesh_node, std::vector<unsigned long>& glb_node_ids) const { - mesh_node.resize(_mesh_info.nodes); - glb_node_ids.resize(_mesh_info.nodes); + mesh_node.resize(_mesh_info.number_of_nodes); + glb_node_ids.resize(_mesh_info.number_of_nodes); for (std::size_t i = 0; i < mesh_node.size(); i++) { @@ -470,10 +474,10 @@ void NodePartitionedMeshReader::setElements( std::vector<MeshLib::Element*>& mesh_elems, const bool ghost) const { // Number of elements, either ghost or regular - unsigned long const ne = - ghost ? _mesh_info.ghost_elements : _mesh_info.regular_elements; + unsigned long const ne = ghost ? _mesh_info.number_of_ghost_elements + : _mesh_info.number_of_regular_elements; unsigned long const id_offset_ghost = - ghost ? _mesh_info.regular_elements : 0; + ghost ? _mesh_info.number_of_regular_elements : 0; for (unsigned long i = 0; i < ne; i++) { diff --git a/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.h b/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.h index e4253eeef0432e52904219adb8af6a44fbfac9f4..e0140a4d3a46dd26c7420c9d1119053219f6f30e 100644 --- a/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.h +++ b/MeshLib/IO/MPI_IO/NodePartitionedMeshReader.h @@ -13,15 +13,16 @@ #pragma once +#include <mpi.h> + #include <iosfwd> #include <string> #include <vector> -#include <mpi.h> - +#include "MeshLib/IO/MPI_IO/PropertyVectorMetaData.h" +#include "MeshLib/IO/NodeData.h" #include "MeshLib/NodePartitionedMesh.h" #include "MeshLib/Properties.h" -#include "MeshLib/IO/MPI_IO/PropertyVectorMetaData.h" namespace MeshLib { @@ -64,42 +65,40 @@ private: /// MPI data type for struct NodeData. MPI_Datatype _mpi_node_type; - /// Node data only for parallel reading. - struct NodeData - { - std::size_t index; ///< Global node index. - double x; - double y; - double z; - }; - /// Define MPI data type for NodeData struct. void registerNodeDataMpiType(); /// A collection of integers that configure the partitioned mesh data. struct PartitionedMeshInfo { - unsigned long nodes; ///< 0: Number of all nodes of a partition, - unsigned long base_nodes; ///< 1: Number of nodes for linear - /// elements of a partition, - unsigned long regular_elements; ///< 2: Number of non-ghost elements - /// of a partition, - unsigned long ghost_elements; ///< 3: Number of ghost element of - /// a partition, - unsigned long active_base_nodes; ///< 4: Number of active nodes for - /// linear element of a partition, - unsigned long active_nodes; ///< 5: Number of all active nodes a - /// partition, - unsigned long global_base_nodes; ///< 6: unused, previously number of + unsigned long + number_of_nodes; ///< 0: Number of all nodes of a partition, + unsigned long number_of_base_nodes; ///< 1: Number of nodes for linear + /// elements of a partition, + unsigned long + number_of_regular_elements; ///< 2: Number of non-ghost elements + /// of a partition, + unsigned long + number_of_ghost_elements; ///< 3: Number of ghost element of + /// a partition, + unsigned long + number_of_regular_base_nodes; ///< 4: Number of regular nodes for + /// linear element of a partition, + unsigned long + number_of_regular_nodes; ///< 5: Number of all regular nodes a + /// partition, + unsigned long + number_of_global_base_nodes; ///< 6: unused, previously number of /// nodes for linear element of global /// mesh, - unsigned long global_nodes; ///< 7: Number of all nodes of global mesh, + unsigned long + number_of_global_nodes; ///< 7: Number of all nodes of global mesh, unsigned long offset[5]; ///< 8~12: Offsets of positions of partitions /// in the data arrays. unsigned long extra_flag; ///< 13: Reserved for extra flag. std::size_t size() const { return 14; } - unsigned long* data() { return &nodes; } + unsigned long* data() { return &number_of_nodes; } } _mesh_info; /*! diff --git a/MeshLib/IO/NodeData.h b/MeshLib/IO/NodeData.h new file mode 100644 index 0000000000000000000000000000000000000000..001c4b222151d4b62d584141eb95dbf0e2862998 --- /dev/null +++ b/MeshLib/IO/NodeData.h @@ -0,0 +1,29 @@ +/** + * \file + * \copyright + * Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + */ + +#pragma once + +namespace MeshLib::IO +{ +/// struct NodeData used for parallel reading and also partitioning +struct NodeData +{ + NodeData() = default; + + NodeData(std::size_t id, double ix, double iy, double iz) + : index(id), x(ix), y(iy), z(iz) + { + } + + std::size_t index; ///< Global node index. + double x; + double y; + double z; +}; +} // end namespace MeshLib::IO diff --git a/MeshLib/NodePartitionedMesh.cpp b/MeshLib/NodePartitionedMesh.cpp index eca33be71e4844ee3ef111f76a210c5354b69934..74df55d31b082bcabd99d39b1104547af1635857 100644 --- a/MeshLib/NodePartitionedMesh.cpp +++ b/MeshLib/NodePartitionedMesh.cpp @@ -15,14 +15,14 @@ namespace MeshLib { std::vector<int> getEndNodeIDRanks( std::size_t const n_global_nodes, - std::vector<std::size_t> const& n_active_base_nodes_at_rank, - std::vector<std::size_t> const& n_active_high_order_nodes_at_rank) + std::vector<std::size_t> const& n_regular_base_nodes_at_rank, + std::vector<std::size_t> const& n_regular_high_order_nodes_at_rank) { std::vector<int> data; - std::transform(n_active_base_nodes_at_rank.begin() + 1, - n_active_base_nodes_at_rank.end(), - n_active_high_order_nodes_at_rank.begin() + 1, + std::transform(n_regular_base_nodes_at_rank.begin() + 1, + n_regular_base_nodes_at_rank.end(), + n_regular_high_order_nodes_at_rank.begin() + 1, std::back_inserter(data), std::plus<int>()); data.push_back(n_global_nodes); @@ -38,27 +38,27 @@ NodePartitionedMesh::NodePartitionedMesh( Properties const& properties, const std::size_t n_global_base_nodes, const std::size_t n_global_nodes, - const std::size_t n_active_nodes, - std::vector<std::size_t>&& n_active_base_nodes_at_rank, - std::vector<std::size_t>&& n_active_high_order_nodes_at_rank) + const std::size_t n_regular_nodes, + std::vector<std::size_t>&& n_regular_base_nodes_at_rank, + std::vector<std::size_t>&& n_regular_high_order_nodes_at_rank) : Mesh(name, nodes, elements, properties), _global_node_ids(glb_node_ids), _n_global_base_nodes(n_global_base_nodes), _n_global_nodes(n_global_nodes), - _n_active_nodes(n_active_nodes), - _n_active_base_nodes_at_rank(std::move(n_active_base_nodes_at_rank)), - _n_active_high_order_nodes_at_rank( - std::move(n_active_high_order_nodes_at_rank)), + _n_regular_nodes(n_regular_nodes), + _n_regular_base_nodes_at_rank(std::move(n_regular_base_nodes_at_rank)), + _n_regular_high_order_nodes_at_rank( + std::move(n_regular_high_order_nodes_at_rank)), _end_node_id_at_rank( - getEndNodeIDRanks(n_global_nodes, _n_active_base_nodes_at_rank, - _n_active_high_order_nodes_at_rank)), + getEndNodeIDRanks(n_global_nodes, _n_regular_base_nodes_at_rank, + _n_regular_high_order_nodes_at_rank)), _is_single_thread(false) { } bool NodePartitionedMesh::isGhostNode(const std::size_t node_id) const { - return node_id >= _n_active_nodes; + return node_id >= _n_regular_nodes; } std::size_t NodePartitionedMesh::getMaximumNConnectedNodesToNode() const diff --git a/MeshLib/NodePartitionedMesh.h b/MeshLib/NodePartitionedMesh.h index d23b71c60a18bae8e160047c29877b08c8981030..1cce37ef93be00643b56b2ee2ecd35a469f09678 100644 --- a/MeshLib/NodePartitionedMesh.h +++ b/MeshLib/NodePartitionedMesh.h @@ -36,7 +36,7 @@ public: _global_node_ids(mesh.getNumberOfNodes()), _n_global_base_nodes(mesh.computeNumberOfBaseNodes()), _n_global_nodes(mesh.getNumberOfNodes()), - _n_active_nodes(mesh.getNumberOfNodes()), + _n_regular_nodes(mesh.getNumberOfNodes()), _is_single_thread(true) { for (std::size_t i = 0; i < _nodes.size(); i++) @@ -58,10 +58,10 @@ public: \param properties Mesh property. \param n_global_base_nodes Number of the base nodes of the global mesh. \param n_global_nodes Number of all nodes of the global mesh. - \param n_active_nodes Number of all active nodes. - \param n_active_base_nodes_at_rank Numbers of the active base nodes of + \param n_regular_nodes Number of all regular nodes. + \param n_regular_base_nodes_at_rank Numbers of the regular base nodes of all previous ranks. - \param n_active_high_order_nodes_at_rank Numbers of the active high + \param n_regular_high_order_nodes_at_rank Numbers of the regular high order nodes of all previous ranks. */ @@ -73,9 +73,9 @@ public: Properties const& properties, const std::size_t n_global_base_nodes, const std::size_t n_global_nodes, - const std::size_t n_active_nodes, - std::vector<std::size_t>&& n_active_base_nodes_at_rank, - std::vector<std::size_t>&& n_active_high_order_nodes_at_rank); + const std::size_t n_regular_nodes, + std::vector<std::size_t>&& n_regular_base_nodes_at_rank, + std::vector<std::size_t>&& n_regular_high_order_nodes_at_rank); /// Get the number of nodes of the global mesh for linear elements. std::size_t getNumberOfGlobalBaseNodes() const @@ -91,20 +91,20 @@ public: return _global_node_ids[node_id]; } - /// Get the number of all active nodes of the partition. - std::size_t getNumberOfActiveNodes() const { return _n_active_nodes; } + /// Get the number of all regular nodes of the partition. + std::size_t getNumberOfRegularNodes() const { return _n_regular_nodes; } /// Check whether a node with ID of node_id is a ghost node bool isGhostNode(const std::size_t node_id) const; - std::size_t getNumberOfActiveBaseNodesAtRank(int const partition_id) const + std::size_t getNumberOfRegularBaseNodesAtRank(int const partition_id) const { - return _n_active_base_nodes_at_rank[partition_id]; + return _n_regular_base_nodes_at_rank[partition_id]; } - std::size_t getNumberOfActiveHighOrderNodesAtRank( + std::size_t getNumberOfRegularHighOrderNodesAtRank( int const partition_id) const { - return _n_active_high_order_nodes_at_rank[partition_id]; + return _n_regular_high_order_nodes_at_rank[partition_id]; } // TODO I guess that is a simplified version of computeSparsityPattern() @@ -115,7 +115,7 @@ public: int getNumberOfPartitions() const { - return _n_active_base_nodes_at_rank.size(); + return _n_regular_base_nodes_at_rank.size(); } bool isForSingleThread() const { return _is_single_thread; } @@ -130,15 +130,15 @@ private: /// Number of all nodes of the global mesh. std::size_t _n_global_nodes; - /// Number of the all active nodes. - std::size_t _n_active_nodes; + /// Number of the all regular nodes. + std::size_t _n_regular_nodes; - /// Gathered numbers of the active nodes for linear interpolations of all + /// Gathered numbers of the regular nodes for linear interpolations of all /// partitions. - std::vector<std::size_t> _n_active_base_nodes_at_rank; + std::vector<std::size_t> _n_regular_base_nodes_at_rank; - /// Gathered numbers of the all active high order nodes of all partitions. - std::vector<std::size_t> _n_active_high_order_nodes_at_rank; + /// Gathered numbers of the all regular high order nodes of all partitions. + std::vector<std::size_t> _n_regular_high_order_nodes_at_rank; /// Gathered the end node id of each rank. std::vector<int> _end_node_id_at_rank; diff --git a/NumLib/DOF/MeshComponentMap.cpp b/NumLib/DOF/MeshComponentMap.cpp index cdbcb1b58eaef16a8a360d78a3e434ed7f09e568..a4bb5f31f5ddd8a6c87e7c1d903895d27db65a4a 100644 --- a/NumLib/DOF/MeshComponentMap.cpp +++ b/NumLib/DOF/MeshComponentMap.cpp @@ -339,10 +339,10 @@ GlobalIndexType getGlobalIndexWithTaylorHoodElement( int const partition_id = partitioned_mesh.getPartitionID(global_node_id); auto const n_total_active_base_nodes_before_this_rank = - partitioned_mesh.getNumberOfActiveBaseNodesAtRank(partition_id); + partitioned_mesh.getNumberOfRegularBaseNodesAtRank(partition_id); auto const n_total_active_high_order_nodes_before_this_rank = - partitioned_mesh.getNumberOfActiveHighOrderNodesAtRank(partition_id); + partitioned_mesh.getNumberOfRegularHighOrderNodesAtRank(partition_id); auto const node_id_offset = n_total_active_base_nodes_before_this_rank + @@ -362,7 +362,7 @@ GlobalIndexType getGlobalIndexWithTaylorHoodElement( } int const n_active_base_nodes_of_this_partition = - partitioned_mesh.getNumberOfActiveBaseNodesAtRank(partition_id + 1) - + partitioned_mesh.getNumberOfRegularBaseNodesAtRank(partition_id + 1) - n_total_active_base_nodes_before_this_rank; /* @@ -370,13 +370,13 @@ GlobalIndexType getGlobalIndexWithTaylorHoodElement( assuming that the base node has three components and the high order node has two components: - Partition | 0 | 1 | ... - -------------------------------- - Active nodes | Base | higher | Base | higher| ... - -------------------------------- - c0 x x x x ... - c1 x x x x ... - c2 x x ... + Partition | 0 | 1 | ... + -------------------------------- + Regular nodes | Base | higher | Base | higher| ... + -------------------------------- + c0 x x x x ... + c1 x x x x ... + c2 x x ... */ return static_cast<GlobalIndexType>( index_offset +