From dc607ce3ffc7ec0b19a78586a30d3a36c6824765 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 1/8] add BlackoilWellModelGuideRates start by moving getGuideRateValues --- CMakeLists_files.cmake | 2 + .../wells/BlackoilWellModelGeneric.cpp | 31 +--------- .../wells/BlackoilWellModelGeneric.hpp | 8 +-- .../wells/BlackoilWellModelGuideRates.cpp | 61 +++++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 58 ++++++++++++++++++ 5 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 opm/simulators/wells/BlackoilWellModelGuideRates.cpp create mode 100644 opm/simulators/wells/BlackoilWellModelGuideRates.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 64220e46d..b5c96746e 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -82,6 +82,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/wells/ALQState.cpp opm/simulators/wells/BlackoilWellModelConstraints.cpp opm/simulators/wells/BlackoilWellModelGeneric.cpp + opm/simulators/wells/BlackoilWellModelGuideRates.cpp opm/simulators/wells/BlackoilWellModelRestart.cpp opm/simulators/wells/GasLiftCommon.cpp opm/simulators/wells/GasLiftGroupInfo.cpp @@ -352,6 +353,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/BlackoilWellModel_impl.hpp opm/simulators/wells/BlackoilWellModelConstraints.hpp opm/simulators/wells/BlackoilWellModelGeneric.hpp + opm/simulators/wells/BlackoilWellModelGuideRates.hpp opm/simulators/wells/BlackoilWellModelRestart.hpp opm/simulators/wells/GasLiftCommon.hpp opm/simulators/wells/GasLiftGroupInfo.hpp diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 0e588f975..db13d5802 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -950,37 +951,11 @@ getGuideRateValues(const Well& well) const const auto qs = WellGroupHelpers:: getWellRateVector(this->wellState(), this->phase_usage_, wname); - this->getGuideRateValues(qs, well.isInjector(), wname, grval); + BlackoilWellModelGuideRates(*this).getGuideRateValues(qs, well.isInjector(), wname, grval); return grval; } -void -BlackoilWellModelGeneric:: -getGuideRateValues(const GuideRate::RateVector& qs, - const bool is_inj, - const std::string& wgname, - data::GuideRateValue& grval) const -{ - auto getGR = [this, &wgname, &qs](const GuideRateModel::Target t) - { - return this->guideRate_.getSI(wgname, t, qs); - }; - - // Note: GuideRate does currently (2020-07-20) not support Target::RES. - grval.set(data::GuideRateValue::Item::Gas, - getGR(GuideRateModel::Target::GAS)); - - grval.set(data::GuideRateValue::Item::Water, - getGR(GuideRateModel::Target::WAT)); - - if (!is_inj) { - // Producer. Extract "all" guiderate values. - grval.set(data::GuideRateValue::Item::Oil, - getGR(GuideRateModel::Target::OIL)); - } -} - data::GuideRateValue BlackoilWellModelGeneric:: getGuideRateValues(const Group& group) const @@ -1004,7 +979,7 @@ getGuideRateValues(const Group& group) const getProductionGroupRateVector(this->groupState(), this->phase_usage_, gname); const auto is_inj = false; // This procedure only applies to G*PGR. - this->getGuideRateValues(qs, is_inj, gname, grval); + BlackoilWellModelGuideRates(*this).getGuideRateValues(qs, is_inj, gname, grval); return grval; } diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index e225e33e2..193575c0e 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -165,6 +165,10 @@ public: const SummaryState& summaryState() const { return summaryState_; } + const GuideRate& guideRate() const { return guideRate_; } + + bool reportStepStarts() const { return report_step_starts_; } + protected: /* @@ -270,10 +274,6 @@ protected: data::GuideRateValue getGuideRateValues(const Group& group) const; data::GuideRateValue getGuideRateValues(const Well& well) const; data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; - void getGuideRateValues(const GuideRate::RateVector& qs, - const bool is_inj, - const std::string& wgname, - data::GuideRateValue& grval) const; void assignWellGuideRates(data::Wells& wsrpt, const int reportStepIdx) const; diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp new file mode 100644 index 000000000..2e703c93b --- /dev/null +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -0,0 +1,61 @@ +/* + Copyright 2016 SINTEF ICT, Applied Mathematics. + Copyright 2016 - 2017 Statoil ASA. + Copyright 2017 Dr. Blatt - HPC-Simulation-Software & Services + Copyright 2016 - 2018 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include +#include + +#include + +#include + +#include +#include + +namespace Opm { + +void +BlackoilWellModelGuideRates:: +getGuideRateValues(const GuideRate::RateVector& qs, + const bool is_inj, + const std::string& wgname, + data::GuideRateValue& grval) const +{ + auto getGR = [this, &wgname, &qs](const GuideRateModel::Target t) + { + return wellModel_.guideRate().getSI(wgname, t, qs); + }; + + // Note: GuideRate does currently (2020-07-20) not support Target::RES. + grval.set(data::GuideRateValue::Item::Gas, + getGR(GuideRateModel::Target::GAS)); + + grval.set(data::GuideRateValue::Item::Water, + getGR(GuideRateModel::Target::WAT)); + + if (!is_inj) { + // Producer. Extract "all" guiderate values. + grval.set(data::GuideRateValue::Item::Oil, + getGR(GuideRateModel::Target::OIL)); + } +} + +} diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp new file mode 100644 index 000000000..690cd0795 --- /dev/null +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -0,0 +1,58 @@ +/* + Copyright 2016 SINTEF ICT, Applied Mathematics. + Copyright 2016 - 2017 Statoil ASA. + Copyright 2017 Dr. Blatt - HPC-Simulation-Software & Services + Copyright 2016 - 2018 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#ifndef OPM_BLACKOILWELLMODEL_GUIDE_RATES_HEADER_INCLUDED +#define OPM_BLACKOILWELLMODEL_GUIDE_RATES_HEADER_INCLUDED + +#include + +#include + +namespace Opm { + +class BlackoilWellModelGeneric; +namespace data { class GuideRateValue; } +class Group; + +/// Class for handling the guide rates in the blackoil well model. +class BlackoilWellModelGuideRates +{ +public: + //! \brief Constructor initializes reference to the well model. + BlackoilWellModelGuideRates(const BlackoilWellModelGeneric& wellModel) + : wellModel_(wellModel) + {} + + //! \brief Obtain guide rate values. + void getGuideRateValues(const GuideRate::RateVector& qs, + const bool is_inj, + const std::string& wgname, + data::GuideRateValue& grval) const; + +private: + const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model +}; + + +} // namespace Opm + +#endif From 41b1a38de37b802a4ea999f7750b45d08cf1120e Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 2/8] move getGuideRateValues(Well) into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 29 +------------------ .../wells/BlackoilWellModelGeneric.hpp | 1 - .../wells/BlackoilWellModelGuideRates.cpp | 28 ++++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 4 +++ 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index db13d5802..fdd8f86cf 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -929,33 +929,6 @@ setWsolvent(const Group& group, } } -data::GuideRateValue -BlackoilWellModelGeneric:: -getGuideRateValues(const Well& well) const -{ - auto grval = data::GuideRateValue{}; - - const auto& wname = well.name(); - if (!this->wellState().has(wname)) { - // No flow rates for 'wname' -- might be before well comes - // online (e.g., for the initial condition before simulation - // starts). - return grval; - } - - if (!this->guideRate_.has(wname)) { - // No guiderates exist for 'wname'. - return grval; - } - - const auto qs = WellGroupHelpers:: - getWellRateVector(this->wellState(), this->phase_usage_, wname); - - BlackoilWellModelGuideRates(*this).getGuideRateValues(qs, well.isInjector(), wname, grval); - - return grval; -} - data::GuideRateValue BlackoilWellModelGeneric:: getGuideRateValues(const Group& group) const @@ -1195,7 +1168,7 @@ calculateAllGroupGuiderates(const int reportStepIdx) const ? gr[gname].injection : gr[gname].production; - grval += this->getGuideRateValues(well); + grval += BlackoilWellModelGuideRates(*this).getGuideRateValues(well); }); // Visit wells and groups before their parents, meaning no group is diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 193575c0e..6c5209ebe 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -272,7 +272,6 @@ protected: std::vector& resv_coeff) = 0; data::GuideRateValue getGuideRateValues(const Group& group) const; - data::GuideRateValue getGuideRateValues(const Well& well) const; data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; void assignWellGuideRates(data::Wells& wsrpt, diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index 2e703c93b..30a1f2683 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -58,4 +58,32 @@ getGuideRateValues(const GuideRate::RateVector& qs, } } +data::GuideRateValue +BlackoilWellModelGuideRates:: +getGuideRateValues(const Well& well) const +{ + auto grval = data::GuideRateValue{}; + + const auto& wname = well.name(); + if (!wellModel_.wellState().has(wname)) { + // No flow rates for 'wname' -- might be before well comes + // online (e.g., for the initial condition before simulation + // starts). + return grval; + } + + if (!wellModel_.guideRate().has(wname)) { + // No guiderates exist for 'wname'. + return grval; + } + + const auto qs = WellGroupHelpers:: + getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname); + + this->getGuideRateValues(qs, well.isInjector(), wname, grval); + + return grval; +} + + } diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 690cd0795..14640646a 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -32,6 +32,7 @@ namespace Opm { class BlackoilWellModelGeneric; namespace data { class GuideRateValue; } class Group; +class Well; /// Class for handling the guide rates in the blackoil well model. class BlackoilWellModelGuideRates @@ -48,6 +49,9 @@ public: const std::string& wgname, data::GuideRateValue& grval) const; + //! \brief Obtain guide rate values for well. + data::GuideRateValue getGuideRateValues(const Well& well) const; + private: const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model }; From b6659d69606decfd38da8a566b23006c473380d5 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 3/8] move getGuideRateValues(Group) into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 30 +------------------ .../wells/BlackoilWellModelGeneric.hpp | 1 - .../wells/BlackoilWellModelGuideRates.cpp | 27 +++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 3 ++ 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index fdd8f86cf..a8f2a77e9 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -929,34 +929,6 @@ setWsolvent(const Group& group, } } -data::GuideRateValue -BlackoilWellModelGeneric:: -getGuideRateValues(const Group& group) const -{ - auto grval = data::GuideRateValue{}; - const auto& gname = group.name(); - - if (!this->groupState().has_production_rates(gname)) { - // No flow rates for production group 'gname' -- might be before - // group comes online (e.g., for the initial condition before - // simulation starts). - return grval; - } - - if (!this->guideRate_.has(gname)) { - // No guiderates exist for 'gname'. - return grval; - } - - const auto qs = WellGroupHelpers:: - getProductionGroupRateVector(this->groupState(), this->phase_usage_, gname); - - const auto is_inj = false; // This procedure only applies to G*PGR. - BlackoilWellModelGuideRates(*this).getGuideRateValues(qs, is_inj, gname, grval); - - return grval; -} - data::GuideRateValue BlackoilWellModelGeneric:: getGuideRateInjectionGroupValues(const Group& group) const @@ -1136,7 +1108,7 @@ calculateAllGroupGuiderates(const int reportStepIdx) const if (gname == "FIELD") { return; } if (this->guideRate_.has(gname)) { - gr[gname].production = this->getGuideRateValues(group); + gr[gname].production = BlackoilWellModelGuideRates(*this).getGuideRateValues(group); } if (this->guideRate_.has(gname, Phase::WATER) || diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 6c5209ebe..e67bb5478 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -271,7 +271,6 @@ protected: const int pvtreg, std::vector& resv_coeff) = 0; - data::GuideRateValue getGuideRateValues(const Group& group) const; data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; void assignWellGuideRates(data::Wells& wsrpt, diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index 30a1f2683..41e8a7447 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -85,5 +85,32 @@ getGuideRateValues(const Well& well) const return grval; } +data::GuideRateValue +BlackoilWellModelGuideRates:: +getGuideRateValues(const Group& group) const +{ + auto grval = data::GuideRateValue{}; + const auto& gname = group.name(); + + if (!wellModel_.groupState().has_production_rates(gname)) { + // No flow rates for production group 'gname' -- might be before + // group comes online (e.g., for the initial condition before + // simulation starts). + return grval; + } + + if (!wellModel_.guideRate().has(gname)) { + // No guiderates exist for 'gname'. + return grval; + } + + const auto qs = WellGroupHelpers:: + getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname); + + const auto is_inj = false; // This procedure only applies to G*PGR. + this->getGuideRateValues(qs, is_inj, gname, grval); + + return grval; +} } diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 14640646a..9c93558f1 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -52,6 +52,9 @@ public: //! \brief Obtain guide rate values for well. data::GuideRateValue getGuideRateValues(const Well& well) const; + //! \brief Obtain guide rate values for group. + data::GuideRateValue getGuideRateValues(const Group& group) const; + private: const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model }; From f19c7b2ee6df74af13b88342bfc6271a30715a6b Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 4/8] move getGuideRateInjectionGroupValues into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 22 +------------------ .../wells/BlackoilWellModelGeneric.hpp | 2 -- .../wells/BlackoilWellModelGuideRates.cpp | 20 +++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 3 +++ 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index a8f2a77e9..a31f63feb 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -929,26 +929,6 @@ setWsolvent(const Group& group, } } -data::GuideRateValue -BlackoilWellModelGeneric:: -getGuideRateInjectionGroupValues(const Group& group) const -{ - auto grval = data::GuideRateValue{}; - - const auto& gname = group.name(); - if (this->guideRate_.has(gname, Phase::GAS)) { - grval.set(data::GuideRateValue::Item::Gas, - this->guideRate_.getSI(gname, Phase::GAS)); - } - - if (this->guideRate_.has(gname, Phase::WATER)) { - grval.set(data::GuideRateValue::Item::Water, - this->guideRate_.getSI(gname, Phase::WATER)); - } - - return grval; -} - void BlackoilWellModelGeneric:: assignWellGuideRates(data::Wells& wsrpt, @@ -1115,7 +1095,7 @@ calculateAllGroupGuiderates(const int reportStepIdx) const this->guideRate_.has(gname, Phase::GAS)) { gr[gname].injection = - this->getGuideRateInjectionGroupValues(group); + BlackoilWellModelGuideRates(*this).getGuideRateInjectionGroupValues(group); } const auto parent = group.parent(); diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index e67bb5478..35ffa9204 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -271,8 +271,6 @@ protected: const int pvtreg, std::vector& resv_coeff) = 0; - data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; - void assignWellGuideRates(data::Wells& wsrpt, const int reportStepIdx) const; void assignShutConnections(data::Wells& wsrpt, diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index 41e8a7447..098f370ee 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -113,4 +113,24 @@ getGuideRateValues(const Group& group) const return grval; } +data::GuideRateValue +BlackoilWellModelGuideRates:: +getGuideRateInjectionGroupValues(const Group& group) const +{ + auto grval = data::GuideRateValue{}; + + const auto& gname = group.name(); + if (wellModel_.guideRate().has(gname, Phase::GAS)) { + grval.set(data::GuideRateValue::Item::Gas, + wellModel_.guideRate().getSI(gname, Phase::GAS)); + } + + if (wellModel_.guideRate().has(gname, Phase::WATER)) { + grval.set(data::GuideRateValue::Item::Water, + wellModel_.guideRate().getSI(gname, Phase::WATER)); + } + + return grval; +} + } diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 9c93558f1..41a3ec2d4 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -55,6 +55,9 @@ public: //! \brief Obtain guide rate values for group. data::GuideRateValue getGuideRateValues(const Group& group) const; + //! \brief Obtain guide rate values for injection group. + data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; + private: const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model }; From 01dfe23a507f3fe2c1b4015d68bc31cc60d09f59 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 5/8] move assignWellGuideRates into BlackoilWellModelGuideRates --- opm/simulators/wells/BlackoilWellModel.hpp | 3 +- .../wells/BlackoilWellModelGeneric.cpp | 154 -------- .../wells/BlackoilWellModelGeneric.hpp | 2 - .../wells/BlackoilWellModelGuideRates.cpp | 339 ++++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 9 +- 5 files changed, 349 insertions(+), 158 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModel.hpp b/opm/simulators/wells/BlackoilWellModel.hpp index e25ff5ab3..b84ce54a7 100644 --- a/opm/simulators/wells/BlackoilWellModel.hpp +++ b/opm/simulators/wells/BlackoilWellModel.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -241,7 +242,7 @@ namespace Opm { this->assignWellTracerRates(wsrpt); - this->assignWellGuideRates(wsrpt, this->reportStepIndex()); + BlackoilWellModelGuideRates(*this).assignWellGuideRates(wsrpt, this->reportStepIndex()); this->assignShutConnections(wsrpt, this->reportStepIndex()); return wsrpt; diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index a31f63feb..17870ec23 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -59,52 +59,6 @@ #include namespace { - struct RetrieveWellGuideRate - { - RetrieveWellGuideRate() = default; - - explicit RetrieveWellGuideRate(const Opm::GuideRate& guideRate, - const std::string& wgname); - - explicit RetrieveWellGuideRate(const Opm::GuideRate& guideRate, - const Opm::Group& group); - - bool prod { false }; - bool inj_water { false }; - bool inj_gas { false }; - }; - - RetrieveWellGuideRate - operator||(RetrieveWellGuideRate lhs, const RetrieveWellGuideRate& rhs) - { - lhs.prod = lhs.prod || rhs.prod; - lhs.inj_water = lhs.inj_water || rhs.inj_water; - lhs.inj_gas = lhs.inj_gas || rhs.inj_gas; - - return lhs; - } - - RetrieveWellGuideRate::RetrieveWellGuideRate(const Opm::GuideRate& guideRate, - const std::string& wgname) - : prod { guideRate.has(wgname) } - , inj_water { guideRate.has(wgname, Opm::Phase::WATER) } - , inj_gas { guideRate.has(wgname, Opm::Phase::GAS) } - {} - - RetrieveWellGuideRate::RetrieveWellGuideRate(const Opm::GuideRate& guideRate, - const Opm::Group& group) - : RetrieveWellGuideRate{ guideRate, group.name() } - { - if (group.isProductionGroup()) { - this->prod = true; - } - - if (group.isInjectionGroup()) { - this->inj_water = this->inj_water || group.hasInjectionControl(Opm::Phase::WATER); - this->inj_gas = this->inj_gas || group.hasInjectionControl(Opm::Phase::GAS); - } - } - class GroupTreeWalker { public: @@ -135,7 +89,6 @@ namespace { this->visitWell_ = WellOp{}; } - void traversePreOrder(); void traversePostOrder(); private: @@ -169,14 +122,6 @@ namespace { const Opm::Well& getWell(std::string_view well) const; }; - void GroupTreeWalker::traversePreOrder() - { - this->preFinish_ = nullptr; - this->postDiscover_ = &GroupTreeWalker::visitGroup; - - this->traverse(); - } - void GroupTreeWalker::traversePostOrder() { this->preFinish_ = &GroupTreeWalker::visitGroup; @@ -929,105 +874,6 @@ setWsolvent(const Group& group, } } -void -BlackoilWellModelGeneric:: -assignWellGuideRates(data::Wells& wsrpt, - const int reportStepIdx) const -{ - auto all = std::unordered_map{}; - auto retrieve = std::unordered_map{}; - - auto walker = GroupTreeWalker{ this->schedule(), reportStepIdx }; - - // Populates 'retrieve'. - walker.groupOp([this, &retrieve](const Group& group) - { - const auto& gname = group.name(); - - const auto parent = (gname == "FIELD") - ? RetrieveWellGuideRate{} - : retrieve[group.parent()]; - - auto [elm, inserted] = - retrieve.emplace(std::piecewise_construct, - std::forward_as_tuple(gname), - std::forward_as_tuple(this->guideRate_, group)); - - if (inserted) { - elm->second = elm->second || parent; - } - }); - - // Populates 'all'. - walker.wellOp([this, &retrieve, &all](const Well& well) - { - const auto& wname = well.name(); - - const auto is_nontrivial = - this->guideRate_.has(wname) || this->guideRate_.hasPotentials(wname); - - if (! (is_nontrivial && this->wellState().has(wname))) { - all[wname].clear(); - return; - } - - auto parent_pos = retrieve.find(well.groupName()); - const auto parent = (parent_pos == retrieve.end()) - ? RetrieveWellGuideRate{} // No entry for 'parent'--unexpected. - : parent_pos->second; - - const auto get_gr = parent - || RetrieveWellGuideRate{ this->guideRate_, wname }; - - const auto qs = WellGroupHelpers:: - getWellRateVector(this->wellState(), this->phase_usage_, wname); - - auto getGR = [this, &wname, &qs](const GuideRateModel::Target t) - { - return this->guideRate_.getSI(wname, t, qs); - }; - - auto& grval = all[wname]; - - if (well.isInjector()) { - if (get_gr.inj_gas) { // Well supports WGIGR - grval.set(data::GuideRateValue::Item::Gas, - getGR(GuideRateModel::Target::GAS)); - } - if (get_gr.inj_water) { // Well supports WWIGR - grval.set(data::GuideRateValue::Item::Water, - getGR(GuideRateModel::Target::WAT)); - } - } - else if (get_gr.prod) { // Well is producer AND we want/support WxPGR - grval - .set(data::GuideRateValue::Item::Oil , getGR(GuideRateModel::Target::OIL)) - .set(data::GuideRateValue::Item::Gas , getGR(GuideRateModel::Target::GAS)) - .set(data::GuideRateValue::Item::Water, getGR(GuideRateModel::Target::WAT)); - } - }); - - // Visit groups before their children, meaning no well is visited until - // all of its upline parent groups--up to FIELD--have been visited. - // Upon completion, 'all' contains guide rate values for all wells - // reachable from 'FIELD' at this time/report step. - walker.traversePreOrder(); - - for (const auto& well : this->wells_ecl_) { - auto xwPos = wsrpt.find(well.name()); - if (xwPos == wsrpt.end()) { // No well results. Unexpected. - continue; - } - - auto grPos = all.find(well.name()); - if (grPos == all.end()) { - continue; - } - - xwPos->second.guide_rates = grPos->second; - } -} - void BlackoilWellModelGeneric:: assignShutConnections(data::Wells& wsrpt, diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 35ffa9204..cde18dd5f 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -271,8 +271,6 @@ protected: const int pvtreg, std::vector& resv_coeff) = 0; - void assignWellGuideRates(data::Wells& wsrpt, - const int reportStepIdx) const; void assignShutConnections(data::Wells& wsrpt, const int reportStepIndex) const; void assignGroupControl(const Group& group, diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index 098f370ee..fd006795b 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -23,12 +23,253 @@ #include #include +#include #include #include #include #include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +struct RetrieveWellGuideRate +{ + RetrieveWellGuideRate() = default; + + explicit RetrieveWellGuideRate(const Opm::GuideRate& guideRate, + const std::string& wgname); + + explicit RetrieveWellGuideRate(const Opm::GuideRate& guideRate, + const Opm::Group& group); + + bool prod { false }; + bool inj_water { false }; + bool inj_gas { false }; +}; + +RetrieveWellGuideRate +operator||(RetrieveWellGuideRate lhs, const RetrieveWellGuideRate& rhs) +{ + lhs.prod = lhs.prod || rhs.prod; + lhs.inj_water = lhs.inj_water || rhs.inj_water; + lhs.inj_gas = lhs.inj_gas || rhs.inj_gas; + + return lhs; +} + +RetrieveWellGuideRate::RetrieveWellGuideRate(const Opm::GuideRate& guideRate, + const std::string& wgname) + : prod { guideRate.has(wgname) } + , inj_water { guideRate.has(wgname, Opm::Phase::WATER) } + , inj_gas { guideRate.has(wgname, Opm::Phase::GAS) } +{} + +RetrieveWellGuideRate::RetrieveWellGuideRate(const Opm::GuideRate& guideRate, + const Opm::Group& group) + : RetrieveWellGuideRate{ guideRate, group.name() } +{ + if (group.isProductionGroup()) { + this->prod = true; + } + + if (group.isInjectionGroup()) { + this->inj_water = this->inj_water || group.hasInjectionControl(Opm::Phase::WATER); + this->inj_gas = this->inj_gas || group.hasInjectionControl(Opm::Phase::GAS); + } +} + +class GroupTreeWalker +{ +public: + using GroupOp = std::function; + using WellOp = std::function; + + explicit GroupTreeWalker(const Opm::Schedule& sched, + const int reportStepIdx) + : sched_ (sched) + , reportStepIdx_(reportStepIdx) + {} + + GroupTreeWalker& groupOp(GroupOp visit) + { + this->visitGroup_ = std::move(visit); + return *this; + } + + GroupTreeWalker& wellOp(WellOp visit) + { + this->visitWell_ = std::move(visit); + return *this; + } + + void clear() + { + this->visitGroup_ = GroupOp{}; + this->visitWell_ = WellOp{}; + } + + void traversePreOrder(); + +private: + using NodeOp = void (GroupTreeWalker::*)(std::string_view) const; + + std::reference_wrapper sched_; + int reportStepIdx_; + + GroupOp visitGroup_{}; + WellOp visitWell_{}; + + std::stack> dfsGroupStack_{}; + std::unordered_set dfsGroupDiscovered_{}; + + NodeOp postDiscover_{nullptr}; + NodeOp preFinish_{nullptr}; + + void traverse(); + + void startWalk(); + void discover(std::string_view group); + void finish(std::string_view group); + + bool isSeen(std::string_view group) const; + std::size_t insertIndex(std::string_view group) const; + + void visitGroup(std::string_view group) const; + void visitWell(std::string_view well) const; + + const Opm::Group& getGroup(std::string_view group) const; + const Opm::Well& getWell(std::string_view well) const; +}; + +void GroupTreeWalker::traversePreOrder() +{ + this->preFinish_ = nullptr; + this->postDiscover_ = &GroupTreeWalker::visitGroup; + + this->traverse(); +} + +void GroupTreeWalker::traverse() +{ + this->startWalk(); + + while (! this->dfsGroupStack_.empty()) { + const auto gname = this->dfsGroupStack_.top(); + + if (this->isSeen(gname)) { + if (this->preFinish_ != nullptr) { + (this->*preFinish_)(gname); + } + + this->finish(gname); + continue; + } + + this->discover(gname); + + if (this->postDiscover_ != nullptr) { + (this->*postDiscover_)(gname); + } + + const auto& group = this->getGroup(gname); + + if (! group.wellgroup()) { // Node group. Register child groups. + for (const auto& child : group.groups()) { + if (! this->isSeen(child)) { + this->dfsGroupStack_.push(child); + } + } + } + else { // Group is a well group--visit its wells. + for (const auto& well : group.wells()) { + this->visitWell(well); + } + } + } +} + +void GroupTreeWalker::startWalk() +{ + this->dfsGroupDiscovered_.clear(); + + while (! this->dfsGroupStack_.empty()) { + this->dfsGroupStack_.pop(); + } + + this->dfsGroupStack_.push("FIELD"); +} + +void GroupTreeWalker::discover(std::string_view group) +{ + this->dfsGroupDiscovered_.insert(this->insertIndex(group)); +} + +void GroupTreeWalker::finish(std::string_view group) +{ + if (this->dfsGroupStack_.top() != group) { + throw std::invalid_argument { + fmt::format("Internal Error: Expected group '{}', but got '{}'", + group, this->dfsGroupStack_.top()) + }; + } + + this->dfsGroupStack_.pop(); +} + +bool GroupTreeWalker::isSeen(std::string_view group) const +{ + return this->dfsGroupDiscovered_.find(this->insertIndex(group)) + != this->dfsGroupDiscovered_.end(); +} + +std::size_t GroupTreeWalker::insertIndex(std::string_view group) const +{ + return this->getGroup(group).insert_index(); +} + +void GroupTreeWalker::visitGroup(std::string_view group) const +{ + if (! this->visitGroup_) { + return; + } + + this->visitGroup_(this->getGroup(group)); +} + +void GroupTreeWalker::visitWell(std::string_view well) const +{ + if (! this->visitWell_) { + return; + } + + this->visitWell_(this->getWell(well)); +} + +const Opm::Group& GroupTreeWalker::getGroup(std::string_view group) const +{ + return this->sched_.get().getGroup({group.data(), group.size()}, this->reportStepIdx_); +} + +const Opm::Well& GroupTreeWalker::getWell(std::string_view well) const +{ + return this->sched_.get().getWell({well.data(), well.size()}, this->reportStepIdx_); +} + +} // anonymous namespace namespace Opm { @@ -133,4 +374,102 @@ getGuideRateInjectionGroupValues(const Group& group) const return grval; } +void BlackoilWellModelGuideRates:: +assignWellGuideRates(data::Wells& wsrpt, + const int reportStepIdx) const +{ + auto all = std::unordered_map{}; + auto retrieve = std::unordered_map{}; + + auto walker = GroupTreeWalker{wellModel_.schedule(), reportStepIdx}; + + // Populates 'retrieve'. + walker.groupOp([this, &retrieve](const Group& group) + { + const auto& gname = group.name(); + + const auto parent = (gname == "FIELD") + ? RetrieveWellGuideRate{} + : retrieve[group.parent()]; + + auto [elm, inserted] = + retrieve.emplace(std::piecewise_construct, + std::forward_as_tuple(gname), + std::forward_as_tuple(wellModel_.guideRate(), group)); + + if (inserted) { + elm->second = elm->second || parent; + } + }); + + // Populates 'all'. + walker.wellOp([this, &retrieve, &all](const Well& well) + { + const auto& wname = well.name(); + + const auto is_nontrivial = + wellModel_.guideRate().has(wname) || wellModel_.guideRate().hasPotentials(wname); + + if (! (is_nontrivial && wellModel_.wellState().has(wname))) { + all[wname].clear(); + return; + } + + auto parent_pos = retrieve.find(well.groupName()); + const auto parent = (parent_pos == retrieve.end()) + ? RetrieveWellGuideRate{} // No entry for 'parent'--unexpected. + : parent_pos->second; + + const auto get_gr = parent + || RetrieveWellGuideRate{wellModel_.guideRate(), wname}; + + const auto qs = WellGroupHelpers:: + getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname); + + auto getGR = [this, &wname, &qs](const GuideRateModel::Target t) + { + return wellModel_.guideRate().getSI(wname, t, qs); + }; + + auto& grval = all[wname]; + + if (well.isInjector()) { + if (get_gr.inj_gas) { // Well supports WGIGR + grval.set(data::GuideRateValue::Item::Gas, + getGR(GuideRateModel::Target::GAS)); + } + if (get_gr.inj_water) { // Well supports WWIGR + grval.set(data::GuideRateValue::Item::Water, + getGR(GuideRateModel::Target::WAT)); + } + } + else if (get_gr.prod) { // Well is producer AND we want/support WxPGR + grval + .set(data::GuideRateValue::Item::Oil , getGR(GuideRateModel::Target::OIL)) + .set(data::GuideRateValue::Item::Gas , getGR(GuideRateModel::Target::GAS)) + .set(data::GuideRateValue::Item::Water, getGR(GuideRateModel::Target::WAT)); + } + }); + + // Visit groups before their children, meaning no well is visited until + // all of its upline parent groups--up to FIELD--have been visited. + // Upon completion, 'all' contains guide rate values for all wells + // reachable from 'FIELD' at this time/report step. + walker.traversePreOrder(); + + for (const auto* well : wellModel_.genericWells()) { + auto xwPos = wsrpt.find(well->name()); + if (xwPos == wsrpt.end()) { // No well results. Unexpected. + continue; + } + + auto grPos = all.find(well->name()); + if (grPos == all.end()) { + continue; + } + + xwPos->second.guide_rates = grPos->second; + } } + +} // namespace Opm diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 41a3ec2d4..08c3486b2 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -30,7 +30,10 @@ namespace Opm { class BlackoilWellModelGeneric; -namespace data { class GuideRateValue; } +namespace data { +class GuideRateValue; +class Wells; +} class Group; class Well; @@ -58,6 +61,10 @@ public: //! \brief Obtain guide rate values for injection group. data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; + //! \brief Assign guide rates for a well. + void assignWellGuideRates(data::Wells& wsrpt, + const int reportStepIdx) const; + private: const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model }; From 5e157cd23b7d63d38e4050022e07e3202bbc88f3 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 6/8] move calculateAllGroupGuideRates into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 242 +----------------- .../wells/BlackoilWellModelGeneric.hpp | 3 - .../wells/BlackoilWellModelGuideRates.cpp | 70 +++++ .../wells/BlackoilWellModelGuideRates.hpp | 16 +- 4 files changed, 82 insertions(+), 249 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 17870ec23..a0aec4b04 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -58,185 +58,6 @@ #include -namespace { - class GroupTreeWalker - { - public: - using GroupOp = std::function; - using WellOp = std::function; - - explicit GroupTreeWalker(const Opm::Schedule& sched, - const int reportStepIdx) - : sched_ (sched) - , reportStepIdx_(reportStepIdx) - {} - - GroupTreeWalker& groupOp(GroupOp visit) - { - this->visitGroup_ = std::move(visit); - return *this; - } - - GroupTreeWalker& wellOp(WellOp visit) - { - this->visitWell_ = std::move(visit); - return *this; - } - - void clear() - { - this->visitGroup_ = GroupOp{}; - this->visitWell_ = WellOp{}; - } - - void traversePostOrder(); - - private: - using NodeOp = void (GroupTreeWalker::*)(std::string_view) const; - - std::reference_wrapper sched_; - int reportStepIdx_; - - GroupOp visitGroup_{}; - WellOp visitWell_{}; - - std::stack> dfsGroupStack_{}; - std::unordered_set dfsGroupDiscovered_{}; - - NodeOp postDiscover_{nullptr}; - NodeOp preFinish_{nullptr}; - - void traverse(); - - void startWalk(); - void discover(std::string_view group); - void finish(std::string_view group); - - bool isSeen(std::string_view group) const; - std::size_t insertIndex(std::string_view group) const; - - void visitGroup(std::string_view group) const; - void visitWell(std::string_view well) const; - - const Opm::Group& getGroup(std::string_view group) const; - const Opm::Well& getWell(std::string_view well) const; - }; - - void GroupTreeWalker::traversePostOrder() - { - this->preFinish_ = &GroupTreeWalker::visitGroup; - this->postDiscover_ = nullptr; - - this->traverse(); - } - - void GroupTreeWalker::traverse() - { - this->startWalk(); - - while (! this->dfsGroupStack_.empty()) { - const auto gname = this->dfsGroupStack_.top(); - - if (this->isSeen(gname)) { - if (this->preFinish_ != nullptr) { - (this->*preFinish_)(gname); - } - - this->finish(gname); - continue; - } - - this->discover(gname); - - if (this->postDiscover_ != nullptr) { - (this->*postDiscover_)(gname); - } - - const auto& group = this->getGroup(gname); - - if (! group.wellgroup()) { // Node group. Register child groups. - for (const auto& child : group.groups()) { - if (! this->isSeen(child)) { - this->dfsGroupStack_.push(child); - } - } - } - else { // Group is a well group--visit its wells. - for (const auto& well : group.wells()) { - this->visitWell(well); - } - } - } - } - - void GroupTreeWalker::startWalk() - { - this->dfsGroupDiscovered_.clear(); - - while (! this->dfsGroupStack_.empty()) { - this->dfsGroupStack_.pop(); - } - - this->dfsGroupStack_.push("FIELD"); - } - - void GroupTreeWalker::discover(std::string_view group) - { - this->dfsGroupDiscovered_.insert(this->insertIndex(group)); - } - - void GroupTreeWalker::finish(std::string_view group) - { - if (this->dfsGroupStack_.top() != group) { - throw std::invalid_argument { - fmt::format("Internal Error: Expected group '{}', but got '{}'", - group, this->dfsGroupStack_.top()) - }; - } - - this->dfsGroupStack_.pop(); - } - - bool GroupTreeWalker::isSeen(std::string_view group) const - { - return this->dfsGroupDiscovered_.find(this->insertIndex(group)) - != this->dfsGroupDiscovered_.end(); - } - - std::size_t GroupTreeWalker::insertIndex(std::string_view group) const - { - return this->getGroup(group).insert_index(); - } - - void GroupTreeWalker::visitGroup(std::string_view group) const - { - if (! this->visitGroup_) { - return; - } - - this->visitGroup_(this->getGroup(group)); - } - - void GroupTreeWalker::visitWell(std::string_view well) const - { - if (! this->visitWell_) { - return; - } - - this->visitWell_(this->getWell(well)); - } - - const Opm::Group& GroupTreeWalker::getGroup(std::string_view group) const - { - return this->sched_.get().getGroup({group.data(), group.size()}, this->reportStepIdx_); - } - - const Opm::Well& GroupTreeWalker::getWell(std::string_view well) const - { - return this->sched_.get().getWell({well.data(), well.size()}, this->reportStepIdx_); - } -} // Anonymous - namespace Opm { BlackoilWellModelGeneric:: @@ -918,67 +739,6 @@ assignShutConnections(data::Wells& wsrpt, } } -std::unordered_map -BlackoilWellModelGeneric:: -calculateAllGroupGuiderates(const int reportStepIdx) const -{ - auto gr = std::unordered_map{}; - - auto walker = GroupTreeWalker{ this->schedule(), reportStepIdx }; - - // Populates 'gr'. - walker.groupOp([this, &gr](const Group& group) - { - const auto& gname = group.name(); - - if (gname == "FIELD") { return; } - - if (this->guideRate_.has(gname)) { - gr[gname].production = BlackoilWellModelGuideRates(*this).getGuideRateValues(group); - } - - if (this->guideRate_.has(gname, Phase::WATER) || - this->guideRate_.has(gname, Phase::GAS)) - { - gr[gname].injection = - BlackoilWellModelGuideRates(*this).getGuideRateInjectionGroupValues(group); - } - - const auto parent = group.parent(); - if (parent == "FIELD") { return; } - - gr[parent].injection += gr[gname].injection; - gr[parent].production += gr[gname].production; - }); - - // Populates 'gr'. - walker.wellOp([this, &gr](const Well& well) - { - if (! (this->guideRate_.has(well.name()) || - this->guideRate_.hasPotentials(well.name()))) - { - return; - } - - const auto& gname = well.groupName(); - - auto& grval = well.isInjector() - ? gr[gname].injection - : gr[gname].production; - - grval += BlackoilWellModelGuideRates(*this).getGuideRateValues(well); - }); - - // Visit wells and groups before their parents, meaning no group is - // visited until all of its children down to the leaves of the group - // tree have been visited. Upon completion, 'gr' contains guide rate - // values for all groups reachable from 'FIELD' at this time/report - // step. - walker.traversePostOrder(); - - return gr; -} - void BlackoilWellModelGeneric:: assignGroupControl(const Group& group, @@ -1044,7 +804,7 @@ assignGroupValues(const int reportStepIdx, std::map& gvalues) const { const auto groupGuideRates = - this->calculateAllGroupGuiderates(reportStepIdx); + BlackoilWellModelGuideRates(*this).calculateAllGroupGuideRates(reportStepIdx); for (const auto& gname : schedule_.groupNames(reportStepIdx)) { const auto& grup = schedule_.getGroup(gname, reportStepIdx); diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index cde18dd5f..c3d8eae1c 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -282,9 +282,6 @@ protected: std::map& gvalues) const; void assignNodeValues(std::map& nodevalues) const; - std::unordered_map - calculateAllGroupGuiderates(const int reportStepIdx) const; - void calculateEfficiencyFactors(const int reportStepIdx); void checkGconsaleLimits(const Group& group, diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index fd006795b..72c09ec4c 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -123,6 +124,7 @@ public: } void traversePreOrder(); + void traversePostOrder(); private: using NodeOp = void (GroupTreeWalker::*)(std::string_view) const; @@ -163,6 +165,14 @@ void GroupTreeWalker::traversePreOrder() this->traverse(); } +void GroupTreeWalker::traversePostOrder() +{ + this->preFinish_ = &GroupTreeWalker::visitGroup; + this->postDiscover_ = nullptr; + + this->traverse(); +} + void GroupTreeWalker::traverse() { this->startWalk(); @@ -472,4 +482,64 @@ assignWellGuideRates(data::Wells& wsrpt, } } +std::unordered_map +BlackoilWellModelGuideRates:: +calculateAllGroupGuideRates(const int reportStepIdx) const +{ + auto gr = std::unordered_map{}; + + auto walker = GroupTreeWalker{wellModel_.schedule(), reportStepIdx}; + + // Populates 'gr'. + walker.groupOp([this, &gr](const Group& group) + { + const auto& gname = group.name(); + + if (gname == "FIELD") { return; } + + if (wellModel_.guideRate().has(gname)) { + gr[gname].production = this->getGuideRateValues(group); + } + + if (wellModel_.guideRate().has(gname, Phase::WATER) || + wellModel_.guideRate().has(gname, Phase::GAS)) + { + gr[gname].injection = this->getGuideRateInjectionGroupValues(group); + } + + const auto parent = group.parent(); + if (parent == "FIELD") { return; } + + gr[parent].injection += gr[gname].injection; + gr[parent].production += gr[gname].production; + }); + + // Populates 'gr'. + walker.wellOp([this, &gr](const Well& well) + { + if (! (wellModel_.guideRate().has(well.name()) || + wellModel_.guideRate().hasPotentials(well.name()))) + { + return; + } + + const auto& gname = well.groupName(); + + auto& grval = well.isInjector() + ? gr[gname].injection + : gr[gname].production; + + grval += this->getGuideRateValues(well); + }); + + // Visit wells and groups before their parents, meaning no group is + // visited until all of its children down to the leaves of the group + // tree have been visited. Upon completion, 'gr' contains guide rate + // values for all groups reachable from 'FIELD' at this time/report + // step. + walker.traversePostOrder(); + + return gr; +} + } // namespace Opm diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 08c3486b2..9c66aec30 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -26,11 +26,13 @@ #include #include +#include namespace Opm { class BlackoilWellModelGeneric; namespace data { +class GroupGuideRates; class GuideRateValue; class Wells; } @@ -46,6 +48,15 @@ public: : wellModel_(wellModel) {} + //! \brief Assign well guide rates. + void assignWellGuideRates(data::Wells& wsrpt, + const int reportStepIdx) const; + + //! \brief Calculates guide rate for all groups. + std::unordered_map + calculateAllGroupGuideRates(const int reportStepIdx) const; + +private: //! \brief Obtain guide rate values. void getGuideRateValues(const GuideRate::RateVector& qs, const bool is_inj, @@ -61,11 +72,6 @@ public: //! \brief Obtain guide rate values for injection group. data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; - //! \brief Assign guide rates for a well. - void assignWellGuideRates(data::Wells& wsrpt, - const int reportStepIdx) const; - -private: const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model }; From d42cdd409bd83d2f28020c479fbd7b68fa95f228 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 7/8] move assignGroupGuideRates into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 30 +------------------ .../wells/BlackoilWellModelGeneric.hpp | 3 -- .../wells/BlackoilWellModelGuideRates.cpp | 28 +++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 6 ++++ 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index a0aec4b04..d83ff4872 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -770,34 +770,6 @@ assignGroupControl(const Group& group, } } -void -BlackoilWellModelGeneric:: -assignGroupGuideRates(const Group& group, - const std::unordered_map& groupGuideRates, - data::GroupData& gdata) const -{ - auto& prod = gdata.guideRates.production; prod.clear(); - auto& inj = gdata.guideRates.injection; inj .clear(); - - auto xgrPos = groupGuideRates.find(group.name()); - if (xgrPos == groupGuideRates.end()) { - // No guiderates defined for this group. - return; - } - - const auto& xgr = xgrPos->second; - - if (this->guideRate_.has(group.name())) { - prod = xgr.production; - } - - if (this->guideRate_.has(group.name(), Phase::WATER) || - this->guideRate_.has(group.name(), Phase::GAS)) - { - inj = xgr.injection; - } -} - void BlackoilWellModelGeneric:: assignGroupValues(const int reportStepIdx, @@ -811,7 +783,7 @@ assignGroupValues(const int reportStepIdx, auto& gdata = gvalues[gname]; this->assignGroupControl(grup, gdata); - this->assignGroupGuideRates(grup, groupGuideRates, gdata); + BlackoilWellModelGuideRates(*this).assignGroupGuideRates(grup, groupGuideRates, gdata); } } diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index c3d8eae1c..937e1f339 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -275,9 +275,6 @@ protected: const int reportStepIndex) const; void assignGroupControl(const Group& group, data::GroupData& gdata) const; - void assignGroupGuideRates(const Group& group, - const std::unordered_map& groupGuideRates, - data::GroupData& gdata) const; void assignGroupValues(const int reportStepIdx, std::map& gvalues) const; void assignNodeValues(std::map& nodevalues) const; diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index 72c09ec4c..aff76ded3 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -542,4 +542,32 @@ calculateAllGroupGuideRates(const int reportStepIdx) const return gr; } +void BlackoilWellModelGuideRates:: +assignGroupGuideRates(const Group& group, + const std::unordered_map& groupGuideRates, + data::GroupData& gdata) const +{ + auto& prod = gdata.guideRates.production; prod.clear(); + auto& inj = gdata.guideRates.injection; inj .clear(); + + auto xgrPos = groupGuideRates.find(group.name()); + if (xgrPos == groupGuideRates.end()) { + // No guiderates defined for this group. + return; + } + + const auto& xgr = xgrPos->second; + + if (wellModel_.guideRate().has(group.name())) { + prod = xgr.production; + } + + if (wellModel_.guideRate().has(group.name(), Phase::WATER) || + wellModel_.guideRate().has(group.name(), Phase::GAS)) + { + inj = xgr.injection; + } +} + + } // namespace Opm diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 9c66aec30..6287f6009 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -32,6 +32,7 @@ namespace Opm { class BlackoilWellModelGeneric; namespace data { +struct GroupData; class GroupGuideRates; class GuideRateValue; class Wells; @@ -56,6 +57,11 @@ public: std::unordered_map calculateAllGroupGuideRates(const int reportStepIdx) const; + //! \brief Assign group guide rates. + void assignGroupGuideRates(const Group& group, + const std::unordered_map& groupGuideRates, + data::GroupData& gdata) const; + private: //! \brief Obtain guide rate values. void getGuideRateValues(const GuideRate::RateVector& qs, From 9f78e0454d10f91db3bf6e3dcd5159dc9b7d2068 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 09:36:05 +0200 Subject: [PATCH 8/8] move guideRateUpdateIsNeeded into BlackoilWellModelGuideRates --- .../wells/BlackoilWellModelGeneric.cpp | 29 ------------------- .../wells/BlackoilWellModelGeneric.hpp | 2 -- .../wells/BlackoilWellModelGuideRates.cpp | 25 ++++++++++++++++ .../wells/BlackoilWellModelGuideRates.hpp | 3 ++ .../wells/BlackoilWellModel_impl.hpp | 3 +- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index d83ff4872..e45e87e2e 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -1191,33 +1191,4 @@ runWellPIScaling(const int timeStepIdx, this->last_run_wellpi_ = timeStepIdx; } - -bool -BlackoilWellModelGeneric:: -guideRateUpdateIsNeeded(const int reportStepIdx) const { - auto need_update = - std::any_of(this->well_container_generic_.begin(), - this->well_container_generic_.end(), - [](const WellInterfaceGeneric* well) - { - return well->changedToOpenThisStep(); - }); - if (!need_update && this->report_step_starts_) { - const auto& events = this->schedule()[reportStepIdx].wellgroup_events(); - constexpr auto effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE - + ScheduleEvents::INJECTION_TYPE_CHANGED - + ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER - + ScheduleEvents::NEW_WELL; - - need_update = std::any_of(this->well_container_generic_.begin(), - this->well_container_generic_.end(), - [&events](const WellInterfaceGeneric* well) - { - return events.hasEvent(well->name(), effective_events_mask); - }); - } - return this->comm_.max(static_cast(need_update)); -} - - } diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 937e1f339..48fd43362 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -320,8 +320,6 @@ protected: const SummaryConfig& summaryConfig, DeferredLogger& deferred_logger); - bool guideRateUpdateIsNeeded(const int reportStepIdx) const; - // create the well container virtual void createWellContainer(const int time_step) = 0; virtual void initWellContainer(const int reportStepIdx) = 0; diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp index aff76ded3..fc0558274 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.cpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.cpp @@ -569,5 +569,30 @@ assignGroupGuideRates(const Group& group, } } +bool BlackoilWellModelGuideRates:: +guideRateUpdateIsNeeded(const int reportStepIdx) const +{ + const auto& genWells = wellModel_.genericWells(); + auto need_update = + std::any_of(genWells.begin(), genWells.end(), + [](const WellInterfaceGeneric* well) + { + return well->changedToOpenThisStep(); + }); + if (!need_update && wellModel_.reportStepStarts()) { + const auto& events = wellModel_.schedule()[reportStepIdx].wellgroup_events(); + constexpr auto effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE + + ScheduleEvents::INJECTION_TYPE_CHANGED + + ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER + + ScheduleEvents::NEW_WELL; + + need_update = std::any_of(genWells.begin(), genWells.end(), + [&events](const WellInterfaceGeneric* well) + { + return events.hasEvent(well->name(), effective_events_mask); + }); + } + return wellModel_.comm().max(static_cast(need_update)); +} } // namespace Opm diff --git a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp index 6287f6009..d481b14e4 100644 --- a/opm/simulators/wells/BlackoilWellModelGuideRates.hpp +++ b/opm/simulators/wells/BlackoilWellModelGuideRates.hpp @@ -62,6 +62,9 @@ public: const std::unordered_map& groupGuideRates, data::GroupData& gdata) const; + //! \brief Check if a guide rate update is needed. + bool guideRateUpdateIsNeeded(const int reportStepIdx) const; + private: //! \brief Obtain guide rate values. void getGuideRateValues(const GuideRate::RateVector& qs, diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 1a4ed8feb..1e9e249e4 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -918,7 +918,8 @@ namespace Opm { //update guide rates const int reportStepIdx = ebosSimulator_.episodeIndex(); - if (alq_updated || guideRateUpdateIsNeeded(reportStepIdx)) { + if (alq_updated || BlackoilWellModelGuideRates(*this). + guideRateUpdateIsNeeded(reportStepIdx)) { const double simulationTime = ebosSimulator_.time(); const auto& comm = ebosSimulator_.vanguard().grid().comm(); const auto& summaryState = ebosSimulator_.vanguard().summaryState();