Adjust error when having distributed MSWells without setting --allow-distributed-wells=false

Instead of throwing inside the loop over all wells, collect the findings and throw at the end. Throwing inside of the loop over all wells leads to a deadlock in some cases.
This commit is contained in:
Lisa Julia Nebel committed 2025-05-08 16:37:17 +02:00
1 parent 46ccde6951
commit 40e7d65283
1 file changed
+29 -2
+29 -2
View File
@@ -44,6 +44,7 @@
#include <cassert>
#include <initializer_list>
#include <numeric>
#include <optional>
#include <set>
#include <stdexcept>
#include <type_traits>
@@ -669,6 +670,8 @@ void WellState<Scalar>::initWellStateMSWell(const std::vector<Well>& wells_ecl,
const auto& pu = this->phaseUsage();
const int np = pu.num_phases;
std::optional<std::string> distributedMSWellLocalErrorMessage;
// in the init function, the well rates and perforation rates have been initialized or copied from prevState
// what we do here, is to set the segment rates and perforation rates
for (int w = 0; w < nw; ++w) {
@@ -716,8 +719,26 @@ void WellState<Scalar>::initWellStateMSWell(const std::vector<Well>& wells_ecl,
}
ws.parallel_info.get().setActiveToLocalMap(active_to_local);
if (!this->enableDistributedWells_ && static_cast<int>(ws.perf_data.size()) != n_activeperf)
throw std::logic_error("Distributed multi-segment wells cannot be initialized properly yet.");
// Check if the multi-segment well is distributed across several processes by comparing the local number
// of active perforations (ws.perf_data.size()) with the total number of active perforations (n_activeperf).
// If they differ on any rank, the well is considered distributed.
if (static_cast<int>(ws.perf_data.size()) != n_activeperf) {
if (!distributedMSWellLocalErrorMessage) {
distributedMSWellLocalErrorMessage = ""; // First well with error: initialize the string
}
// Append to the existing error message for errors in further wells
*distributedMSWellLocalErrorMessage += fmt::format(
"Distributed multi-segment well {} detected on rank {}.\n"
"The number of active perforations on rank {} is {}, but the total number of active perforations is {}.\n\n",
well_ecl.name(),
ws.parallel_info.get().communication().rank(),
ws.parallel_info.get().communication().rank(),
ws.perf_data.size(),
n_activeperf
);
}
std::vector<std::vector<int>> segment_inlets(well_nseg);
@@ -809,6 +830,12 @@ void WellState<Scalar>::initWellStateMSWell(const std::vector<Well>& wells_ecl,
}
}
// Instead of throwing inside the loop over all wells, collect the findings and throw at the end.
// Throwing inside of the loop over all wells leads to a deadlock in some cases.
if (!this->enableDistributedWells_ && distributedMSWellLocalErrorMessage) {
throw std::logic_error(*distributedMSWellLocalErrorMessage);
}
if (prev_well_state) {
for (int w = 0; w < nw; ++w) {