From fef6cfcf38de0bd8834f50e7b163514b2edd1fa5 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 17 Jan 2025 09:35:16 +0100 Subject: [PATCH 1/5] Fix parallel gsatprod --- opm/simulators/flow/FlowGenericVanguard.cpp | 1 + opm/simulators/utils/ParallelSerialization.cpp | 1 + tests/test_ParallelSerialization.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/opm/simulators/flow/FlowGenericVanguard.cpp b/opm/simulators/flow/FlowGenericVanguard.cpp index 1f6e0af49..52ceaeeb8 100644 --- a/opm/simulators/flow/FlowGenericVanguard.cpp +++ b/opm/simulators/flow/FlowGenericVanguard.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/opm/simulators/utils/ParallelSerialization.cpp b/opm/simulators/utils/ParallelSerialization.cpp index 1d34cb387..4b64ffe26 100644 --- a/opm/simulators/utils/ParallelSerialization.cpp +++ b/opm/simulators/utils/ParallelSerialization.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/test_ParallelSerialization.cpp b/tests/test_ParallelSerialization.cpp index e7bd453e9..6d41c2a64 100644 --- a/tests/test_ParallelSerialization.cpp +++ b/tests/test_ParallelSerialization.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -239,6 +240,7 @@ TEST_FOR_TYPE(FoamConfig) TEST_FOR_TYPE(FoamData) TEST_FOR_TYPE(GConSale) TEST_FOR_TYPE(GConSump) +TEST_FOR_TYPE(GSatProd) TEST_FOR_TYPE(GridDims) TEST_FOR_TYPE(Group) TEST_FOR_TYPE_NAMED(Group::GroupInjectionProperties, GroupInjectionProperties) From f9d66441975b4343e89c5253efa008ba13a40294 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 17 Jan 2025 12:34:47 +0100 Subject: [PATCH 2/5] add gsatprod to group rates --- opm/simulators/wells/GlobalWellInfo.cpp | 6 ++++++ opm/simulators/wells/GlobalWellInfo.hpp | 3 +++ opm/simulators/wells/WellGroupHelpers.cpp | 16 ++++++++++++++++ opm/simulators/wells/WellState.hpp | 4 ++++ 4 files changed, 29 insertions(+) diff --git a/opm/simulators/wells/GlobalWellInfo.cpp b/opm/simulators/wells/GlobalWellInfo.cpp index 294a4d117..0509c7fa4 100644 --- a/opm/simulators/wells/GlobalWellInfo.cpp +++ b/opm/simulators/wells/GlobalWellInfo.cpp @@ -119,6 +119,12 @@ void GlobalWellInfo::clear() this->m_efficiency_scaling_factors.assign(this->name_map.size(), 1.0); } +template +bool GlobalWellInfo::isRank0() const +{ + return is_rank0_; +} + template Scalar GlobalWellInfo:: efficiency_scaling_factor(const std::string& wname) const diff --git a/opm/simulators/wells/GlobalWellInfo.hpp b/opm/simulators/wells/GlobalWellInfo.hpp index 03c9152cb..c941e2969 100644 --- a/opm/simulators/wells/GlobalWellInfo.hpp +++ b/opm/simulators/wells/GlobalWellInfo.hpp @@ -65,6 +65,7 @@ public: comm.sum( this->m_in_producing_group.data(), size); comm.sum( this->m_is_open.data(), size); comm.min( this->m_efficiency_scaling_factors.data(), size); + is_rank0_ = (comm.rank() == 0); } @@ -80,6 +81,7 @@ public: void update_efficiency_scaling_factor(std::size_t well_index, const Scalar efficiency_scaling_factor); Scalar efficiency_scaling_factor(const std::string& wname) const; void clear(); + bool isRank0() const; private: std::vector local_map; // local_index -> global_index @@ -89,6 +91,7 @@ private: std::vector m_in_producing_group; // global_index -> int/bool std::vector m_is_open; // global_index -> int/bool std::vector m_efficiency_scaling_factors; // global_index --> double + bool is_rank0_{true}; }; diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index e54bb5783..c313ca76e 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,21 @@ namespace Opm { const auto& groupTmp = schedule.getGroup(groupName, reportStepIdx); const auto& gefac = groupTmp.getGroupEfficiencyFactor(); rate += gefac * sumWellPhaseRates(res_rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector); + const auto& gsatprod = schedule[reportStepIdx].gsatprod.get(); + // only sum once + if (wellState.isRank0() && !injector && gsatprod.has(groupName)) { + const auto& gsatprod_rates = gsatprod.get(groupName); + const auto& pu = wellState.phaseUsage(); + if (pu.phase_used[BlackoilPhases::Aqua] && pu.phase_pos[BlackoilPhases::Aqua] == phasePos) { + rate += gsatprod_rates.water_rate; + } + if (pu.phase_used[BlackoilPhases::Liquid] && pu.phase_pos[BlackoilPhases::Liquid] == phasePos) { + rate += gsatprod_rates.oil_rate; + } + if (pu.phase_used[BlackoilPhases::Vapour] && pu.phase_pos[BlackoilPhases::Vapour] == phasePos) { + rate += gsatprod_rates.gas_rate; + } + } } for (const std::string& wellName : group.wells()) { diff --git a/opm/simulators/wells/WellState.hpp b/opm/simulators/wells/WellState.hpp index fb5e4d063..a73925d28 100644 --- a/opm/simulators/wells/WellState.hpp +++ b/opm/simulators/wells/WellState.hpp @@ -260,6 +260,10 @@ public: bool wellIsOwned(const std::string& wellName) const; + bool isRank0() const { + return this->global_well_info.value().isRank0(); + } + void updateStatus(int well_index, WellStatus status); void openWell(int well_index); From 7ae7ff6ee041ccf1d9254657ee3222dd4a230f37 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 17 Jan 2025 12:44:59 +0100 Subject: [PATCH 3/5] Mark GSATPROD supported --- opm/simulators/utils/PartiallySupportedFlowKeywords.cpp | 8 ++++++++ opm/simulators/utils/UnsupportedFlowKeywords.cpp | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/opm/simulators/utils/PartiallySupportedFlowKeywords.cpp b/opm/simulators/utils/PartiallySupportedFlowKeywords.cpp index 96b4595c8..644ea31a1 100644 --- a/opm/simulators/utils/PartiallySupportedFlowKeywords.cpp +++ b/opm/simulators/utils/PartiallySupportedFlowKeywords.cpp @@ -602,6 +602,14 @@ partiallySupported() {20,{true, allow_values {}, "GCONPROD(COMBRATE): linearly combined rate is not used and should be defaulted (1*)"}}, // LINEAR_COMBINED_TARGET }, }, + { + "GSATPROD", + { + {5,{true, allow_values {.0}, "GSATPROD(RESV): reservoir volume rate is not supported and should be defaulted (1*)"}}, // RESERVOIR_VOLUME_RATE + {6,{true, allow_values {.0}, "GSATPROD(GASLIFT): gaslift rate is not supported and should be defaulted (1*)"}}, // GASLIFT + {7,{false, allow_values {.0}, "GSATPROD(CALRATE): calorific rate is not used and should be defaulted (1*)"}}, // CALORIFIC_RATE + }, + }, { "GUIDERAT", { diff --git a/opm/simulators/utils/UnsupportedFlowKeywords.cpp b/opm/simulators/utils/UnsupportedFlowKeywords.cpp index d8afce549..da61bbd8b 100644 --- a/opm/simulators/utils/UnsupportedFlowKeywords.cpp +++ b/opm/simulators/utils/UnsupportedFlowKeywords.cpp @@ -253,7 +253,6 @@ const KeywordValidation::UnsupportedKeywords& unsupportedKeywords() {"GTADD", {true, std::nullopt}}, {"GTMULT", {true, std::nullopt}}, {"GUIDECAL", {true, std::nullopt}}, - {"GSATPROD", {true, std::nullopt}}, {"GUPFREQ", {true, std::nullopt}}, {"GWRTWCV", {true, std::nullopt}}, {"HALFTRAN", {true, std::nullopt}}, From 5c8a9eca5bf77ebacf4692235588e6616c2b08d9 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 21 Jan 2025 12:55:59 +0100 Subject: [PATCH 4/5] adapt to changes in common --- opm/simulators/wells/WellGroupHelpers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index c313ca76e..3ea7428de 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -103,14 +103,15 @@ namespace Opm { if (wellState.isRank0() && !injector && gsatprod.has(groupName)) { const auto& gsatprod_rates = gsatprod.get(groupName); const auto& pu = wellState.phaseUsage(); + using Rate = GSatProd::GSatProdGroup::Rate; if (pu.phase_used[BlackoilPhases::Aqua] && pu.phase_pos[BlackoilPhases::Aqua] == phasePos) { - rate += gsatprod_rates.water_rate; + rate += gsatprod_rates.rate[Rate::Water]; } if (pu.phase_used[BlackoilPhases::Liquid] && pu.phase_pos[BlackoilPhases::Liquid] == phasePos) { - rate += gsatprod_rates.oil_rate; + rate += gsatprod_rates.rate[Rate::Oil]; } if (pu.phase_used[BlackoilPhases::Vapour] && pu.phase_pos[BlackoilPhases::Vapour] == phasePos) { - rate += gsatprod_rates.gas_rate; + rate += gsatprod_rates.rate[Rate::Gas]; } } } From 7b4894b60000fe6e17b41f692bfa9e83012fa477 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 22 Jan 2025 10:53:54 +0100 Subject: [PATCH 5/5] cleanup based on review --- opm/simulators/wells/WellGroupHelpers.cpp | 58 +++++++++++++++++------ opm/simulators/wells/WellGroupHelpers.hpp | 9 ++++ 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 3ea7428de..b0f20b846 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -98,21 +98,13 @@ namespace Opm { const auto& groupTmp = schedule.getGroup(groupName, reportStepIdx); const auto& gefac = groupTmp.getGroupEfficiencyFactor(); rate += gefac * sumWellPhaseRates(res_rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector); - const auto& gsatprod = schedule[reportStepIdx].gsatprod.get(); - // only sum once - if (wellState.isRank0() && !injector && gsatprod.has(groupName)) { - const auto& gsatprod_rates = gsatprod.get(groupName); - const auto& pu = wellState.phaseUsage(); - using Rate = GSatProd::GSatProdGroup::Rate; - if (pu.phase_used[BlackoilPhases::Aqua] && pu.phase_pos[BlackoilPhases::Aqua] == phasePos) { - rate += gsatprod_rates.rate[Rate::Water]; - } - if (pu.phase_used[BlackoilPhases::Liquid] && pu.phase_pos[BlackoilPhases::Liquid] == phasePos) { - rate += gsatprod_rates.rate[Rate::Oil]; - } - if (pu.phase_used[BlackoilPhases::Vapour] && pu.phase_pos[BlackoilPhases::Vapour] == phasePos) { - rate += gsatprod_rates.rate[Rate::Gas]; - } + } + + // only sum satelite production once + if (wellState.isRank0() && !injector) { + const auto rateComp = selectRateComponent(wellState.phaseUsage(), phasePos); + if (rateComp.has_value()) { + rate += satelliteProduction(schedule[reportStepIdx], group.groups(), *rateComp); } } @@ -154,6 +146,42 @@ namespace Opm { return rate; } +template +Scalar WellGroupHelpers:: +satelliteProduction(const ScheduleState& sched, + const std::vector& groups, + const GSatProd::GSatProdGroup::Rate rateComp) +{ + auto gsatProdRate = Scalar{}; + const auto& gsatProd = sched.gsatprod(); + for (const auto& group : groups) { + if (! gsatProd.has(group)) { + continue; + } + gsatProdRate += gsatProd.get(group).rate[rateComp]; + } + return gsatProdRate; +} + +template +std::optional WellGroupHelpers:: +selectRateComponent(const PhaseUsage& pu, const int phasePos) +{ + using Rate = GSatProd::GSatProdGroup::Rate; + + for (const auto& [phase, rateComp] : std::array { + std::pair { BlackoilPhases::Aqua, Rate::Water }, + std::pair { BlackoilPhases::Liquid, Rate::Oil }, + std::pair { BlackoilPhases::Vapour, Rate::Gas } }) + { + if (pu.phase_used[phase] && (pu.phase_pos[phase] == phasePos)) { + return rateComp; + } + } + + return std::nullopt; +} + template void WellGroupHelpers:: setCmodeGroup(const Group& group, diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index 00db85713..62bd15b28 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -22,8 +22,10 @@ #define OPM_WELLGROUPHELPERS_HEADER_INCLUDED #include +#include #include #include +#include #include #include @@ -56,6 +58,13 @@ public: const int phasePos, const bool injector); + static Scalar satelliteProduction(const ScheduleState& sched, + const std::vector& groups, + const GSatProd::GSatProdGroup::Rate rateComp); + + static std::optional + selectRateComponent(const PhaseUsage& pu, const int phasePos); + static void setCmodeGroup(const Group& group, const Schedule& schedule, const SummaryState& summaryState,