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.
This commit is contained in:
Bård Skaflestad 2023-10-23 16:10:38 +02:00
parent c0c96123bc
commit 68fe118781
4 changed files with 111 additions and 30 deletions

View File

@ -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

View File

@ -21,6 +21,7 @@
#include <opm/simulators/utils/ParallelNLDDPartitioningZoltan.hpp>
#include <opm/simulators/utils/compressPartition.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp>
#include <opm/common/ErrorMacros.hpp>
@ -546,35 +547,6 @@ extern "C" {
}
}
std::vector<int> compressPartitionIDs(std::vector<int>&& parts0)
{
auto partition = std::move(parts0);
if (! partition.empty()) {
auto mmPos = std::minmax_element(partition.begin(), partition.end());
auto seen = std::vector<bool>(*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<int>(*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<int>
@ -603,5 +575,5 @@ Opm::ParallelNLDDPartitioningZoltan::partitionElements(const ZoltanParamMap& par
::forceSameDomain(cells, parts);
}
return compressPartitionIDs(std::move(parts));
return util::compressPartitionIDs(std::move(parts));
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <opm/simulators/utils/compressPartition.hpp>
#include <algorithm>
#include <tuple>
#include <utility>
#include <vector>
namespace {
template <typename T>
std::pair<T, T> valueRange(const std::vector<T>& x)
{
auto mmPos = std::minmax_element(x.begin(), x.end());
return { *mmPos.first, *mmPos.second };
}
} // Anonymous namespace
std::pair<std::vector<int>, int>
Opm::util::compressAndCountPartitionIDs(std::vector<int>&& parts0)
{
auto parts = std::pair<std::vector<int>, int> { std::move(parts0), 0 };
auto& [partition, num_domains] = parts;
if (! partition.empty()) {
const auto& [low, high] = valueRange(partition);
auto seen = std::vector<bool>(high - low + 1, false);
for (const auto& domain : partition) {
seen[domain - low] = domain >= 0;
}
auto compressed = std::vector<int>(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<int> Opm::util::compressPartitionIDs(std::vector<int>&& parts0)
{
return compressAndCountPartitionIDs(std::move(parts0)).first;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED
#define OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED
#include <utility>
#include <vector>
namespace Opm { namespace util {
std::pair<std::vector<int>, int>
compressAndCountPartitionIDs(std::vector<int>&& parts0);
std::vector<int> compressPartitionIDs(std::vector<int>&& parts0);
}} // namespace Opm::util
#endif // OPM_UTIL_COMPRESS_PARTITION_HPP_INCLUDED