mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-10-25 07:07:42 -05:00
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:
1 parent
46ccde6951
commit
40e7d65283
1 file changed
+29
-2
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user