Include satellite injection, update satellite production

This commit is contained in:
Stein Krogstad committed 2025-09-10 16:21:43 +02:00
1 parent 490f70d91c
commit 934134ec9d
4 files changed
+81 -40

No files matched your search

@@ -577,6 +577,12 @@ partiallySupported()
{20,{true, allow_values<double> {}, "GCONPROD(COMBRATE): linearly combined rate is not used and should be defaulted (1*)"}}, // LINEAR_COMBINED_TARGET
},
},
{
"GSATINJE",
{
{4,{true, allow_values<double> {.0}, "GSATINJE(RESV): reservoir volume rate is not supported and should be defaulted (1*)"}}, // RESERVOIR_VOLUME_RATE
},
},
{
"GUIDERAT",
{
@@ -246,7 +246,6 @@ const KeywordValidation::UnsupportedKeywords& unsupportedKeywords()
{"GRUPRIG", {true, std::nullopt}},
{"GRUPSLAV", {true, std::nullopt}},
{"GRUPTARG", {true, std::nullopt}},
{"GSATINJE", {true, std::nullopt}},
{"GSEPCOND", {true, std::nullopt}},
{"GSSCPTST", {true, std::nullopt}},
{"GSWINGF", {true, std::nullopt}},
+64 -35
View File
@@ -25,6 +25,7 @@
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/GroupSatelliteInjection.hpp>
#include <opm/input/eclipse/Schedule/Group/GPMaint.hpp>
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
@@ -94,25 +95,27 @@ namespace Opm {
const bool injector,
const bool network)
{
// Only obtain satellite rates once (on rank 0)
Scalar rate = 0.0;
if (wellState.isRank0() && (group.hasSatelliteProduction() || group.hasSatelliteInjection())) {
if (injector) {
rate = satelliteInjectionRate(schedule[reportStepIdx], group, wellState.phaseUsageInfo(), phasePos, res_rates);
} else {
const auto rateComp = selectRateComponent(wellState.phaseUsageInfo(), phasePos);
if (rateComp.has_value()) {
rate = satelliteProductionRate(summaryState, schedule[reportStepIdx], group, *rateComp, res_rates);
}
}
// Satellite groups have no sub groups/wells so we're done
return rate;
}
for (const std::string& groupName : group.groups()) {
const auto& groupTmp = schedule.getGroup(groupName, reportStepIdx);
const auto& gefac = groupTmp.getGroupEfficiencyFactor(network);
rate += gefac * sumWellPhaseRates(res_rates, groupTmp, schedule, wellState, summaryState, reportStepIdx, phasePos, injector, network);
}
// only sum satellite production once
// With the current treatment, satellite production must also explicitly be accounted for in
// updateGroupTargetReduction. A cleaner solution would perhaps be to let sumWellPhaseRates return
// the satellite production directly (it currently returns zero for satellite groups).
if (wellState.isRank0() && !injector) {
const auto rateComp = selectRateComponent(wellState.phaseUsageInfo(), phasePos);
if (rateComp.has_value()) {
rate += satelliteProduction(summaryState, schedule[reportStepIdx], group.groups(), *rateComp);
}
}
for (const std::string& wellName : group.wells()) {
const auto well_index = wellState.index(wellName);
if (!well_index.has_value())
@@ -152,20 +155,58 @@ namespace Opm {
template<typename Scalar, typename IndexTraits>
Scalar WellGroupHelpers<Scalar, IndexTraits>::
satelliteProduction(const SummaryState& summaryState,
const ScheduleState& sched,
const std::vector<std::string>& groups,
const GSatProd::GSatProdGroupProp::Rate rateComp)
satelliteInjectionRate(const ScheduleState& sched,
const Group& group,
const PhaseUsageInfo<IndexTraits>& pu,
const int phase_pos,
bool res_rates)
{
auto gsatProdRate = Scalar{};
const auto& gsatProd = sched.gsatprod();
for (const auto& group : groups) {
if (! gsatProd.has(group)) {
continue;
Scalar rate = 0.0;
if (group.hasSatelliteInjection()) {
std::optional<Phase> ph;
for (const auto& [bo_phase, phase] : std::array {
std::pair( IndexTraits::waterPhaseIdx, Phase::WATER),
std::pair( IndexTraits::oilPhaseIdx, Phase::OIL),
std::pair( IndexTraits::gasPhaseIdx, Phase::GAS) })
{
if (pu.phaseIsActive(bo_phase) && (pu.canonicalToActivePhaseIdx(bo_phase) == phase_pos)) {
ph = phase;
}
}
if (ph.has_value()) {
const auto& satellite_inj = sched.satelliteInjection(group.name());
const auto& rate_ix = satellite_inj.rateIndex(ph.value());
if (rate_ix.has_value()) {
const auto& satrates = satellite_inj[*rate_ix];
if (!res_rates) { // surface rates
if (const auto& qs = satrates.surface(); qs.has_value()) {
rate = *qs;
}
// We don't support reservoir rates for satellite injection groups
}
}
}
gsatProdRate += gsatProd.get(group, summaryState).rate[rateComp];
}
return gsatProdRate;
return rate;
}
template <typename Scalar, typename IndexTraits>
Scalar WellGroupHelpers<Scalar, IndexTraits>::
satelliteProductionRate(const SummaryState& summaryState,
const ScheduleState& sched,
const Group& group,
const GSatProd::GSatProdGroupProp::Rate rateComp,
bool res_rates)
{
Scalar rate = 0.0;
if (group.hasSatelliteProduction()) {
const auto& gsatProd = sched.gsatprod();
if (!res_rates) {
rate = gsatProd.get(group.name(), summaryState).rate[rateComp];
}
// We don't support reservoir rates for satellite production groups
}
return rate;
}
template<typename Scalar, typename IndexTraits>
@@ -439,18 +480,6 @@ updateGroupTargetReduction(const Group& group,
}
}
// only sum satellite production once
// With the current treatment, satellite rates here must be added to target reduction excactly the same
// way as in sumWellPhaseRates (see comment there)
if (wellState.isRank0()) {
for (int phase = 0; phase < np; phase++) {
const auto rateComp = selectRateComponent(wellState.phaseUsageInfo(), phase);
if (rateComp.has_value()) {
groupTargetReduction[phase] += satelliteProduction(summaryState, schedule[reportStepIdx], group.groups(), *rateComp);
}
}
}
for (const std::string& wellName : group.wells()) {
const auto& wellTmp = schedule.getWell(wellName, reportStepIdx);
+11 -4
View File
@@ -63,10 +63,17 @@ public:
const bool injector,
const bool network = false);
static Scalar satelliteProduction(const SummaryState& summaryState,
const ScheduleState& sched,
const std::vector<std::string>& groups,
const GSatProd::GSatProdGroupProp::Rate rateComp);
static Scalar satelliteInjectionRate(const ScheduleState& sched,
const Group& group,
const PhaseUsageInfo<IndexTraits>& pu,
const int phase_pos,
bool res_rates);
static Scalar satelliteProductionRate(const SummaryState& summaryState,
const ScheduleState& sched,
const Group& group,
const GSatProd::GSatProdGroupProp::Rate rateComp,
bool res_rates);
static std::optional<GSatProd::GSatProdGroupProp::Rate>
selectRateComponent(const PhaseUsageInfo<IndexTraits>& pu, const int phasePos);