From e8f04eec683bbd044eae7d9bbdb4031178c69643 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 29 Jun 2023 12:40:57 +0200 Subject: [PATCH] changed: move all partitionCells code to partitionCells.cpp --- opm/simulators/flow/BlackoilModelEbos.hpp | 64 +----------- opm/simulators/flow/partitionCells.cpp | 113 +++++++++++++++++++++- opm/simulators/flow/partitionCells.hpp | 17 ++++ 3 files changed, 133 insertions(+), 61 deletions(-) diff --git a/opm/simulators/flow/BlackoilModelEbos.hpp b/opm/simulators/flow/BlackoilModelEbos.hpp index cc90cf423..5e48d691d 100644 --- a/opm/simulators/flow/BlackoilModelEbos.hpp +++ b/opm/simulators/flow/BlackoilModelEbos.hpp @@ -327,7 +327,11 @@ namespace Opm { { // Create partitions. const auto& [partition_vector, num_domains] = - this->partitionCells(); + partitionCells(this->grid_, + this->ebosSimulator_.vanguard().schedule().getWellsatEnd(), + this->param_.local_domain_partition_method_, + this->param_.num_local_domains_, + this->param_.local_domain_partition_imbalance_); // Scan through partitioning to get correct size for each. std::vector sizes(num_domains, 0); @@ -1936,19 +1940,6 @@ namespace Opm { } private: - template - struct HasZoltanPartitioning : public std::false_type {}; - - template - struct HasZoltanPartitioning< - GridType, - std::void_t().zoltanPartitionWithoutScatter - (std::declval*>(), - std::declval(), - std::declval(), - std::declval()))> - > : public std::true_type {}; - template bool isNumericalAquiferCell(const Dune::CpGrid& grid, const T& elem) { @@ -1975,51 +1966,6 @@ namespace Opm { double maxResidualAllowed() const { return param_.max_residual_allowed_; } double linear_solve_setup_time_; - std::pair, int> partitionCells() const - { - const std::string& method = this->param_.local_domain_partition_method_; - if (method == "zoltan") { - if constexpr (HasZoltanPartitioning::value) { - return this->partitionCellsZoltan(); - } else { - OPM_THROW(std::runtime_error, "Zoltan requested for local domain partitioning, " - "but is not available for the current grid type."); - } - } else if (method == "simple") { - const int num_cells = detail::countLocalInteriorCells(this->grid_); - return partitionCellsSimple(num_cells, this->param_.num_local_domains_); - } else if (method.size() > 10 && method.substr(method.size() - 10, 10) == ".partition") { - // Method string ends with ".partition", interpret as filename for partitioning. - const int num_cells = detail::countLocalInteriorCells(this->grid_); - return partitionCellsFromFile(method, num_cells); - } else { - OPM_THROW(std::runtime_error, "Unknown local domain partitioning method requested: " + method); - } - } - - std::pair, int> partitionCellsZoltan() const - { - const auto wells = this->ebosSimulator_.vanguard().schedule().getWellsatEnd(); - - auto partition_vector = this->grid_.zoltanPartitionWithoutScatter - (&wells, nullptr, this->param_.num_local_domains_, - this->param_.local_domain_partition_imbalance_); - - return this->countDomains(std::move(partition_vector)); - } - - std::pair, int> - countDomains(std::vector partition_vector) const - { - auto maxPos = std::max_element(partition_vector.begin(), - partition_vector.end()); - - const auto num_domains = (maxPos == partition_vector.end()) - ? 0 : *maxPos + 1; - - return { std::move(partition_vector), num_domains }; - } - public: std::vector wasSwitched_; }; diff --git a/opm/simulators/flow/partitionCells.cpp b/opm/simulators/flow/partitionCells.cpp index 7a39b5d7e..e4f5f1ea5 100644 --- a/opm/simulators/flow/partitionCells.cpp +++ b/opm/simulators/flow/partitionCells.cpp @@ -17,8 +17,20 @@ along with OPM. If not, see . */ +#include #include +#include +#include + +#include + +#include + +#if HAVE_DUNE_ALUGRID +#include +#endif // HAVE_DUNE_ALUGRID + #include #include @@ -28,9 +40,64 @@ #include #include #include +#include -namespace Opm -{ +namespace { + + std::pair, int> + countDomains(std::vector partition_vector) + { + auto maxPos = std::max_element(partition_vector.begin(), + partition_vector.end()); + + const auto num_domains = (maxPos == partition_vector.end()) + ? 0 : *maxPos + 1; + + return { std::move(partition_vector), num_domains }; + } + + template + struct HasZoltanPartitioning : public std::false_type {}; + + template + struct HasZoltanPartitioning< + GridType, + std::void_t().zoltanPartitionWithoutScatter + (std::declval*>(), + std::declval(), + std::declval(), + std::declval()))> + > : public std::true_type {}; + +} // anonymous namespace + +namespace Opm { + + template + std::pair, int> partitionCells(const Grid& grid, + const std::vector& wells, + const std::string& method, + const int num_local_domains, + const double partition_imbalance) + { + if (method == "zoltan") { + if constexpr (HasZoltanPartitioning::value) { + return partitionCellsZoltan(grid, wells, num_local_domains, partition_imbalance); + } else { + OPM_THROW(std::runtime_error, "Zoltan requested for local domain partitioning, " + "but is not available for the current grid type."); + } + } else if (method == "simple") { + const int num_cells = detail::countLocalInteriorCells(grid); + return partitionCellsSimple(num_cells, num_local_domains); + } else if (method.size() > 10 && method.substr(method.size() - 10, 10) == ".partition") { + // Method string ends with ".partition", interpret as filename for partitioning. + const int num_cells = detail::countLocalInteriorCells(grid); + return partitionCellsFromFile(method, num_cells); + } else { + OPM_THROW(std::runtime_error, "Unknown local domain partitioning method requested: " + method); + } + } // Read from file, containing one number per cell. @@ -71,4 +138,46 @@ namespace Opm } + template + std::pair, int> partitionCellsZoltan(const Grid& grid, + const std::vector& wells, + const int num_domains, + const double domain_imbalance) + { + auto partition_vector = grid.zoltanPartitionWithoutScatter + (&wells, nullptr, num_domains, domain_imbalance); + + return countDomains(std::move(partition_vector)); + } + + template std::pair,int> + partitionCells(const Dune::CpGrid&, + const std::vector&, + const std::string&, + const int, + const double); + + template std::pair,int> + partitionCells>(const Dune::PolyhedralGrid<3,3,double>&, + const std::vector&, + const std::string&, + const int, + const double); + +#if HAVE_DUNE_ALUGRID +#if HAVE_MPI + using ALUGrid3CN = Dune::ALUGrid<3, 3, Dune::cube, Dune::nonconforming, Dune::ALUGridMPIComm>; +#else + using ALUGrid3CN = Dune::ALUGrid<3, 3, Dune::cube, Dune::nonconforming, Dune::ALUGridNoComm>; +#endif //HAVE_MPI + + template std::pair,int> + partitionCells(const ALUGrid3CN&, + const std::vector&, + const std::string&, + const int, + const double); +#endif + + } // namespace Opm diff --git a/opm/simulators/flow/partitionCells.hpp b/opm/simulators/flow/partitionCells.hpp index b39077efc..fd2e62880 100644 --- a/opm/simulators/flow/partitionCells.hpp +++ b/opm/simulators/flow/partitionCells.hpp @@ -26,6 +26,16 @@ namespace Opm { + class Well; + + /// Partitions the grid using the specified method. + /// \return pair containing a partition vector (partition number for each cell), and the number of partitions. + template + std::pair, int> partitionCells(const Grid& grid, + const std::vector& wells, + const std::string& method, + const int num_local_domains, + const double partition_imbalance); /// Read a partitioning from file, assumed to contain one number per cell, its partition number. /// \return pair containing a partition vector (partition number for each cell), and the number of partitions. @@ -35,6 +45,13 @@ namespace Opm /// \return pair containing a partition vector (partition number for each cell), and the number of partitions. std::pair, int> partitionCellsSimple(const int num_cells, const int num_domains); + /// Partitions the grid using the Zoltan graph partitioner. + /// \return pair containing a partition vector (partition number for each cell), and the number of partitions. + template + std::pair, int> partitionCellsZoltan(const Grid& grid, + const std::vector& wells, + const int num_domains, + const double domain_imbalance); } // namespace Opm