From 9367335fe3d0851277e716248a14e3a47b632741 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 19 Oct 2022 09:55:14 +0200 Subject: [PATCH 01/11] added: WellTest this will hold the code for well tests. start by moving checkMaxRatioLimitWell to the new class --- CMakeLists_files.cmake | 2 + .../wells/WellInterfaceFluidSystem.cpp | 34 +++-------- .../wells/WellInterfaceFluidSystem.hpp | 5 -- opm/simulators/wells/WellTest.cpp | 46 +++++++++++++++ opm/simulators/wells/WellTest.hpp | 56 +++++++++++++++++++ 5 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 opm/simulators/wells/WellTest.cpp create mode 100644 opm/simulators/wells/WellTest.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 5f82e1103..b9e4e9341 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -108,6 +108,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/wells/WellInterfaceIndices.cpp opm/simulators/wells/WellProdIndexCalculator.cpp opm/simulators/wells/WellState.cpp + opm/simulators/wells/WellTest.cpp opm/simulators/wells/WGState.cpp ) @@ -381,6 +382,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/WellInterface_impl.hpp opm/simulators/wells/WellProdIndexCalculator.hpp opm/simulators/wells/WellState.hpp + opm/simulators/wells/WellTest.hpp opm/simulators/wells/WGState.hpp ) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index c87825fe0..31b3833cd 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -28,13 +28,14 @@ #include #include -#include +#include #include +#include +#include +#include #include #include -#include -#include -#include +#include #include #include @@ -579,7 +580,8 @@ checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const double max_water_cut_limit = econ_production_limits.maxWaterCut(); assert(max_water_cut_limit > 0.); - const bool watercut_limit_violated = checkMaxRatioLimitWell(ws, max_water_cut_limit, waterCut); + const bool watercut_limit_violated = + WellTest(*this).checkMaxRatioLimitWell(ws, max_water_cut_limit, waterCut); if (watercut_limit_violated) { report.ratio_limit_violated = true; @@ -613,7 +615,7 @@ checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, const double max_gor_limit = econ_production_limits.maxGasOilRatio(); assert(max_gor_limit > 0.); - const bool gor_limit_violated = checkMaxRatioLimitWell(ws, max_gor_limit, gor); + const bool gor_limit_violated = WellTest(*this).checkMaxRatioLimitWell(ws, max_gor_limit, gor); if (gor_limit_violated) { report.ratio_limit_violated = true; @@ -648,7 +650,7 @@ checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, const double max_wgr_limit = econ_production_limits.maxWaterGasRatio(); assert(max_wgr_limit > 0.); - const bool wgr_limit_violated = checkMaxRatioLimitWell(ws, max_wgr_limit, wgr); + const bool wgr_limit_violated = WellTest(*this).checkMaxRatioLimitWell(ws, max_wgr_limit, wgr); if (wgr_limit_violated) { report.ratio_limit_violated = true; @@ -922,24 +924,6 @@ checkMaxRatioLimitCompletions(const SingleWellState& ws, } } -template -template -bool WellInterfaceFluidSystem:: -checkMaxRatioLimitWell(const SingleWellState& ws, - const double max_ratio_limit, - const RatioFunc& ratioFunc) const -{ - const int np = number_of_phases_; - - std::vector well_rates(np, 0.0); - for (int p = 0; p < np; ++p) { - well_rates[p] = ws.surface_rates[p]; - } - - const double well_ratio = ratioFunc(well_rates, phaseUsage()); - return (well_ratio > max_ratio_limit); -} - template int WellInterfaceFluidSystem:: diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 43fae1cb9..544fa0336 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -182,11 +182,6 @@ private: const double max_ratio_limit, const RatioFunc& ratioFunc, RatioLimitCheckReport& report) const; - - template - bool checkMaxRatioLimitWell(const SingleWellState& well_state, - const double max_ratio_limit, - const RatioFunc& ratioFunc) const; }; } diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp new file mode 100644 index 000000000..db450691d --- /dev/null +++ b/opm/simulators/wells/WellTest.cpp @@ -0,0 +1,46 @@ +/* + Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. + Copyright 2017 Statoil ASA. + Copyright 2018 IRIS + + 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 + +namespace Opm +{ + +bool WellTest::checkMaxRatioLimitWell(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc) const +{ + const int np = well_.numPhases(); + + std::vector well_rates(np, 0.0); + for (int p = 0; p < np; ++p) { + well_rates[p] = ws.surface_rates[p]; + } + + const double well_ratio = ratioFunc(well_rates, well_.phaseUsage()); + return (well_ratio > max_ratio_limit); +} + +} // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp new file mode 100644 index 000000000..0769379c0 --- /dev/null +++ b/opm/simulators/wells/WellTest.hpp @@ -0,0 +1,56 @@ +/* + Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. + Copyright 2017 Statoil ASA. + Copyright 2017 IRIS + Copyright 2019 Norce + + 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_WELL_TEST_HEADER_INCLUDED +#define OPM_WELL_TEST_HEADER_INCLUDED + +#include +#include + +namespace Opm +{ + +class PhaseUsage; +class SingleWellState; +class WellInterfaceGeneric; + +//! \brief Class for performing well tests. +class WellTest { +public: + //! \brief Constructor sets reference to well. + WellTest(const WellInterfaceGeneric& well) : well_(well) {} + + using RatioFunc = std::function& rates, + const PhaseUsage& pu)>; + + bool checkMaxRatioLimitWell(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc) const; + +private: + const WellInterfaceGeneric& well_; //!< Reference to well interface +}; + +} + +#endif // OPM_WELL_TEST_HEADER_INCLUDED From d56eb168375018c271ecce770d9b1bbd5a18e198 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 10:57:09 +0200 Subject: [PATCH 02/11] WellInterfaceGeneric: add accessor for completions --- opm/simulators/wells/WellInterfaceGeneric.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index 8fb0d6a4a..3972ad7e8 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -172,6 +172,10 @@ public: return well_index_; } + const std::map>& getCompletions() const { + return completions_; + } + double getTHPConstraint(const SummaryState& summaryState) const; double getALQ(const WellState& well_state) const; double wsolvent() const; From 37f51420f6dadaeeeeb7e8bdaf7d787953021c65 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 03/11] move checkMaxRatioLimitCompletions to WellTest --- opm/simulators/wells/WellInterface.hpp | 1 - .../wells/WellInterfaceFluidSystem.cpp | 54 ++----------------- .../wells/WellInterfaceFluidSystem.hpp | 16 +----- opm/simulators/wells/WellTest.cpp | 44 +++++++++++++++ opm/simulators/wells/WellTest.hpp | 12 +++++ 5 files changed, 62 insertions(+), 65 deletions(-) diff --git a/opm/simulators/wells/WellInterface.hpp b/opm/simulators/wells/WellInterface.hpp index 23aae8b4d..b46c5b198 100644 --- a/opm/simulators/wells/WellInterface.hpp +++ b/opm/simulators/wells/WellInterface.hpp @@ -103,7 +103,6 @@ public: using WellInterfaceFluidSystem::Gas; using WellInterfaceFluidSystem::Oil; using WellInterfaceFluidSystem::Water; - using RatioLimitCheckReport = typename WellInterfaceFluidSystem::RatioLimitCheckReport; static constexpr bool has_solvent = getPropValue(); static constexpr bool has_zFraction = getPropValue(); diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 31b3833cd..4715be678 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -585,7 +585,8 @@ checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, if (watercut_limit_violated) { report.ratio_limit_violated = true; - checkMaxRatioLimitCompletions(ws, max_water_cut_limit, waterCut, report); + WellTest(*this).checkMaxRatioLimitCompletions(ws, max_water_cut_limit, + waterCut, report); } } @@ -619,7 +620,7 @@ checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, if (gor_limit_violated) { report.ratio_limit_violated = true; - checkMaxRatioLimitCompletions(ws, max_gor_limit, gor, report); + WellTest(*this).checkMaxRatioLimitCompletions(ws, max_gor_limit, gor, report); } } @@ -654,7 +655,7 @@ checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, if (wgr_limit_violated) { report.ratio_limit_violated = true; - checkMaxRatioLimitCompletions(ws, max_wgr_limit, wgr, report); + WellTest(*this).checkMaxRatioLimitCompletions(ws, max_wgr_limit, wgr, report); } } @@ -877,53 +878,6 @@ updateWellTestState(const SingleWellState& ws, // TODO: well can be shut/closed due to other reasons } -template -template -void WellInterfaceFluidSystem:: -checkMaxRatioLimitCompletions(const SingleWellState& ws, - const double max_ratio_limit, - const RatioFunc& ratioFunc, - RatioLimitCheckReport& report) const -{ - int worst_offending_completion = INVALIDCOMPLETION; - - // the maximum water cut value of the completions - // it is used to identify the most offending completion - double max_ratio_completion = 0; - const int np = number_of_phases_; - - const auto& perf_data = ws.perf_data; - const auto& perf_phase_rates = perf_data.phase_rates; - // look for the worst_offending_completion - for (const auto& completion : completions_) { - std::vector completion_rates(np, 0.0); - - // looping through the connections associated with the completion - const std::vector& conns = completion.second; - for (const int c : conns) { - for (int p = 0; p < np; ++p) { - const double connection_rate = perf_phase_rates[c * np + p]; - completion_rates[p] += connection_rate; - } - } // end of for (const int c : conns) - - parallel_well_info_.communication().sum(completion_rates.data(), completion_rates.size()); - const double ratio_completion = ratioFunc(completion_rates, phaseUsage()); - - if (ratio_completion > max_ratio_completion) { - worst_offending_completion = completion.first; - max_ratio_completion = ratio_completion; - } - } // end of for (const auto& completion : completions_) - - const double violation_extent = max_ratio_completion / max_ratio_limit; - - if (violation_extent > report.violation_extent) { - report.worst_offending_completion = worst_offending_completion; - report.violation_extent = violation_extent; - } -} - template int WellInterfaceFluidSystem:: diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 544fa0336..f1a16c3fd 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -39,8 +39,9 @@ namespace RateConverter class Group; class GroupState; class Schedule; -class WellState; +struct RatioLimitCheckReport; class SingleWellState; +class WellState; template class WellInterfaceFluidSystem : public WellInterfaceGeneric { @@ -126,12 +127,6 @@ protected: const double* rates_or_potentials, Opm::DeferredLogger& deferred_logger) const; - struct RatioLimitCheckReport{ - bool ratio_limit_violated = false; - int worst_offending_completion = INVALIDCOMPLETION; - double violation_extent = 0.0; - }; - void checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; @@ -175,13 +170,6 @@ protected: // For the conversion between the surface volume rate and reservoir voidage rate const RateConverterType& rateConverter_; - -private: - template - void checkMaxRatioLimitCompletions(const SingleWellState& ws, - const double max_ratio_limit, - const RatioFunc& ratioFunc, - RatioLimitCheckReport& report) const; }; } diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index db450691d..4564453aa 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -43,4 +43,48 @@ bool WellTest::checkMaxRatioLimitWell(const SingleWellState& ws, return (well_ratio > max_ratio_limit); } +void WellTest::checkMaxRatioLimitCompletions(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc, + RatioLimitCheckReport& report) const +{ + int worst_offending_completion = RatioLimitCheckReport::INVALIDCOMPLETION; + + // the maximum water cut value of the completions + // it is used to identify the most offending completion + double max_ratio_completion = 0; + const int np = well_.numPhases(); + + const auto& perf_data = ws.perf_data; + const auto& perf_phase_rates = perf_data.phase_rates; + // look for the worst_offending_completion + for (const auto& completion : well_.getCompletions()) { + std::vector completion_rates(np, 0.0); + + // looping through the connections associated with the completion + const std::vector& conns = completion.second; + for (const int c : conns) { + for (int p = 0; p < np; ++p) { + const double connection_rate = perf_phase_rates[c * np + p]; + completion_rates[p] += connection_rate; + } + } // end of for (const int c : conns) + + well_.parallelWellInfo().communication().sum(completion_rates.data(), completion_rates.size()); + const double ratio_completion = ratioFunc(completion_rates, well_.phaseUsage()); + + if (ratio_completion > max_ratio_completion) { + worst_offending_completion = completion.first; + max_ratio_completion = ratio_completion; + } + } // end of for (const auto& completion : completions_) + + const double violation_extent = max_ratio_completion / max_ratio_limit; + + if (violation_extent > report.violation_extent) { + report.worst_offending_completion = worst_offending_completion; + report.violation_extent = violation_extent; + } +} + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 0769379c0..f54ddd4c7 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -25,6 +25,7 @@ #define OPM_WELL_TEST_HEADER_INCLUDED #include +#include #include namespace Opm @@ -34,6 +35,13 @@ class PhaseUsage; class SingleWellState; class WellInterfaceGeneric; +struct RatioLimitCheckReport { + static constexpr int INVALIDCOMPLETION = std::numeric_limits::max(); + bool ratio_limit_violated = false; + int worst_offending_completion = INVALIDCOMPLETION; + double violation_extent = 0.0; +}; + //! \brief Class for performing well tests. class WellTest { public: @@ -47,6 +55,10 @@ public: const double max_ratio_limit, const RatioFunc& ratioFunc) const; + void checkMaxRatioLimitCompletions(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc, + RatioLimitCheckReport& report) const; private: const WellInterfaceGeneric& well_; //!< Reference to well interface }; From fe8259bb76a2a8c9c32381012ef711c672729920 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 04/11] move checkMaxGORLimit to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 38 ++----------------- .../wells/WellInterfaceFluidSystem.hpp | 4 -- opm/simulators/wells/WellTest.cpp | 33 ++++++++++++++++ opm/simulators/wells/WellTest.hpp | 5 +++ 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 4715be678..d46f12954 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -590,40 +590,6 @@ checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, } } -template -void -WellInterfaceFluidSystem:: -checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const -{ - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); - - // function to calculate gor based on rates - auto gor = [](const std::vector& rates, - const PhaseUsage& pu) { - const double oil_rate = -rates[pu.phase_pos[Oil]]; - const double gas_rate = -rates[pu.phase_pos[Gas]]; - if (gas_rate <= 0.) - return 0.; - else if (oil_rate <= 0.) - return 1.e100; // big value to mark it as violated - else - return (gas_rate / oil_rate); - }; - - const double max_gor_limit = econ_production_limits.maxGasOilRatio(); - assert(max_gor_limit > 0.); - - const bool gor_limit_violated = WellTest(*this).checkMaxRatioLimitWell(ws, max_gor_limit, gor); - - if (gor_limit_violated) { - report.ratio_limit_violated = true; - WellTest(*this).checkMaxRatioLimitCompletions(ws, max_gor_limit, gor, report); - } -} - template void WellInterfaceFluidSystem:: @@ -680,7 +646,9 @@ checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, } if (econ_production_limits.onMaxGasOilRatio()) { - checkMaxGORLimit(econ_production_limits, ws, report); + assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); + assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); + WellTest(*this).checkMaxGORLimit(econ_production_limits, ws, report); } if (econ_production_limits.onMaxWaterGasRatio()) { diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index f1a16c3fd..d5087fbea 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -131,10 +131,6 @@ protected: const SingleWellState& ws, RatioLimitCheckReport& report) const; - void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const; - void checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index 4564453aa..a3fa18228 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -87,4 +88,36 @@ void WellTest::checkMaxRatioLimitCompletions(const SingleWellState& ws, } } +void WellTest::checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const +{ + static constexpr int Oil = BlackoilPhases::Liquid; + static constexpr int Gas = BlackoilPhases::Vapour; + + // function to calculate gor based on rates + auto gor = [](const std::vector& rates, + const PhaseUsage& pu) { + const double oil_rate = -rates[pu.phase_pos[Oil]]; + const double gas_rate = -rates[pu.phase_pos[Gas]]; + if (gas_rate <= 0.) + return 0.; + else if (oil_rate <= 0.) + return 1.e100; // big value to mark it as violated + else + return (gas_rate / oil_rate); + }; + + const double max_gor_limit = econ_production_limits.maxGasOilRatio(); + assert(max_gor_limit > 0.); + + const bool gor_limit_violated = this->checkMaxRatioLimitWell(ws, max_gor_limit, gor); + + if (gor_limit_violated) { + report.ratio_limit_violated = true; + this->checkMaxRatioLimitCompletions(ws, max_gor_limit, gor, report); + } +} + + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index f54ddd4c7..59033a91c 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -33,6 +33,7 @@ namespace Opm class PhaseUsage; class SingleWellState; +class WellEconProductionLimits; class WellInterfaceGeneric; struct RatioLimitCheckReport { @@ -59,6 +60,10 @@ public: const double max_ratio_limit, const RatioFunc& ratioFunc, RatioLimitCheckReport& report) const; + + void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const; private: const WellInterfaceGeneric& well_; //!< Reference to well interface }; From e7273868f5b250910bbe34b07cc876cf02fae6a0 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 05/11] move checkMaxWGRLimit to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 39 ++----------------- .../wells/WellInterfaceFluidSystem.hpp | 4 -- opm/simulators/wells/WellTest.cpp | 31 +++++++++++++++ opm/simulators/wells/WellTest.hpp | 5 +++ 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index d46f12954..7640f2a15 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -590,41 +590,6 @@ checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, } } -template -void -WellInterfaceFluidSystem:: -checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const -{ - assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); - - // function to calculate wgr based on rates - auto wgr = [](const std::vector& rates, - const PhaseUsage& pu) { - - const double water_rate = -rates[pu.phase_pos[Water]]; - const double gas_rate = -rates[pu.phase_pos[Gas]]; - if (water_rate <= 0.) - return 0.; - else if (gas_rate <= 0.) - return 1.e100; // big value to mark it as violated - else - return (water_rate / gas_rate); - }; - - const double max_wgr_limit = econ_production_limits.maxWaterGasRatio(); - assert(max_wgr_limit > 0.); - - const bool wgr_limit_violated = WellTest(*this).checkMaxRatioLimitWell(ws, max_wgr_limit, wgr); - - if (wgr_limit_violated) { - report.ratio_limit_violated = true; - WellTest(*this).checkMaxRatioLimitCompletions(ws, max_wgr_limit, wgr, report); - } -} - template void WellInterfaceFluidSystem:: @@ -652,7 +617,9 @@ checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, } if (econ_production_limits.onMaxWaterGasRatio()) { - checkMaxWGRLimit(econ_production_limits, ws, report); + assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); + assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); + WellTest(*this).checkMaxWGRLimit(econ_production_limits, ws, report); } if (econ_production_limits.onMaxGasLiquidRatio()) { diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index d5087fbea..9f5b478df 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -131,10 +131,6 @@ protected: const SingleWellState& ws, RatioLimitCheckReport& report) const; - void checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const; - void checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index a3fa18228..fbd475998 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -119,5 +119,36 @@ void WellTest::checkMaxGORLimit(const WellEconProductionLimits& econ_production_ } } +void WellTest::checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const +{ + static constexpr int Gas = BlackoilPhases::Vapour; + static constexpr int Water = BlackoilPhases::Aqua; + + // function to calculate wgr based on rates + auto wgr = [](const std::vector& rates, + const PhaseUsage& pu) { + + const double water_rate = -rates[pu.phase_pos[Water]]; + const double gas_rate = -rates[pu.phase_pos[Gas]]; + if (water_rate <= 0.) + return 0.; + else if (gas_rate <= 0.) + return 1.e100; // big value to mark it as violated + else + return (water_rate / gas_rate); + }; + + const double max_wgr_limit = econ_production_limits.maxWaterGasRatio(); + assert(max_wgr_limit > 0.); + + const bool wgr_limit_violated = this->checkMaxRatioLimitWell(ws, max_wgr_limit, wgr); + + if (wgr_limit_violated) { + report.ratio_limit_violated = true; + this->checkMaxRatioLimitCompletions(ws, max_wgr_limit, wgr, report); + } +} } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 59033a91c..3d90cf46d 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -64,6 +64,11 @@ public: void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; + + void checkMaxWGRLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const; + private: const WellInterfaceGeneric& well_; //!< Reference to well interface }; From 2b152e67e146e9cc09103644c38c006863a96982 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 06/11] move checkMaxWaterCutLimit to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 44 ++----------------- .../wells/WellInterfaceFluidSystem.hpp | 4 -- opm/simulators/wells/WellTest.cpp | 39 ++++++++++++++++ opm/simulators/wells/WellTest.hpp | 28 ++++++------ 4 files changed, 57 insertions(+), 58 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 7640f2a15..fcde3c272 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -550,46 +550,6 @@ checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, return false; } -template -void -WellInterfaceFluidSystem:: -checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const -{ - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); - - // function to calculate water cut based on rates - auto waterCut = [](const std::vector& rates, - const PhaseUsage& pu) { - const double oil_rate = -rates[pu.phase_pos[Oil]]; - const double water_rate = -rates[pu.phase_pos[Water]]; - const double liquid_rate = oil_rate + water_rate; - if (liquid_rate <= 0.) - return 0.; - else if (water_rate < 0) - return 0.; - else if (oil_rate < 0) - return 1.; - else - return (water_rate / liquid_rate); - - }; - - const double max_water_cut_limit = econ_production_limits.maxWaterCut(); - assert(max_water_cut_limit > 0.); - - const bool watercut_limit_violated = - WellTest(*this).checkMaxRatioLimitWell(ws, max_water_cut_limit, waterCut); - - if (watercut_limit_violated) { - report.ratio_limit_violated = true; - WellTest(*this).checkMaxRatioLimitCompletions(ws, max_water_cut_limit, - waterCut, report); - } -} - template void WellInterfaceFluidSystem:: @@ -607,7 +567,9 @@ checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, // extent. if (econ_production_limits.onMaxWaterCut()) { - checkMaxWaterCutLimit(econ_production_limits, ws, report); + assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); + assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); + WellTest(*this).checkMaxWaterCutLimit(econ_production_limits, ws, report); } if (econ_production_limits.onMaxGasOilRatio()) { diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 9f5b478df..7160e95e4 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -127,10 +127,6 @@ protected: const double* rates_or_potentials, Opm::DeferredLogger& deferred_logger) const; - void checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report) const; - void checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index fbd475998..8c59eed7d 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -29,6 +29,7 @@ namespace Opm { +template bool WellTest::checkMaxRatioLimitWell(const SingleWellState& ws, const double max_ratio_limit, const RatioFunc& ratioFunc) const @@ -44,6 +45,7 @@ bool WellTest::checkMaxRatioLimitWell(const SingleWellState& ws, return (well_ratio > max_ratio_limit); } +template void WellTest::checkMaxRatioLimitCompletions(const SingleWellState& ws, const double max_ratio_limit, const RatioFunc& ratioFunc, @@ -151,4 +153,41 @@ void WellTest::checkMaxWGRLimit(const WellEconProductionLimits& econ_production_ } } +void WellTest::checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const +{ + static constexpr int Oil = BlackoilPhases::Liquid; + static constexpr int Water = BlackoilPhases::Aqua; + + // function to calculate water cut based on rates + auto waterCut = [](const std::vector& rates, + const PhaseUsage& pu) { + const double oil_rate = -rates[pu.phase_pos[Oil]]; + const double water_rate = -rates[pu.phase_pos[Water]]; + const double liquid_rate = oil_rate + water_rate; + if (liquid_rate <= 0.) + return 0.; + else if (water_rate < 0) + return 0.; + else if (oil_rate < 0) + return 1.; + else + return (water_rate / liquid_rate); + + }; + + const double max_water_cut_limit = econ_production_limits.maxWaterCut(); + assert(max_water_cut_limit > 0.); + + const bool watercut_limit_violated = + this->checkMaxRatioLimitWell(ws, max_water_cut_limit, waterCut); + + if (watercut_limit_violated) { + report.ratio_limit_violated = true; + this->checkMaxRatioLimitCompletions(ws, max_water_cut_limit, + waterCut, report); + } +} + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 3d90cf46d..278dc8102 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -24,7 +24,6 @@ #ifndef OPM_WELL_TEST_HEADER_INCLUDED #define OPM_WELL_TEST_HEADER_INCLUDED -#include #include #include @@ -49,18 +48,6 @@ public: //! \brief Constructor sets reference to well. WellTest(const WellInterfaceGeneric& well) : well_(well) {} - using RatioFunc = std::function& rates, - const PhaseUsage& pu)>; - - bool checkMaxRatioLimitWell(const SingleWellState& ws, - const double max_ratio_limit, - const RatioFunc& ratioFunc) const; - - void checkMaxRatioLimitCompletions(const SingleWellState& ws, - const double max_ratio_limit, - const RatioFunc& ratioFunc, - RatioLimitCheckReport& report) const; - void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; @@ -69,7 +56,22 @@ public: const SingleWellState& ws, RatioLimitCheckReport& report) const; + void checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + RatioLimitCheckReport& report) const; + private: + template + bool checkMaxRatioLimitWell(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc) const; + + template + void checkMaxRatioLimitCompletions(const SingleWellState& ws, + const double max_ratio_limit, + const RatioFunc& ratioFunc, + RatioLimitCheckReport& report) const; + const WellInterfaceGeneric& well_; //!< Reference to well interface }; From 1a0774ceabaeb3897a986352f96e2f7bd2ce5be6 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 07/11] move checkRateEconLimits to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 58 +++---------------- .../wells/WellInterfaceFluidSystem.hpp | 4 -- opm/simulators/wells/WellTest.cpp | 44 ++++++++++++++ opm/simulators/wells/WellTest.hpp | 5 ++ 4 files changed, 58 insertions(+), 53 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index fcde3c272..716dd904f 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -504,52 +504,6 @@ checkConstraints(WellState& well_state, } } -template -bool -WellInterfaceFluidSystem:: -checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, - const double* rates_or_potentials, - DeferredLogger& deferred_logger) const -{ - const PhaseUsage& pu = phaseUsage(); - - if (econ_production_limits.onMinOilRate()) { - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - const double oil_rate = rates_or_potentials[pu.phase_pos[ Oil ] ]; - const double min_oil_rate = econ_production_limits.minOilRate(); - if (std::abs(oil_rate) < min_oil_rate) { - return true; - } - } - - if (econ_production_limits.onMinGasRate() ) { - assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); - const double gas_rate = rates_or_potentials[pu.phase_pos[ Gas ] ]; - const double min_gas_rate = econ_production_limits.minGasRate(); - if (std::abs(gas_rate) < min_gas_rate) { - return true; - } - } - - if (econ_production_limits.onMinLiquidRate() ) { - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); - const double oil_rate = rates_or_potentials[pu.phase_pos[ Oil ] ]; - const double water_rate = rates_or_potentials[pu.phase_pos[ Water ] ]; - const double liquid_rate = oil_rate + water_rate; - const double min_liquid_rate = econ_production_limits.minLiquidRate(); - if (std::abs(liquid_rate) < min_liquid_rate) { - return true; - } - } - - if (econ_production_limits.onMinReservoirFluidRate()) { - deferred_logger.warning("NOT_SUPPORTING_MIN_RESERVOIR_FLUID_RATE", "Minimum reservoir fluid production rate limit is not supported yet"); - } - - return false; -} - template void WellInterfaceFluidSystem:: @@ -636,16 +590,22 @@ updateWellTestStateEconomic(const SingleWellState& ws, const auto& quantity_limit = econ_production_limits.quantityLimit(); if (econ_production_limits.onAnyRateLimit()) { if (quantity_limit == WellEconProductionLimits::QuantityLimit::POTN) { - rate_limit_violated = checkRateEconLimits(econ_production_limits, ws.well_potentials.data(), deferred_logger); + rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, + ws.well_potentials, + deferred_logger); // Due to instability of the bhpFromThpLimit code the potentials are sometimes wrong // this can lead to premature shutting of wells due to rate limits of the potentials. // Since rates are supposed to be less or equal to the potentials, we double-check // that also the rate limit is violated before shutting the well. if (rate_limit_violated) - rate_limit_violated = checkRateEconLimits(econ_production_limits, ws.surface_rates.data(), deferred_logger); + rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, + ws.surface_rates, + deferred_logger); } else { - rate_limit_violated = checkRateEconLimits(econ_production_limits, ws.surface_rates.data(), deferred_logger); + rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, + ws.surface_rates, + deferred_logger); } } diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 7160e95e4..d4c54b70e 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -123,10 +123,6 @@ protected: const SummaryState& summaryState, DeferredLogger& deferred_logger) const; - bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, - const double* rates_or_potentials, - Opm::DeferredLogger& deferred_logger) const; - void checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index 8c59eed7d..ae8608d89 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -190,4 +191,47 @@ void WellTest::checkMaxWaterCutLimit(const WellEconProductionLimits& econ_produc } } +bool WellTest::checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const std::vector& rates_or_potentials, + DeferredLogger& deferred_logger) const +{ + static constexpr int Gas = BlackoilPhases::Vapour; + static constexpr int Oil = BlackoilPhases::Liquid; + static constexpr int Water = BlackoilPhases::Aqua; + + const PhaseUsage& pu = well_.phaseUsage(); + + if (econ_production_limits.onMinOilRate()) { + const double oil_rate = rates_or_potentials[pu.phase_pos[Oil]]; + const double min_oil_rate = econ_production_limits.minOilRate(); + if (std::abs(oil_rate) < min_oil_rate) { + return true; + } + } + + if (econ_production_limits.onMinGasRate() ) { + const double gas_rate = rates_or_potentials[pu.phase_pos[Gas]]; + const double min_gas_rate = econ_production_limits.minGasRate(); + if (std::abs(gas_rate) < min_gas_rate) { + return true; + } + } + + if (econ_production_limits.onMinLiquidRate() ) { + const double oil_rate = rates_or_potentials[pu.phase_pos[Oil]]; + const double water_rate = rates_or_potentials[pu.phase_pos[Water]]; + const double liquid_rate = oil_rate + water_rate; + const double min_liquid_rate = econ_production_limits.minLiquidRate(); + if (std::abs(liquid_rate) < min_liquid_rate) { + return true; + } + } + + if (econ_production_limits.onMinReservoirFluidRate()) { + deferred_logger.warning("NOT_SUPPORTING_MIN_RESERVOIR_FLUID_RATE", "Minimum reservoir fluid production rate limit is not supported yet"); + } + + return false; +} + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 278dc8102..1a31c7d20 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -30,6 +30,7 @@ namespace Opm { +class DeferredLogger; class PhaseUsage; class SingleWellState; class WellEconProductionLimits; @@ -60,6 +61,10 @@ public: const SingleWellState& ws, RatioLimitCheckReport& report) const; + bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const std::vector& rates_or_potentials, + DeferredLogger& deferred_logger) const; + private: template bool checkMaxRatioLimitWell(const SingleWellState& ws, From 71d404336e4fabed16268c96c495b96aad664873 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 08/11] move checkRatioEconLimits to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 61 +------------------ .../wells/WellInterfaceFluidSystem.hpp | 5 -- opm/simulators/wells/WellTest.cpp | 51 ++++++++++++++++ opm/simulators/wells/WellTest.hpp | 15 +++-- 4 files changed, 63 insertions(+), 69 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 716dd904f..42c68250c 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -504,62 +504,6 @@ checkConstraints(WellState& well_state, } } -template -void -WellInterfaceFluidSystem:: -checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report, - DeferredLogger& deferred_logger) const -{ - // TODO: not sure how to define the worst-offending completion when more than one - // ratio related limit is violated. - // The defintion used here is that we define the violation extent based on the - // ratio between the value and the corresponding limit. - // For each violated limit, we decide the worst-offending completion separately. - // Among the worst-offending completions, we use the one has the biggest violation - // extent. - - if (econ_production_limits.onMaxWaterCut()) { - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); - WellTest(*this).checkMaxWaterCutLimit(econ_production_limits, ws, report); - } - - if (econ_production_limits.onMaxGasOilRatio()) { - assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); - WellTest(*this).checkMaxGORLimit(econ_production_limits, ws, report); - } - - if (econ_production_limits.onMaxWaterGasRatio()) { - assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); - assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)); - WellTest(*this).checkMaxWGRLimit(econ_production_limits, ws, report); - } - - if (econ_production_limits.onMaxGasLiquidRatio()) { - deferred_logger.warning("NOT_SUPPORTING_MAX_GLR", "the support for max Gas-Liquid ratio is not implemented yet!"); - } - - if (report.ratio_limit_violated) { - // No worst offending completion is found because all the completions are either injecting or - // have trivial rates. - if(report.worst_offending_completion == INVALIDCOMPLETION) { - std::string message = "The well ratio limit is violated but all the completion rates are trivial! " + this->name() + " is kept open"; - deferred_logger.warning("WECON_INVALIDCOMPLETION", message); - report.ratio_limit_violated = false; - } - // Due to numerical instability there may exist corner cases where the well breaks - // the ratio limit but no completion does. - else if(report.violation_extent <= 1.) { - std::string message = "The well ratio limit is violated but no completion ratio limit is violated! " + this->name() + " is kept open"; - deferred_logger.warning("WECON_INCONSISTANT_COMPLETION_WELL", message); - report.ratio_limit_violated = false; - } - } -} - template void WellInterfaceFluidSystem:: @@ -643,9 +587,8 @@ updateWellTestStateEconomic(const SingleWellState& ws, } // checking for ratio related limits, mostly all kinds of ratio. - RatioLimitCheckReport ratio_report; - - checkRatioEconLimits(econ_production_limits, ws, ratio_report, deferred_logger); + RatioLimitCheckReport ratio_report = + WellTest(*this).checkRatioEconLimits(econ_production_limits, ws, deferred_logger); if (ratio_report.ratio_limit_violated) { const auto workover = econ_production_limits.workover(); diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index d4c54b70e..37c2a3fbb 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -123,11 +123,6 @@ protected: const SummaryState& summaryState, DeferredLogger& deferred_logger) const; - void checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - RatioLimitCheckReport& report, - DeferredLogger& deferred_logger) const; - void updateWellTestStateEconomic(const SingleWellState& ws, const double simulation_time, const bool write_message_to_opmlog, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index ae8608d89..8f8221cea 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -234,4 +234,55 @@ bool WellTest::checkRateEconLimits(const WellEconProductionLimits& econ_producti return false; } +RatioLimitCheckReport WellTest:: +checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + DeferredLogger& deferred_logger) const +{ + // TODO: not sure how to define the worst-offending completion when more than one + // ratio related limit is violated. + // The defintion used here is that we define the violation extent based on the + // ratio between the value and the corresponding limit. + // For each violated limit, we decide the worst-offending completion separately. + // Among the worst-offending completions, we use the one has the biggest violation + // extent. + RatioLimitCheckReport report; + + if (econ_production_limits.onMaxWaterCut()) { + this->checkMaxWaterCutLimit(econ_production_limits, ws, report); + } + + if (econ_production_limits.onMaxGasOilRatio()) { + this->checkMaxGORLimit(econ_production_limits, ws, report); + } + + if (econ_production_limits.onMaxWaterGasRatio()) { + this->checkMaxWGRLimit(econ_production_limits, ws, report); + } + + if (econ_production_limits.onMaxGasLiquidRatio()) { + deferred_logger.warning("NOT_SUPPORTING_MAX_GLR", "the support for max Gas-Liquid ratio is not implemented yet!"); + } + + if (report.ratio_limit_violated) { + // No worst offending completion is found because all the completions are either injecting or + // have trivial rates. + if(report.worst_offending_completion == RatioLimitCheckReport::INVALIDCOMPLETION) { + std::string message = "The well ratio limit is violated but all the completion rates are trivial! " + well_.name() + " is kept open"; + deferred_logger.warning("WECON_INVALIDCOMPLETION", message); + report.ratio_limit_violated = false; + } + // Due to numerical instability there may exist corner cases where the well breaks + // the ratio limit but no completion does. + else if(report.violation_extent <= 1.) { + std::string message = "The well ratio limit is violated but no completion ratio limit is violated! " + well_.name() + " is kept open"; + deferred_logger.warning("WECON_INCONSISTANT_COMPLETION_WELL", message); + report.ratio_limit_violated = false; + } + } + + return report; +} + + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 1a31c7d20..6904bbc54 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -49,6 +49,16 @@ public: //! \brief Constructor sets reference to well. WellTest(const WellInterfaceGeneric& well) : well_(well) {} + bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const std::vector& rates_or_potentials, + DeferredLogger& deferred_logger) const; + + RatioLimitCheckReport + checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + DeferredLogger& deferred_logger) const; + +private: void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; @@ -61,11 +71,6 @@ public: const SingleWellState& ws, RatioLimitCheckReport& report) const; - bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, - const std::vector& rates_or_potentials, - DeferredLogger& deferred_logger) const; - -private: template bool checkMaxRatioLimitWell(const SingleWellState& ws, const double max_ratio_limit, From e2b5fc8082965314dd7697f369a664cdae90636d Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 09/11] move updateWellTestStateEconomic to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 157 +----------------- .../wells/WellInterfaceFluidSystem.hpp | 6 - opm/simulators/wells/WellTest.cpp | 154 ++++++++++++++++- opm/simulators/wells/WellTest.hpp | 38 +++-- 4 files changed, 177 insertions(+), 178 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 42c68250c..0821db8db 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -504,161 +504,6 @@ checkConstraints(WellState& well_state, } } -template -void -WellInterfaceFluidSystem:: -updateWellTestStateEconomic(const SingleWellState& ws, - const double simulation_time, - const bool write_message_to_opmlog, - WellTestState& well_test_state, - DeferredLogger& deferred_logger) const -{ - if (this->wellIsStopped()) - return; - - const WellEconProductionLimits& econ_production_limits = well_ecl_.getEconLimits(); - - // if no limit is effective here, then continue to the next well - if ( !econ_production_limits.onAnyEffectiveLimit() ) { - return; - } - - if (this->isInjector()) { - deferred_logger.warning("ECON_LIMITS_INJECTOR_" + this->name(), this->name() + " is an injector, the production economic limits for this well will be ignored.\n"); - return; - } - - // flag to check if the mim oil/gas rate limit is violated - bool rate_limit_violated = false; - - const auto& quantity_limit = econ_production_limits.quantityLimit(); - if (econ_production_limits.onAnyRateLimit()) { - if (quantity_limit == WellEconProductionLimits::QuantityLimit::POTN) { - rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, - ws.well_potentials, - deferred_logger); - // Due to instability of the bhpFromThpLimit code the potentials are sometimes wrong - // this can lead to premature shutting of wells due to rate limits of the potentials. - // Since rates are supposed to be less or equal to the potentials, we double-check - // that also the rate limit is violated before shutting the well. - if (rate_limit_violated) - rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, - ws.surface_rates, - deferred_logger); - } - else { - rate_limit_violated = WellTest(*this).checkRateEconLimits(econ_production_limits, - ws.surface_rates, - deferred_logger); - } - } - - if (rate_limit_violated) { - if (econ_production_limits.endRun()) { - const std::string warning_message = std::string("ending run after well closed due to economic limits") - + std::string("is not supported yet \n") - + std::string("the program will keep running after ") + name() - + std::string(" is closed"); - deferred_logger.warning("NOT_SUPPORTING_ENDRUN", warning_message); - } - - if (econ_production_limits.validFollowonWell()) { - deferred_logger.warning("NOT_SUPPORTING_FOLLOWONWELL", "opening following on well after well closed is not supported yet"); - } - - well_test_state.close_well(name(), WellTestConfig::Reason::ECONOMIC, simulation_time); - if (write_message_to_opmlog) { - if (this->well_ecl_.getAutomaticShutIn()) { - const std::string msg = std::string("well ") + name() + std::string(" will be shut due to rate economic limit"); - deferred_logger.info(msg); - } else { - const std::string msg = std::string("well ") + name() + std::string(" will be stopped due to rate economic limit"); - deferred_logger.info(msg); - } - } - // the well is closed, not need to check other limits - return; - } - - - if ( !econ_production_limits.onAnyRatioLimit() ) { - // there is no need to check the ratio limits - return; - } - - // checking for ratio related limits, mostly all kinds of ratio. - RatioLimitCheckReport ratio_report = - WellTest(*this).checkRatioEconLimits(econ_production_limits, ws, deferred_logger); - - if (ratio_report.ratio_limit_violated) { - const auto workover = econ_production_limits.workover(); - switch (workover) { - case WellEconProductionLimits::EconWorkover::CON: - { - const int worst_offending_completion = ratio_report.worst_offending_completion; - - well_test_state.close_completion(name(), worst_offending_completion, simulation_time); - if (write_message_to_opmlog) { - if (worst_offending_completion < 0) { - const std::string msg = std::string("Connection ") + std::to_string(- worst_offending_completion) - + std::string(" for well ") + name() + std::string(" will be closed due to economic limit"); - deferred_logger.info(msg); - } else { - const std::string msg = std::string("Completion ") + std::to_string(worst_offending_completion) - + std::string(" for well ") + name() + std::string(" will be closed due to economic limit"); - deferred_logger.info(msg); - } - } - - bool allCompletionsClosed = true; - const auto& connections = well_ecl_.getConnections(); - for (const auto& connection : connections) { - if (connection.state() == Connection::State::OPEN - && !well_test_state.completion_is_closed(name(), connection.complnum())) { - allCompletionsClosed = false; - } - } - - if (allCompletionsClosed) { - well_test_state.close_well(name(), WellTestConfig::Reason::ECONOMIC, simulation_time); - if (write_message_to_opmlog) { - if (this->well_ecl_.getAutomaticShutIn()) { - const std::string msg = name() + std::string(" will be shut due to last completion closed"); - deferred_logger.info(msg); - } else { - const std::string msg = name() + std::string(" will be stopped due to last completion closed"); - deferred_logger.info(msg); - } - } - } - break; - } - case WellEconProductionLimits::EconWorkover::WELL: - { - well_test_state.close_well(name(), WellTestConfig::Reason::ECONOMIC, simulation_time); - if (write_message_to_opmlog) { - if (well_ecl_.getAutomaticShutIn()) { - // tell the control that the well is closed - const std::string msg = name() + std::string(" will be shut due to ratio economic limit"); - deferred_logger.info(msg); - } else { - const std::string msg = name() + std::string(" will be stopped due to ratio economic limit"); - deferred_logger.info(msg); - } - } - break; - } - case WellEconProductionLimits::EconWorkover::NONE: - break; - default: - { - deferred_logger.warning("NOT_SUPPORTED_WORKOVER_TYPE", - "not supporting workover type " + WellEconProductionLimits::EconWorkover2String(workover) ); - } - } - } -} - template void WellInterfaceFluidSystem:: @@ -673,7 +518,7 @@ updateWellTestState(const SingleWellState& ws, // updating well test state based on Economic limits for operable wells if (this->isOperableAndSolvable()) - updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); + WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); // TODO: well can be shut/closed due to other reasons } diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 37c2a3fbb..8a8b8a3bc 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -123,12 +123,6 @@ protected: const SummaryState& summaryState, DeferredLogger& deferred_logger) const; - void updateWellTestStateEconomic(const SingleWellState& ws, - const double simulation_time, - const bool write_message_to_opmlog, - WellTestState& well_test_state, - DeferredLogger& deferred_logger) const; - std::optional getGroupInjectionTargetRate(const Group& group, const WellState& well_state, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index 8f8221cea..64fe4c006 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -234,7 +236,7 @@ bool WellTest::checkRateEconLimits(const WellEconProductionLimits& econ_producti return false; } -RatioLimitCheckReport WellTest:: +WellTest::RatioLimitCheckReport WellTest:: checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, DeferredLogger& deferred_logger) const @@ -284,5 +286,155 @@ checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, return report; } +void WellTest::updateWellTestStateEconomic(const SingleWellState& ws, + const double simulation_time, + const bool write_message_to_opmlog, + WellTestState& well_test_state, + DeferredLogger& deferred_logger) const +{ + if (well_.wellIsStopped()) + return; + + const WellEconProductionLimits& econ_production_limits = well_.wellEcl().getEconLimits(); + + // if no limit is effective here, then continue to the next well + if (!econ_production_limits.onAnyEffectiveLimit()) { + return; + } + + if (well_.isInjector()) { + deferred_logger.warning("ECON_LIMITS_INJECTOR_" + well_.name(), well_.name() + " is an injector, the production economic limits for this well will be ignored.\n"); + return; + } + + // flag to check if the mim oil/gas rate limit is violated + bool rate_limit_violated = false; + + const auto& quantity_limit = econ_production_limits.quantityLimit(); + if (econ_production_limits.onAnyRateLimit()) { + if (quantity_limit == WellEconProductionLimits::QuantityLimit::POTN) { + rate_limit_violated = this->checkRateEconLimits(econ_production_limits, + ws.well_potentials, + deferred_logger); + // Due to instability of the bhpFromThpLimit code the potentials are sometimes wrong + // this can lead to premature shutting of wells due to rate limits of the potentials. + // Since rates are supposed to be less or equal to the potentials, we double-check + // that also the rate limit is violated before shutting the well. + if (rate_limit_violated) + rate_limit_violated = this->checkRateEconLimits(econ_production_limits, + ws.surface_rates, + deferred_logger); + } + else { + rate_limit_violated = this->checkRateEconLimits(econ_production_limits, + ws.surface_rates, + deferred_logger); + } + } + + if (rate_limit_violated) { + if (econ_production_limits.endRun()) { + const std::string warning_message = std::string("ending run after well closed due to economic limits") + + std::string("is not supported yet \n") + + std::string("the program will keep running after ") + well_.name() + + std::string(" is closed"); + deferred_logger.warning("NOT_SUPPORTING_ENDRUN", warning_message); + } + + if (econ_production_limits.validFollowonWell()) { + deferred_logger.warning("NOT_SUPPORTING_FOLLOWONWELL", "opening following on well after well closed is not supported yet"); + } + + well_test_state.close_well(well_.name(), WellTestConfig::Reason::ECONOMIC, simulation_time); + if (write_message_to_opmlog) { + if (well_.wellEcl().getAutomaticShutIn()) { + const std::string msg = std::string("well ") + well_.name() + std::string(" will be shut due to rate economic limit"); + deferred_logger.info(msg); + } else { + const std::string msg = std::string("well ") + well_.name() + std::string(" will be stopped due to rate economic limit"); + deferred_logger.info(msg); + } + } + // the well is closed, not need to check other limits + return; + } + + if ( !econ_production_limits.onAnyRatioLimit() ) { + // there is no need to check the ratio limits + return; + } + + // checking for ratio related limits, mostly all kinds of ratio. + RatioLimitCheckReport ratio_report = + this->checkRatioEconLimits(econ_production_limits, ws, deferred_logger); + + if (ratio_report.ratio_limit_violated) { + const auto workover = econ_production_limits.workover(); + switch (workover) { + case WellEconProductionLimits::EconWorkover::CON: + { + const int worst_offending_completion = ratio_report.worst_offending_completion; + + well_test_state.close_completion(well_.name(), worst_offending_completion, simulation_time); + if (write_message_to_opmlog) { + if (worst_offending_completion < 0) { + const std::string msg = std::string("Connection ") + std::to_string(- worst_offending_completion) + + std::string(" for well ") + well_.name() + std::string(" will be closed due to economic limit"); + deferred_logger.info(msg); + } else { + const std::string msg = std::string("Completion ") + std::to_string(worst_offending_completion) + + std::string(" for well ") + well_.name() + std::string(" will be closed due to economic limit"); + deferred_logger.info(msg); + } + } + + bool allCompletionsClosed = true; + const auto& connections = well_.wellEcl().getConnections(); + for (const auto& connection : connections) { + if (connection.state() == Connection::State::OPEN + && !well_test_state.completion_is_closed(well_.name(), connection.complnum())) { + allCompletionsClosed = false; + } + } + + if (allCompletionsClosed) { + well_test_state.close_well(well_.name(), WellTestConfig::Reason::ECONOMIC, simulation_time); + if (write_message_to_opmlog) { + if (well_.wellEcl().getAutomaticShutIn()) { + const std::string msg = well_.name() + std::string(" will be shut due to last completion closed"); + deferred_logger.info(msg); + } else { + const std::string msg = well_.name() + std::string(" will be stopped due to last completion closed"); + deferred_logger.info(msg); + } + } + } + break; + } + case WellEconProductionLimits::EconWorkover::WELL: + { + well_test_state.close_well(well_.name(), WellTestConfig::Reason::ECONOMIC, simulation_time); + if (write_message_to_opmlog) { + if (well_.wellEcl().getAutomaticShutIn()) { + // tell the control that the well is closed + const std::string msg = well_.name() + std::string(" will be shut due to ratio economic limit"); + deferred_logger.info(msg); + } else { + const std::string msg = well_.name() + std::string(" will be stopped due to ratio economic limit"); + deferred_logger.info(msg); + } + } + break; + } + case WellEconProductionLimits::EconWorkover::NONE: + break; + default: + { + deferred_logger.warning("NOT_SUPPORTED_WORKOVER_TYPE", + "not supporting workover type " + WellEconProductionLimits::EconWorkover2String(workover)); + } + } + } +} } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 6904bbc54..29f9e8b16 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -35,13 +35,7 @@ class PhaseUsage; class SingleWellState; class WellEconProductionLimits; class WellInterfaceGeneric; - -struct RatioLimitCheckReport { - static constexpr int INVALIDCOMPLETION = std::numeric_limits::max(); - bool ratio_limit_violated = false; - int worst_offending_completion = INVALIDCOMPLETION; - double violation_extent = 0.0; -}; +class WellTestState; //! \brief Class for performing well tests. class WellTest { @@ -49,16 +43,20 @@ public: //! \brief Constructor sets reference to well. WellTest(const WellInterfaceGeneric& well) : well_(well) {} - bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, - const std::vector& rates_or_potentials, - DeferredLogger& deferred_logger) const; - - RatioLimitCheckReport - checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, - const SingleWellState& ws, - DeferredLogger& deferred_logger) const; + void updateWellTestStateEconomic(const SingleWellState& ws, + const double simulation_time, + const bool write_message_to_opmlog, + WellTestState& well_test_state, + DeferredLogger& deferred_logger) const; private: + struct RatioLimitCheckReport { + static constexpr int INVALIDCOMPLETION = std::numeric_limits::max(); + bool ratio_limit_violated = false; + int worst_offending_completion = INVALIDCOMPLETION; + double violation_extent = 0.0; + }; + void checkMaxGORLimit(const WellEconProductionLimits& econ_production_limits, const SingleWellState& ws, RatioLimitCheckReport& report) const; @@ -82,6 +80,16 @@ private: const RatioFunc& ratioFunc, RatioLimitCheckReport& report) const; + bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits, + const std::vector& rates_or_potentials, + DeferredLogger& deferred_logger) const; + + RatioLimitCheckReport + checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits, + const SingleWellState& ws, + DeferredLogger& deferred_logger) const; + + const WellInterfaceGeneric& well_; //!< Reference to well interface }; From 8b503f9a007adc7406a997b0591d123c6f518624 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 10/11] move updateWellTestStatePhysical to WellTest --- .../wells/WellInterfaceFluidSystem.cpp | 10 +++++----- opm/simulators/wells/WellInterfaceGeneric.cpp | 20 ------------------- opm/simulators/wells/WellInterfaceGeneric.hpp | 4 ---- opm/simulators/wells/WellTest.cpp | 19 ++++++++++++++++++ opm/simulators/wells/WellTest.hpp | 5 +++++ 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index 0821db8db..f7faff4a3 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -24,7 +24,6 @@ #include -#include #include #include @@ -513,12 +512,13 @@ updateWellTestState(const SingleWellState& ws, WellTestState& wellTestState, DeferredLogger& deferred_logger) const { - // updating well test state based on physical (THP/BHP) limits. - updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); - // updating well test state based on Economic limits for operable wells - if (this->isOperableAndSolvable()) + if (this->isOperableAndSolvable()) { WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); + } else { + // updating well test state based on physical (THP/BHP) limits. + WellTest(*this).updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); + } // TODO: well can be shut/closed due to other reasons } diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index 26134ed7d..ea15573f8 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -394,26 +394,6 @@ bool WellInterfaceGeneric::isVFPActive(DeferredLogger& deferred_logger) const } } -void WellInterfaceGeneric::updateWellTestStatePhysical(const double simulation_time, - const bool write_message_to_opmlog, - WellTestState& well_test_state, - DeferredLogger& deferred_logger) const -{ - if (!isOperableAndSolvable()) { - if (well_test_state.well_is_closed(name())) { - // Already closed, do nothing. - } else { - well_test_state.close_well(name(), WellTestConfig::Reason::PHYSICAL, simulation_time); - if (write_message_to_opmlog) { - const std::string action = well_ecl_.getAutomaticShutIn() ? "shut" : "stopped"; - const std::string msg = "Well " + name() - + " will be " + action + " as it can not operate under current reservoir conditions."; - deferred_logger.info(msg); - } - } - } -} - bool WellInterfaceGeneric::isOperableAndSolvable() const { return operability_status_.isOperableAndSolvable(); diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index 3972ad7e8..ce9199e01 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -202,10 +202,6 @@ public: protected: bool getAllowCrossFlow() const; double mostStrictBhpFromBhpLimits(const SummaryState& summaryState) const; - void updateWellTestStatePhysical(const double simulation_time, - const bool write_message_to_opmlog, - WellTestState& well_test_state, - DeferredLogger& deferred_logger) const; std::optional bhpMax(const std::function& fflo, const double bhp_limit, diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index 64fe4c006..1c0549bef 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -437,4 +437,23 @@ void WellTest::updateWellTestStateEconomic(const SingleWellState& ws, } } +void WellTest::updateWellTestStatePhysical(const double simulation_time, + const bool write_message_to_opmlog, + WellTestState& well_test_state, + DeferredLogger& deferred_logger) const +{ + if (well_test_state.well_is_closed(well_.name())) { + // Already closed, do nothing. + } else { + well_test_state.close_well(well_.name(), WellTestConfig::Reason::PHYSICAL, simulation_time); + if (write_message_to_opmlog) { + const std::string action = well_.wellEcl().getAutomaticShutIn() ? "shut" : "stopped"; + const std::string msg = "Well " + well_.name() + + " will be " + action + " as it can not operate under current reservoir conditions."; + deferred_logger.info(msg); + } + } +} + + } // namespace Opm diff --git a/opm/simulators/wells/WellTest.hpp b/opm/simulators/wells/WellTest.hpp index 29f9e8b16..c643207d9 100644 --- a/opm/simulators/wells/WellTest.hpp +++ b/opm/simulators/wells/WellTest.hpp @@ -49,6 +49,11 @@ public: WellTestState& well_test_state, DeferredLogger& deferred_logger) const; + void updateWellTestStatePhysical(const double simulation_time, + const bool write_message_to_opmlog, + WellTestState& well_test_state, + DeferredLogger& deferred_logger) const; + private: struct RatioLimitCheckReport { static constexpr int INVALIDCOMPLETION = std::numeric_limits::max(); From 0cc0b29a14ee7aada7cac9654cd3e2bbe955f414 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 24 Oct 2022 11:06:35 +0200 Subject: [PATCH 11/11] move updateWellTestState to WellInterfaceGeneric --- .../wells/WellInterfaceFluidSystem.cpp | 21 ---------------- .../wells/WellInterfaceFluidSystem.hpp | 6 ----- opm/simulators/wells/WellInterfaceGeneric.cpp | 25 ++++++++++++++++--- opm/simulators/wells/WellInterfaceGeneric.hpp | 6 ++++- opm/simulators/wells/WellTest.cpp | 1 - 5 files changed, 27 insertions(+), 32 deletions(-) diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.cpp b/opm/simulators/wells/WellInterfaceFluidSystem.cpp index f7faff4a3..36f468d2f 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.cpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -503,26 +502,6 @@ checkConstraints(WellState& well_state, } } -template -void -WellInterfaceFluidSystem:: -updateWellTestState(const SingleWellState& ws, - const double& simulationTime, - const bool& writeMessageToOPMLog, - WellTestState& wellTestState, - DeferredLogger& deferred_logger) const -{ - // updating well test state based on Economic limits for operable wells - if (this->isOperableAndSolvable()) { - WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); - } else { - // updating well test state based on physical (THP/BHP) limits. - WellTest(*this).updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); - } - - // TODO: well can be shut/closed due to other reasons -} - template int WellInterfaceFluidSystem:: diff --git a/opm/simulators/wells/WellInterfaceFluidSystem.hpp b/opm/simulators/wells/WellInterfaceFluidSystem.hpp index 8a8b8a3bc..26dbfd73c 100644 --- a/opm/simulators/wells/WellInterfaceFluidSystem.hpp +++ b/opm/simulators/wells/WellInterfaceFluidSystem.hpp @@ -52,12 +52,6 @@ protected: static constexpr int INVALIDCOMPLETION = std::numeric_limits::max(); public: - void updateWellTestState(const SingleWellState& ws, - const double& simulationTime, - const bool& writeMessageToOPMLog, - WellTestState& wellTestState, - DeferredLogger& deferred_logger) const; - int flowPhaseToEbosPhaseIdx(const int phaseIdx) const; static constexpr int Water = BlackoilPhases::Aqua; diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index ea15573f8..a297cd116 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -27,10 +27,11 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include +#include #include #include #include @@ -215,6 +216,24 @@ double WellInterfaceGeneric::mostStrictBhpFromBhpLimits(const SummaryState& summ return 0.0; } +void WellInterfaceGeneric::updateWellTestState(const SingleWellState& ws, + const double& simulationTime, + const bool& writeMessageToOPMLog, + WellTestState& wellTestState, + DeferredLogger& deferred_logger) const +{ + // updating well test state based on Economic limits for operable wells + if (this->isOperableAndSolvable()) { + WellTest(*this).updateWellTestStateEconomic(ws, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); + } else { + // updating well test state based on physical (THP/BHP) limits. + WellTest(*this).updateWellTestStatePhysical(simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger); + } + + // TODO: well can be shut/closed due to other reasons +} + + double WellInterfaceGeneric::getTHPConstraint(const SummaryState& summaryState) const { if (dynamic_thp_limit_) { diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index ce9199e01..06825526a 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -197,7 +197,11 @@ public: DeferredLogger& deferred_logger ) const; - + void updateWellTestState(const SingleWellState& ws, + const double& simulationTime, + const bool& writeMessageToOPMLog, + WellTestState& wellTestState, + DeferredLogger& deferred_logger) const; protected: bool getAllowCrossFlow() const; diff --git a/opm/simulators/wells/WellTest.cpp b/opm/simulators/wells/WellTest.cpp index 1c0549bef..cd1a3d646 100644 --- a/opm/simulators/wells/WellTest.cpp +++ b/opm/simulators/wells/WellTest.cpp @@ -455,5 +455,4 @@ void WellTest::updateWellTestStatePhysical(const double simulation_time, } } - } // namespace Opm