From 9a669f540022835b84976bdf082e3adeca4a9b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 28 Feb 2020 05:27:25 +0100 Subject: [PATCH 1/3] Restart File: Output Well's Preferred Phase Note: We're missing the 'LIQUID' option (integer value 4) since Well::getPreferredPhase() does not return that value. Also, while here, remove the previously misattributed IWEL[15] item. This item is the well's preferred phase, not the prediction control. Finally, don't assign the active control mode to the history control. That was a mistake. --- opm/io/eclipse/rst/well.hpp | 1 - opm/output/eclipse/VectorItems/well.hpp | 10 +- src/opm/io/eclipse/rst/well.cpp | 1 - src/opm/output/eclipse/AggregateWellData.cpp | 91 +++++++++++++------ .../EclipseState/Schedule/Well/Well.cpp | 2 +- 5 files changed, 73 insertions(+), 32 deletions(-) diff --git a/opm/io/eclipse/rst/well.hpp b/opm/io/eclipse/rst/well.hpp index 33114a167..59f287dd9 100644 --- a/opm/io/eclipse/rst/well.hpp +++ b/opm/io/eclipse/rst/well.hpp @@ -69,7 +69,6 @@ struct RstWell { int well_status; int active_control; int vfp_table; - int pred_requested_control; bool allow_xflow; int hist_requested_control; int msw_index; diff --git a/opm/output/eclipse/VectorItems/well.hpp b/opm/output/eclipse/VectorItems/well.hpp index c1ceca186..406e1f073 100644 --- a/opm/output/eclipse/VectorItems/well.hpp +++ b/opm/output/eclipse/VectorItems/well.hpp @@ -39,8 +39,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems Status = 10, // Well status VFPTab = 11, // ID (one-based) of well's current VFP table. - PredReqWCtrl = 15, // Well's requested control mode from - // simulation deck (WCONINJE, WCONPROD). + PreferredPhase = 15, // Well's preferred phase (from WELSPECS) item18 = 17, // Unknown XFlow = 22, @@ -111,6 +110,13 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems // COMPDAT keyword. }; + enum Preferred_Phase : int { + Oil = 1, + Water = 2, + Gas = 3, + Liquid = 4, + }; + enum PLossMod : int { HFA = 0, // Components of pressure loss in MSW model for well (WELSEGS item 6) // Hydrostatic, Friction, Acceleration diff --git a/src/opm/io/eclipse/rst/well.cpp b/src/opm/io/eclipse/rst/well.cpp index 402bae2e2..13c93c59a 100644 --- a/src/opm/io/eclipse/rst/well.cpp +++ b/src/opm/io/eclipse/rst/well.cpp @@ -64,7 +64,6 @@ RstWell::RstWell(const ::Opm::UnitSystem& unit_system, well_status( iwel[VI::IWell::Status]), active_control( iwel[VI::IWell::ActWCtrl]), vfp_table( iwel[VI::IWell::VFPTab]), - pred_requested_control( iwel[VI::IWell::PredReqWCtrl]), allow_xflow( iwel[VI::IWell::XFlow] == 1), hist_requested_control( iwel[VI::IWell::HistReqWCtrl]), msw_index( iwel[VI::IWell::MsWID]), diff --git a/src/opm/output/eclipse/AggregateWellData.cpp b/src/opm/output/eclipse/AggregateWellData.cpp index ff0c4a60d..2ada40e53 100644 --- a/src/opm/output/eclipse/AggregateWellData.cpp +++ b/src/opm/output/eclipse/AggregateWellData.cpp @@ -27,18 +27,20 @@ #include #include -#include -#include -#include -#include -#include -#include #include #include +#include #include #include -#include #include +#include +#include +#include +#include +#include + +#include +#include #include #include @@ -228,28 +230,59 @@ namespace { } } + int preferredPhase(const Opm::Well& well) + { + using PhaseVal = VI::IWell::Value::Preferred_Phase; + + if (well.isProducer()) { // Preferred phase from WELSPECS + switch (well.getPreferredPhase()) { + case Opm::Phase::OIL: return PhaseVal::Oil; + case Opm::Phase::GAS: return PhaseVal::Gas; + case Opm::Phase::WATER: return PhaseVal::Water; + + // Should have LIQUID here too... + + default: + throw std::invalid_argument { + "Unsupported Preferred Phase '" + + std::to_string(static_cast(well.getPreferredPhase())) + + '\'' + }; + } + } + else { // Injector. Preferred phase reset to injected phase. + using IType = Opm::InjectorType; + const auto& iprop = well.getInjectionProperties(); + + switch (iprop.injectorType) { + case IType::OIL: return PhaseVal::Oil; + case IType::GAS: return PhaseVal::Gas; + case IType::WATER: return PhaseVal::Water; + + default: + throw std::invalid_argument { + "Unsupported Injector Type '" + + std::to_string(static_cast(iprop.injectorType)) + + '\'' + }; + } + } + } template - void setCurrentControl(const Opm::Well& well, - const int curr, - IWellArray& iWell) + void setHistoryControlMode(const Opm::Well& well, + const int curr, + IWellArray& iWell) { - using Ix = VI::IWell::index; + iWell[VI::IWell::index::HistReqWCtrl] = + well.predictionMode() ? 0 : curr; + } - iWell[Ix::ActWCtrl] = curr; - - if (well.predictionMode()) { - // Well in prediction mode (WCONPROD, WCONINJE). Assign - // requested control mode for prediction. - iWell[Ix::PredReqWCtrl] = curr; - iWell[Ix::HistReqWCtrl] = 0; - } - else { - // Well controlled by observed rates/BHP (WCONHIST, - // WCONINJH). Assign requested control mode for history. - iWell[Ix::PredReqWCtrl] = 0; // Possibly =1 instead. - iWell[Ix::HistReqWCtrl] = curr; - } + template + void setCurrentControl(const int curr, + IWellArray& iWell) + { + iWell[VI::IWell::index::ActWCtrl] = curr; } template @@ -264,6 +297,7 @@ namespace { iWell[Ix::IHead] = well.getHeadI() + 1; iWell[Ix::JHead] = well.getHeadJ() + 1; iWell[Ix::Status] = wellStatus(well.getStatus()); + // Connections { const auto& conn = well.getConnections(); @@ -292,6 +326,8 @@ namespace { iWell[Ix::VFPTab] = wellVFPTab(well, st); iWell[Ix::XFlow] = well.getAllowCrossFlow() ? 1 : 0; + iWell[Ix::PreferredPhase] = preferredPhase(well); + // The following items aren't fully characterised yet, but // needed for restart of M2. Will need further refinement. iWell[Ix::item18] = -100; @@ -306,7 +342,8 @@ namespace { // // Observe that the setupCurrentContro() function is called again // for open wells in the dynamicContrib() function. - setCurrentControl(well, eclipseControlMode(well, st), iWell); + setCurrentControl(eclipseControlMode(well, st), iWell); + setHistoryControlMode(well, eclipseControlMode(well, st), iWell); // Multi-segmented well information iWell[Ix::MsWID] = 0; // MS Well ID (0 or 1..#MS wells) @@ -366,7 +403,7 @@ namespace { using Value = VI::IWell::Value::Status; if (wellControlDefined(xw)) { - setCurrentControl(well, ctrlMode(well, xw), iWell); + setCurrentControl(ctrlMode(well, xw), iWell); } const auto any_flowing_conn = diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp index c9685b281..afe628dcb 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp @@ -145,7 +145,7 @@ Well::Well(const RestartIO::RstWell& rst_well, guide_rate(def_guide_rate), efficiency_factor(rst_well.efficiency_factor), solvent_fraction(def_solvent_fraction), - prediction_mode(rst_well.pred_requested_control != 0), + prediction_mode(rst_well.hist_requested_control == 0), econ_limits(std::make_shared()), foam_properties(std::make_shared()), polymer_properties(std::make_shared()), From c76878520a00da29a4137b55bee468924a36d22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 3 Mar 2020 05:45:56 +0100 Subject: [PATCH 2/3] Load Well's Preferred Phase from Restart File --- opm/io/eclipse/rst/well.hpp | 1 + src/opm/io/eclipse/rst/well.cpp | 1 + test_util/EclRegressionTest.cpp | 6 ++---- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/io/eclipse/rst/well.hpp b/opm/io/eclipse/rst/well.hpp index 59f287dd9..e6ba452a2 100644 --- a/opm/io/eclipse/rst/well.hpp +++ b/opm/io/eclipse/rst/well.hpp @@ -70,6 +70,7 @@ struct RstWell { int active_control; int vfp_table; bool allow_xflow; + int preferred_phase; int hist_requested_control; int msw_index; int completion_ordering; diff --git a/src/opm/io/eclipse/rst/well.cpp b/src/opm/io/eclipse/rst/well.cpp index 13c93c59a..3da024e9f 100644 --- a/src/opm/io/eclipse/rst/well.cpp +++ b/src/opm/io/eclipse/rst/well.cpp @@ -65,6 +65,7 @@ RstWell::RstWell(const ::Opm::UnitSystem& unit_system, active_control( iwel[VI::IWell::ActWCtrl]), vfp_table( iwel[VI::IWell::VFPTab]), allow_xflow( iwel[VI::IWell::XFlow] == 1), + preferred_phase( iwel[VI::IWell::PreferredPhase]), hist_requested_control( iwel[VI::IWell::HistReqWCtrl]), msw_index( iwel[VI::IWell::MsWID]), completion_ordering( iwel[VI::IWell::CompOrd]), diff --git a/test_util/EclRegressionTest.cpp b/test_util/EclRegressionTest.cpp index ea2646680..bbfd2e2cc 100644 --- a/test_util/EclRegressionTest.cpp +++ b/test_util/EclRegressionTest.cpp @@ -60,8 +60,6 @@ std::vector sorted(std::vector v) { return v; } -} - template int compare(const std::string& name, const T& v1, const T& v2, const std::string& fmt) { if (v1 == v2) @@ -97,8 +95,8 @@ bool rst_cmp(const Opm::RestartIO::RstState& rst1, const Opm::RestartIO::RstStat error_count += compare(well1.name, well1.well_status, well2.well_status, "Different status for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.active_control, well2.active_control, "Different active_control for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.vfp_table, well2.vfp_table, "Different vfp_table for well: {} case1: {} case2: {}"); - error_count += compare(well1.name, well1.pred_requested_control, well2.pred_requested_control,"Different pred_requested_control for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.allow_xflow, well2.allow_xflow, "Different allow_xflow for well: {} case1: {} case2: {}"); + error_count += compare(well1.name, well1.preferred_phase, well2.preferred_phase, "Different preferred_phase for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.hist_requested_control, well2.hist_requested_control,"Different hist_requested_control for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.msw_index, well2.msw_index, "Different msw_index for well: {} case1: {} case2: {}"); error_count += compare(well1.name, well1.completion_ordering, well2.completion_ordering, "Different completion_ordering for well: {} case1: {} case2: {}"); @@ -106,7 +104,7 @@ bool rst_cmp(const Opm::RestartIO::RstState& rst1, const Opm::RestartIO::RstStat } return error_count == 0; } - +} using namespace Opm::EclIO; From 2fb768e7276692b09e85a86b6bbd9cc561ffdf10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 12 Nov 2020 11:16:24 +0100 Subject: [PATCH 3/3] Simplify Preferred Phase Extraction Well::getPreferredPhase() now knows that the preferred phase for injectors is the injected phase. There is no need to special-case injectors here. --- src/opm/output/eclipse/AggregateWellData.cpp | 41 ++++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/opm/output/eclipse/AggregateWellData.cpp b/src/opm/output/eclipse/AggregateWellData.cpp index 2ada40e53..596db098e 100644 --- a/src/opm/output/eclipse/AggregateWellData.cpp +++ b/src/opm/output/eclipse/AggregateWellData.cpp @@ -234,38 +234,19 @@ namespace { { using PhaseVal = VI::IWell::Value::Preferred_Phase; - if (well.isProducer()) { // Preferred phase from WELSPECS - switch (well.getPreferredPhase()) { - case Opm::Phase::OIL: return PhaseVal::Oil; - case Opm::Phase::GAS: return PhaseVal::Gas; - case Opm::Phase::WATER: return PhaseVal::Water; + switch (well.getPreferredPhase()) { + case Opm::Phase::OIL: return PhaseVal::Oil; + case Opm::Phase::GAS: return PhaseVal::Gas; + case Opm::Phase::WATER: return PhaseVal::Water; - // Should have LIQUID here too... + // Should have LIQUID here too... - default: - throw std::invalid_argument { - "Unsupported Preferred Phase '" + - std::to_string(static_cast(well.getPreferredPhase())) - + '\'' - }; - } - } - else { // Injector. Preferred phase reset to injected phase. - using IType = Opm::InjectorType; - const auto& iprop = well.getInjectionProperties(); - - switch (iprop.injectorType) { - case IType::OIL: return PhaseVal::Oil; - case IType::GAS: return PhaseVal::Gas; - case IType::WATER: return PhaseVal::Water; - - default: - throw std::invalid_argument { - "Unsupported Injector Type '" + - std::to_string(static_cast(iprop.injectorType)) - + '\'' - }; - } + default: + throw std::invalid_argument { + "Unsupported Preferred Phase '" + + std::to_string(static_cast(well.getPreferredPhase())) + + '\'' + }; } }