From 68fe11878127fd8f956298eaf353f0b547d7667c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Mon, 23 Oct 2023 16:10:38 +0200 Subject: [PATCH] Make Compress/Count Partition Vector Helper Generally Available This function pair is useful also when loading a partition from file to ensure that there are no gaps in block numbering. --- CMakeLists_files.cmake | 2 + .../utils/ParallelNLDDPartitioningZoltan.cpp | 32 +------- opm/simulators/utils/compressPartition.cpp | 74 +++++++++++++++++++ opm/simulators/utils/compressPartition.hpp | 33 +++++++++ 4 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 opm/simulators/utils/compressPartition.cpp create mode 100644 opm/simulators/utils/compressPartition.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 340f56602..a07e6e63a 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -79,6 +79,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/timestepping/SimulatorTimerInterface.cpp opm/simulators/timestepping/gatherConvergenceReport.cpp opm/simulators/utils/ComponentName.cpp + opm/simulators/utils/compressPartition.cpp opm/simulators/utils/DeferredLogger.cpp opm/simulators/utils/gatherDeferredLogger.cpp opm/simulators/utils/ParallelFileMerger.cpp @@ -523,6 +524,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/timestepping/SimulatorTimerInterface.hpp opm/simulators/timestepping/gatherConvergenceReport.hpp opm/simulators/utils/ComponentName.hpp + opm/simulators/utils/compressPartition.hpp opm/simulators/utils/ParallelFileMerger.hpp opm/simulators/utils/DeferredLoggingErrorHelpers.hpp opm/simulators/utils/DeferredLogger.hpp diff --git a/opm/simulators/utils/ParallelNLDDPartitioningZoltan.cpp b/opm/simulators/utils/ParallelNLDDPartitioningZoltan.cpp index e897468eb..53726c5d0 100644 --- a/opm/simulators/utils/ParallelNLDDPartitioningZoltan.cpp +++ b/opm/simulators/utils/ParallelNLDDPartitioningZoltan.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -546,35 +547,6 @@ extern "C" { } } - std::vector compressPartitionIDs(std::vector&& parts0) - { - auto partition = std::move(parts0); - - if (! partition.empty()) { - auto mmPos = std::minmax_element(partition.begin(), partition.end()); - auto seen = std::vector(*mmPos.second - *mmPos.first + 1, false); - for (const auto& domain : partition) { - seen[domain - *mmPos.first] = domain >= 0; - } - - auto num_domains = 0; - auto compressed = std::vector(*mmPos.second - *mmPos.first + 1, -1); - for (auto i = 0*compressed.size(); i < compressed.size(); ++i) { - if (seen[i]) { - compressed[i] = num_domains++; - } - } - - for (auto& domain : partition) { - if (domain >= 0) { - domain = compressed[domain - *mmPos.first]; - } - } - } - - return partition; - } - } // Anonymous namespace std::vector @@ -603,5 +575,5 @@ Opm::ParallelNLDDPartitioningZoltan::partitionElements(const ZoltanParamMap& par ::forceSameDomain(cells, parts); } - return compressPartitionIDs(std::move(parts)); + return util::compressPartitionIDs(std::move(parts)); } diff --git a/opm/simulators/utils/compressPartition.cpp b/opm/simulators/utils/compressPartition.cpp new file mode 100644 index 000000000..43d097764 --- /dev/null +++ b/opm/simulators/utils/compressPartition.cpp @@ -0,0 +1,74 @@ +/* + Copyright 2023 Equinor ASA + + This file is part of the Open Porous Media Project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include + +#include +#include +#include +#include + +namespace { + + template + std::pair valueRange(const std::vector& x) + { + auto mmPos = std::minmax_element(x.begin(), x.end()); + + return { *mmPos.first, *mmPos.second }; + } + +} // Anonymous namespace + +std::pair, int> +Opm::util::compressAndCountPartitionIDs(std::vector&& parts0) +{ + auto parts = std::pair, int> { std::move(parts0), 0 }; + + auto& [partition, num_domains] = parts; + + if (! partition.empty()) { + const auto& [low, high] = valueRange(partition); + + auto seen = std::vector(high - low + 1, false); + for (const auto& domain : partition) { + seen[domain - low] = domain >= 0; + } + + auto compressed = std::vector(seen.size(), -1); + for (auto i = 0*compressed.size(); i < compressed.size(); ++i) { + if (seen[i]) { + compressed[i] = num_domains++; + } + } + + for (auto& domain : partition) { + if (domain >= 0) { + domain = compressed[domain - low]; + } + } + } + + return parts; +} + +std::vector Opm::util::compressPartitionIDs(std::vector&& parts0) +{ + return compressAndCountPartitionIDs(std::move(parts0)).first; +} diff --git a/opm/simulators/utils/compressPartition.hpp b/opm/simulators/utils/compressPartition.hpp new file mode 100644 index 000000000..4d90c38ee --- /dev/null +++ b/opm/simulators/utils/compressPartition.hpp @@ -0,0 +1,33 @@ +/* + Copyright 2023 Equinor ASA + + This file is part of the Open Porous Media Project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#ifndef OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED +#define OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED + +#include +#include + +namespace Opm { namespace util { + std::pair, int> + compressAndCountPartitionIDs(std::vector&& parts0); + + std::vector compressPartitionIDs(std::vector&& parts0); +}} // namespace Opm::util + +#endif // OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED