From a2ae7d5beda9e46048bff30f89ee526fca5b66fe Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 24 Mar 2023 14:59:52 +0100 Subject: [PATCH] Fix resv for groups --- opm/simulators/wells/BlackoilWellModel.hpp | 1 + .../wells/BlackoilWellModelGeneric.cpp | 2 +- .../wells/BlackoilWellModelGeneric.hpp | 1 + .../wells/BlackoilWellModel_impl.hpp | 3 ++- opm/simulators/wells/WellAssemble.cpp | 16 +++++++++---- opm/simulators/wells/WellGroupConstraints.cpp | 4 ++-- opm/simulators/wells/WellGroupConstraints.hpp | 2 +- opm/simulators/wells/WellGroupControls.cpp | 8 +++---- opm/simulators/wells/WellGroupControls.hpp | 2 +- .../wells/WellInterfaceFluidSystem.cpp | 24 ++++++++++++++----- tests/test_RestartSerialization.cpp | 2 +- 11 files changed, 44 insertions(+), 21 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index 4ae748b99..559ee566b 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -444,6 +444,7 @@ namespace Opm { void calcRates(const int fipnum, const int pvtreg, + const std::vector& production_rates, std::vector& resv_coeff) override; void calcInjRates(const int fipnum, diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 16f1eeced..c1d2b68ab 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -549,7 +549,7 @@ checkGroupHigherConstraints(const Group& group, rates[phasePos] = -comm_.sum(local_current_rate); } std::vector resv_coeff(phase_usage_.num_phases, 0.0); - calcRates(fipnum, pvtreg, resv_coeff); + calcRates(fipnum, pvtreg, this->groupState().production_rates(group.name()), resv_coeff); // Check higher up only if under individual (not FLD) control. const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name()); if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) { diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 87f906314..cb2e3eaf2 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -312,6 +312,7 @@ protected: double wsolvent); virtual void calcRates(const int fipnum, const int pvtreg, + const std::vector& production_rates, std::vector& resv_coeff) = 0; virtual void calcInjRates(const int fipnum, const int pvtreg, diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index c194df689..f78390a48 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -1856,9 +1856,10 @@ namespace Opm { BlackoilWellModel:: calcRates(const int fipnum, const int pvtreg, + const std::vector& production_rates, std::vector& resv_coeff) { - rateConverter_->calcCoeff(fipnum, pvtreg, resv_coeff); + rateConverter_->calcCoeff(fipnum, pvtreg, production_rates, resv_coeff); } template diff --git a/opm/simulators/wells/WellAssemble.cpp b/opm/simulators/wells/WellAssemble.cpp index ed5b40761..7aeafa354 100644 --- a/opm/simulators/wells/WellAssemble.cpp +++ b/opm/simulators/wells/WellAssemble.cpp @@ -179,9 +179,13 @@ assembleControlEqProd(const WellState& well_state, active_rates[pu.phase_pos[canonical_phase]] = rates[canonical_phase]; } } - auto rCoeff = [this](const RegionId id, const int region, std::vector& coeff) + auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { - well_.rateConverter().calcCoeff(id, region, coeff); + if (prod_gname) + well_.rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); + else + well_.rateConverter().calcCoeff(id, region, coeff); + }; WellGroupControls(well_).getGroupProductionControl(group, well_state, group_state, @@ -269,9 +273,13 @@ assembleControlEqInj(const WellState& well_state, case Well::InjectorCMode::GRUP: { assert(well_.wellEcl().isAvailableForGroupControl()); const auto& group = schedule.getGroup(well_.wellEcl().groupName(), well_.currentStep()); - auto rCoeff = [this](const RegionId id, const int region, std::vector& coeff) + auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { - well_.rateConverter().calcInjCoeff(id, region, coeff); + if(prod_gname) { + well_.rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); + } else { + well_.rateConverter().calcInjCoeff(id, region, coeff); + } }; WellGroupControls(well_).getGroupInjectionControl(group, well_state, diff --git a/opm/simulators/wells/WellGroupConstraints.cpp b/opm/simulators/wells/WellGroupConstraints.cpp index 849915d34..240ccb95c 100644 --- a/opm/simulators/wells/WellGroupConstraints.cpp +++ b/opm/simulators/wells/WellGroupConstraints.cpp @@ -70,7 +70,7 @@ checkGroupConstraintsInj(const Group& group, // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(well_.phaseUsage().num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. const auto& ws = well_state.well(well_.indexOfWell()); // Call check for the well's injection phase. @@ -104,7 +104,7 @@ checkGroupConstraintsProd(const Group& group, { // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(well_.phaseUsage().num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. const auto& ws = well_state.well(well_.indexOfWell()); return WellGroupHelpers::checkGroupConstraintsProd(well_.name(), diff --git a/opm/simulators/wells/WellGroupConstraints.hpp b/opm/simulators/wells/WellGroupConstraints.hpp index 04e9f15ac..2dba927df 100644 --- a/opm/simulators/wells/WellGroupConstraints.hpp +++ b/opm/simulators/wells/WellGroupConstraints.hpp @@ -47,7 +47,7 @@ public: //! \brief Constructor sets reference to well. WellGroupConstraints(const WellInterfaceGeneric& well) : well_(well) {} - using RateConvFunc = std::function&)>; + using RateConvFunc = std::function&, std::vector&)>; bool checkGroupConstraints(WellState& well_state, const GroupState& group_state, diff --git a/opm/simulators/wells/WellGroupControls.cpp b/opm/simulators/wells/WellGroupControls.cpp index 6a5f021c9..166506c05 100644 --- a/opm/simulators/wells/WellGroupControls.cpp +++ b/opm/simulators/wells/WellGroupControls.cpp @@ -127,7 +127,7 @@ getGroupInjectionControl(const Group& group, // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(pu.num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), std::nullopt, resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. double sales_target = 0; if (schedule[well_.currentStep()].gconsale().has(group.name())) { @@ -251,7 +251,7 @@ getGroupInjectionTargetRate(const Group& group, // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(pu.num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), std::nullopt, resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. double sales_target = 0; if (schedule[well_.currentStep()].gconsale().has(group.name())) { @@ -353,7 +353,7 @@ void WellGroupControls::getGroupProductionControl(const Group& group, // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(well_.phaseUsage().num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. // gconsale may adjust the grat target. // the adjusted rates is send to the targetCalculator @@ -442,7 +442,7 @@ getGroupProductionTargetRate(const Group& group, // Make conversion factors for RESV <-> surface rates. std::vector resv_coeff(well_.phaseUsage().num_phases, 1.0); - rateConverter(0, well_.pvtRegionIdx(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. + rateConverter(0, well_.pvtRegionIdx(), group.name(), resv_coeff); // FIPNUM region 0 here, should use FIPNUM from WELSPECS. // gconsale may adjust the grat target. // the adjusted rates is send to the targetCalculator diff --git a/opm/simulators/wells/WellGroupControls.hpp b/opm/simulators/wells/WellGroupControls.hpp index 81a3bdf9c..168a391c2 100644 --- a/opm/simulators/wells/WellGroupControls.hpp +++ b/opm/simulators/wells/WellGroupControls.hpp @@ -47,7 +47,7 @@ public: //! \brief Constructor sets reference to well. WellGroupControls(const WellInterfaceGeneric& well) : well_(well) {} - using RateConvFunc = std::function&)>; + using RateConvFunc = std::function&, std::vector&)>; template void getGroupInjectionControl(const Group& group, diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 0fce0b473..67e26feed 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -131,9 +131,13 @@ checkGroupConstraints(WellState& well_state, const SummaryState& summaryState, DeferredLogger& deferred_logger) const { - auto rCoeff = [this](const int id, const int region, std::vector& coeff) + auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { - this->rateConverter().calcCoeff(id, region, coeff); + if (prod_gname) + this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); + else + this->rateConverter().calcInjCoeff(id, region, coeff); + }; return WellGroupConstraints(*this).checkGroupConstraints(well_state, group_state, @@ -187,9 +191,13 @@ getGroupInjectionTargetRate(const Group& group, double efficiencyFactor, DeferredLogger& deferred_logger) const { - auto rCoeff = [this](const int id, const int region, std::vector& coeff) + auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { - this->rateConverter().calcCoeff(id, region, coeff); + if (prod_gname) + this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); + else + this->rateConverter().calcInjCoeff(id, region, coeff); + }; return WellGroupControls(*this).getGroupInjectionTargetRate(group, well_state, @@ -210,9 +218,13 @@ getGroupProductionTargetRate(const Group& group, double efficiencyFactor, DeferredLogger& deferred_logger) const { - auto rCoeff = [this](const int id, const int region, std::vector& coeff) + auto rCoeff = [this, &group_state](const RegionId id, const int region, const std::optional& prod_gname, std::vector& coeff) { - this->rateConverter().calcCoeff(id, region, coeff); + if (prod_gname) + this->rateConverter().calcCoeff(id, region, group_state.production_rates(*prod_gname), coeff); + else + this->rateConverter().calcInjCoeff(id, region, coeff); + }; return WellGroupControls(*this).getGroupProductionTargetRate(group, well_state, diff --git a/tests/test_RestartSerialization.cpp b/tests/test_RestartSerialization.cpp index 506a0492b..a99cd64ce 100644 --- a/tests/test_RestartSerialization.cpp +++ b/tests/test_RestartSerialization.cpp @@ -275,7 +275,7 @@ public: switched_inj_groups_ = {{{"test4", Phase::SOLVENT}, "test5"}}; } - void calcRates(const int, const int, std::vector&) override + void calcRates(const int, const int, const std::vector&, std::vector&) override {} void calcInjRates(const int, const int, std::vector&) override