Merge pull request #5894 from totto82/gsatprod

Implement gsatprod
This commit is contained in:
Bård Skaflestad 2025-01-22 14:17:22 +01:00 committed by GitHub
commit e288a61c59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 79 additions and 1 deletions

View File

@ -49,6 +49,7 @@
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
#include <opm/input/eclipse/Schedule/Network/Balance.hpp>
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>

View File

@ -34,6 +34,7 @@
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
#include <opm/input/eclipse/Schedule/MSW/SICD.hpp>
#include <opm/input/eclipse/Schedule/MSW/Valve.hpp>

View File

@ -602,6 +602,14 @@ partiallySupported()
{20,{true, allow_values<double> {}, "GCONPROD(COMBRATE): linearly combined rate is not used and should be defaulted (1*)"}}, // LINEAR_COMBINED_TARGET
},
},
{
"GSATPROD",
{
{5,{true, allow_values<double> {.0}, "GSATPROD(RESV): reservoir volume rate is not supported and should be defaulted (1*)"}}, // RESERVOIR_VOLUME_RATE
{6,{true, allow_values<double> {.0}, "GSATPROD(GASLIFT): gaslift rate is not supported and should be defaulted (1*)"}}, // GASLIFT
{7,{false, allow_values<double> {.0}, "GSATPROD(CALRATE): calorific rate is not used and should be defaulted (1*)"}}, // CALORIFIC_RATE
},
},
{
"GUIDERAT",
{

View File

@ -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}},

View File

@ -119,6 +119,12 @@ void GlobalWellInfo<Scalar>::clear()
this->m_efficiency_scaling_factors.assign(this->name_map.size(), 1.0);
}
template<class Scalar>
bool GlobalWellInfo<Scalar>::isRank0() const
{
return is_rank0_;
}
template<class Scalar>
Scalar GlobalWellInfo<Scalar>::
efficiency_scaling_factor(const std::string& wname) const

View File

@ -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<std::size_t> local_map; // local_index -> global_index
@ -89,6 +91,7 @@ private:
std::vector<int> m_in_producing_group; // global_index -> int/bool
std::vector<int> m_is_open; // global_index -> int/bool
std::vector<Scalar> m_efficiency_scaling_factors; // global_index --> double
bool is_rank0_{true};
};

View File

@ -24,6 +24,7 @@
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#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/GPMaint.hpp>
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
@ -99,6 +100,14 @@ namespace Opm {
rate += gefac * sumWellPhaseRates(res_rates, groupTmp, schedule, wellState, reportStepIdx, phasePos, injector);
}
// 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);
}
}
for (const std::string& wellName : group.wells()) {
const auto& well_index = wellState.index(wellName);
if (!well_index.has_value())
@ -137,6 +146,42 @@ namespace Opm {
return rate;
}
template <typename Scalar>
Scalar WellGroupHelpers<Scalar>::
satelliteProduction(const ScheduleState& sched,
const std::vector<std::string>& 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 <typename Scalar>
std::optional<GSatProd::GSatProdGroup::Rate> WellGroupHelpers<Scalar>::
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<class Scalar>
void WellGroupHelpers<Scalar>::
setCmodeGroup(const Group& group,

View File

@ -22,8 +22,10 @@
#define OPM_WELLGROUPHELPERS_HEADER_INCLUDED
#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp>
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
#include <map>
#include <string>
@ -56,6 +58,13 @@ public:
const int phasePos,
const bool injector);
static Scalar satelliteProduction(const ScheduleState& sched,
const std::vector<std::string>& groups,
const GSatProd::GSatProdGroup::Rate rateComp);
static std::optional<GSatProd::GSatProdGroup::Rate>
selectRateComponent(const PhaseUsage& pu, const int phasePos);
static void setCmodeGroup(const Group& group,
const Schedule& schedule,
const SummaryState& summaryState,

View File

@ -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);

View File

@ -67,6 +67,7 @@
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateModel.hpp>
@ -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)