From 0c9a2cbbf6ceb98f8365ac5a2b954629feff1c08 Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Wed, 16 Oct 2019 15:47:03 +0200 Subject: [PATCH 1/6] initial changes to test output of UDQ and ACTIONX data to ecl-restart change to avoid zero-size windows in Actionx changes to improve Restart output content change to correct IUDQ for DEFINE corrections to IACN and SACN initial changes to add item to ZWEL further changes to add Action to well further changes to allow for action name in ZWEL more changes further changes to output action name to ZWEL changes to test/debug Restart write turn on writing of ZWEL again First running version of udq-actionx-rst use Action::Result direkte first working! version some corrections changes to allow for output of SACN [4.6.8] added debug print changes to improve IACN and IACT further corrections to Actionx IACN pluss error messages changes to adapt to well2 converted to well class further changes to enable restart with group control changes to adapt to newly merged code in master changes to include Intehead [51] - group control test changes to iGrp[nwgmax +7] initial changes for GUIDERATE changes to add guiderate parameters to the restart file add comment correction to guiderate - test if exist correction to DoubHead - test if GR exist correction to ISEG[8] correction for eclipse version Restart-file Cosmetic change corrections to igrp correction to segment type in iseg --- opm/output/eclipse/AggregateGroupData.hpp | 27 +- opm/output/eclipse/AggregateWellData.hpp | 6 + opm/output/eclipse/DoubHEAD.hpp | 12 + opm/output/eclipse/InteHEAD.hpp | 14 +- opm/output/eclipse/VectorItems/connection.hpp | 1 + opm/output/eclipse/VectorItems/doubhead.hpp | 20 +- opm/output/eclipse/VectorItems/group.hpp | 24 + opm/output/eclipse/VectorItems/intehead.hpp | 13 +- opm/output/eclipse/VectorItems/msw.hpp | 1 + opm/output/eclipse/VectorItems/well.hpp | 1 + .../Schedule/Action/ActionResult.hpp | 6 +- .../EclipseState/Schedule/Group/Group.hpp | 1 + .../Schedule/Group/GuideRateModel.hpp | 8 +- .../output/eclipse/AggregateActionxData.cpp | 250 +++++--- .../eclipse/AggregateConnectionData.cpp | 1 + src/opm/output/eclipse/AggregateGroupData.cpp | 179 +++++- src/opm/output/eclipse/AggregateMSWData.cpp | 31 +- src/opm/output/eclipse/AggregateUDQData.cpp | 108 +++- src/opm/output/eclipse/AggregateWellData.cpp | 61 +- src/opm/output/eclipse/CreateDoubHead.cpp | 45 +- src/opm/output/eclipse/CreateInteHead.cpp | 131 +++- src/opm/output/eclipse/CreateUdqDims.cpp | 66 +- src/opm/output/eclipse/DoubHEAD.cpp | 35 +- src/opm/output/eclipse/InteHEAD.cpp | 62 +- src/opm/output/eclipse/RestartIO.cpp | 37 +- .../Schedule/Action/ActionResult.cpp | 15 +- .../EclipseState/Schedule/Group/Group.cpp | 3 + .../Schedule/Group/GuideRateModel.cpp | 24 + tests/UDQ_ACTIONX_TEST1.DATA | 19 +- tests/test_AggregateActionxData.cpp | 23 +- tests/test_AggregateActionxData_2.cpp | 564 ++++++++++++++++++ tests/test_AggregateGroupData.cpp | 6 +- tests/test_AggregateUDQData.cpp | 4 +- 33 files changed, 1523 insertions(+), 275 deletions(-) create mode 100644 tests/test_AggregateActionxData_2.cpp diff --git a/opm/output/eclipse/AggregateGroupData.hpp b/opm/output/eclipse/AggregateGroupData.hpp index eb7f8bf42..932213b6b 100644 --- a/opm/output/eclipse/AggregateGroupData.hpp +++ b/opm/output/eclipse/AggregateGroupData.hpp @@ -23,7 +23,7 @@ #include #include - +#include #include #include #include @@ -32,7 +32,8 @@ namespace Opm { class Schedule; class SummaryState; -class Group; +//class Group; +class UnitSystem; } // Opm namespace Opm { namespace RestartIO { namespace Helpers { @@ -42,10 +43,11 @@ class AggregateGroupData public: explicit AggregateGroupData(const std::vector& inteHead); - void captureDeclaredGroupData(const Opm::Schedule& sched, - const std::size_t simStep, - const Opm::SummaryState& sumState, - const std::vector& inteHead); + void captureDeclaredGroupData(const Opm::Schedule& sched, + const Opm::UnitSystem& units, + const std::size_t simStep, + const Opm::SummaryState& sumState, + const std::vector& inteHead); const std::vector& getIGroup() const { @@ -104,6 +106,19 @@ public: {"GGPTH", 143}, {"GGITH", 144}, }; + + + using inj_cmode_enum = Opm::Group::InjectionCMode; + const std::map cmodeToNum = { + + {inj_cmode_enum::NONE, 0}, + {inj_cmode_enum::RATE, 1}, + {inj_cmode_enum::RESV, 2}, + {inj_cmode_enum::REIN, 3}, + {inj_cmode_enum::VREP, 4}, + {inj_cmode_enum::FLD, 0}, + {inj_cmode_enum::SALE, 0}, + }; const std::map fieldKeyToIndex = { {"FOPR", 0}, diff --git a/opm/output/eclipse/AggregateWellData.hpp b/opm/output/eclipse/AggregateWellData.hpp index fea039e7c..1f8a43c03 100644 --- a/opm/output/eclipse/AggregateWellData.hpp +++ b/opm/output/eclipse/AggregateWellData.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -39,6 +40,11 @@ namespace Opm { namespace data { }} // Opm::data namespace Opm { namespace RestartIO { namespace Helpers { + + struct ActionResStatus { + std::vector result; + std::vector name; + }; class AggregateWellData { diff --git a/opm/output/eclipse/DoubHEAD.hpp b/opm/output/eclipse/DoubHEAD.hpp index d9e72ee54..86b9adfd5 100755 --- a/opm/output/eclipse/DoubHEAD.hpp +++ b/opm/output/eclipse/DoubHEAD.hpp @@ -40,6 +40,17 @@ namespace Opm { namespace RestartIO { std::chrono::duration elapsed; }; + struct guideRate { + double A; + double B; + double C; + double D; + double E; + double F; + double delay; + double damping_fact; + }; + DoubHEAD(); ~DoubHEAD() = default; @@ -61,6 +72,7 @@ namespace Opm { namespace RestartIO { const double cnvT); DoubHEAD& udq_param(const UDQParams& udqPar); + DoubHEAD& guide_rate_param(const guideRate& guide_rp); const std::vector& data() const { diff --git a/opm/output/eclipse/InteHEAD.hpp b/opm/output/eclipse/InteHEAD.hpp index d824d6f99..5969615d9 100755 --- a/opm/output/eclipse/InteHEAD.hpp +++ b/opm/output/eclipse/InteHEAD.hpp @@ -93,7 +93,11 @@ namespace Opm { namespace RestartIO { struct UdqParam { int udqParam_1; - int no_udqs; + int no_wudqs; + int no_gudqs; + int no_fudqs; + int no_iuads; + int no_iuaps; }; struct ActionParam { @@ -102,6 +106,11 @@ namespace Opm { namespace RestartIO { int max_no_conditions_per_action; int max_no_characters_per_line; }; + + struct GuideRateNominatedPhase { + int nominated_phase; + }; + InteHEAD(); ~InteHEAD() = default; @@ -122,6 +131,7 @@ namespace Opm { namespace RestartIO { InteHEAD& params_NWELZ(const int niwelz, const int nswelz, const int nxwelz, const int nzwelz); InteHEAD& params_NCON(const int niconz, const int nsconz, const int nxconz); InteHEAD& params_GRPZ(const std::array& grpz); + InteHEAD& params_NGCTRL(const int gct); InteHEAD& params_NAAQZ(const int ncamax, const int niaaqz, const int nsaaqz, const int nxaaqz, const int nicaqz, const int nscaqz, const int nacaqz); InteHEAD& stepParam(const int tstep, const int report_step); InteHEAD& tuningParam(const TuningPar& tunpar); @@ -131,6 +141,8 @@ namespace Opm { namespace RestartIO { InteHEAD& ngroups(const Group& gr); InteHEAD& udqParam_1(const UdqParam& udqpar); InteHEAD& actionParam(const ActionParam& act_par); + InteHEAD& variousUDQ_ACTIONXParam(); + InteHEAD& nominatedPhaseGuideRate(GuideRateNominatedPhase nphase); const std::vector& data() const { diff --git a/opm/output/eclipse/VectorItems/connection.hpp b/opm/output/eclipse/VectorItems/connection.hpp index 22e1d480b..a7b155c4a 100644 --- a/opm/output/eclipse/VectorItems/connection.hpp +++ b/opm/output/eclipse/VectorItems/connection.hpp @@ -57,6 +57,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems item30 = 29, // Unknown item31 = 30, // Unknown + item41 = 40, // = 0 for connection factor not defined, = 1 for connection factor defined }; } // SConn diff --git a/opm/output/eclipse/VectorItems/doubhead.hpp b/opm/output/eclipse/VectorItems/doubhead.hpp index 7e76a8513..1905e158c 100644 --- a/opm/output/eclipse/VectorItems/doubhead.hpp +++ b/opm/output/eclipse/VectorItems/doubhead.hpp @@ -27,12 +27,20 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems // This is a subset of the items in src/opm/output/eclipse/DoubHEAD.cpp . // Promote items from that list to this in order to make them public. enum doubhead : std::vector::size_type { - TsInit = 1, // Maximum Length of Next Timestep - TsMaxz = 2, // Maximum Length of Timestep After Next - TsMinz = 3, // Minumum Length of All Timesteps - UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities) - UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data) - UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions) + TsInit = 1, // Maximum Length of Next Timestep + TsMaxz = 2, // Maximum Length of Timestep After Next + TsMinz = 3, // Minumum Length of All Timesteps + GRpar_a = 87, // Guiderate parameter A + GRpar_b = 88, // Guiderate parameter B + GRpar_c = 89, // Guiderate parameter C + GRpar_d = 90, // Guiderate parameter D + GRpar_e = 91, // Guiderate parameter E + GRpar_f = 92, // Guiderate parameter F + GRpar_int = 97, // Guiderate parameter delay interval + GRpar_damp = 144, // Guiderate parameter damping factor + UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities) + UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data) + UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions) }; }}}} // Opm::RestartIO::Helpers::VectorItems diff --git a/opm/output/eclipse/VectorItems/group.hpp b/opm/output/eclipse/VectorItems/group.hpp index 46853a081..2f9027b54 100644 --- a/opm/output/eclipse/VectorItems/group.hpp +++ b/opm/output/eclipse/VectorItems/group.hpp @@ -24,6 +24,30 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems { + + namespace SGroup { + enum prod_index : std::vector::size_type { + OilRateLimit = 6, // Group's oil production target/limit + WatRateLimit = 7, // Group's water production target/limit + GasRateLimit = 8, // Group's gas production target/limit + LiqRateLimit = 9, // Group's liquid production target/limit + }; + + enum inj_index : std::vector::size_type { + waterSurfRateLimit = 15, // Group's water surface volume injection rate target/limit + waterResRateLimit = 16, // Group's water reservoir volume injection rate target/limit + waterReinjectionLimit = 17, // Group's water reinjection fraction target/limit + waterVoidageLimit = 18, // Group's water voidage injection fraction target/limit + gasSurfRateLimit = 20, // Group's gas surface volume injection rate target/limit + gasResRateLimit = 21, // Group's gas reservoir volume injection rate target/limit + gasReinjectionLimit = 22, // Group's gas reinjection fraction target/limit + gasVoidageLimit = 23, // Group's gas voidage injection fraction target/limit + + }; + } // SGroup + + + namespace XGroup { enum index : std::vector::size_type { OilPrRate = 0, // Group's oil production rate diff --git a/opm/output/eclipse/VectorItems/intehead.hpp b/opm/output/eclipse/VectorItems/intehead.hpp index eed5e953c..458b8cb30 100644 --- a/opm/output/eclipse/VectorItems/intehead.hpp +++ b/opm/output/eclipse/VectorItems/intehead.hpp @@ -75,6 +75,10 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems NICAQZ = 45, // Number of data elements per aquifer connection in ICAQ array NSCAQZ = 46, // Number of data elements per aquifer connection in SCAQ array NACAQZ = 47, // Number of data elements per aquifer connection in ACAQ array + + NGCTRL = 51, // Index indicating if group control is used or not (1 - if group control, 0 if not) + + NGRNPH = 58, // Index indicating if group control is used or not (1 - if group control, 0 if not) DAY = 64, // Calendar day of report step (1..31) MONTH = 65, // Calendar month of report step (1..12) @@ -96,11 +100,14 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems NILBRZ = 180, // Number of entries per segment in ILBR array MAX_ACT_COND = 245, // Maximum number of conditions pr action - MAX_AN_AQUIFERS = 252, // Maximum number of analytic aquifers - NO_UDQS = 266, // No of UDQ data (parameters) - UDQPAR_1 = 267, // Integer seed value for the RAND + NO_FIELD_UDQS = 262, // No of Field UDQ data (parameters) / + NO_GROUP_UDQS = 263, // No of Group UDQ data (parameters) / + NO_WELL_UDQS = 266, // No of Well UDQ data (parameters) / + UDQPAR_1 = 267, // Integer seed value for the RAND / + NO_IUADS = 290, // No IUADs + NO_IUAPS = 291, // No IUAPs RSEED = 296, }; }}}} // Opm::RestartIO::Helpers::VectorItems diff --git a/opm/output/eclipse/VectorItems/msw.hpp b/opm/output/eclipse/VectorItems/msw.hpp index b205368c5..4037c6f39 100644 --- a/opm/output/eclipse/VectorItems/msw.hpp +++ b/opm/output/eclipse/VectorItems/msw.hpp @@ -39,6 +39,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems namespace Value { enum SegmentType : int { + REGULAR = -1, AICD = -8, SICD = -7, Valve = -5, diff --git a/opm/output/eclipse/VectorItems/well.hpp b/opm/output/eclipse/VectorItems/well.hpp index 1e3ec5dbb..9dc08c904 100644 --- a/opm/output/eclipse/VectorItems/well.hpp +++ b/opm/output/eclipse/VectorItems/well.hpp @@ -180,6 +180,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems namespace ZWell { enum index : std::vector::size_type { WellName = 0, // Well name + ActionX = 2, // ActionX name }; } // ZWell }}}} // Opm::RestartIO::Helpers::VectorItems diff --git a/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp b/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp index 1f60ef7b4..d8a568692 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp @@ -95,11 +95,15 @@ public: explicit operator bool() const; std::vector wells() const; - bool has_well(const std::string& well); + + bool has_well(const std::string& well) const; + void add_well(const std::string& well); Result& operator|=(const Result& other); + Result& operator=(const Result& src); Result& operator&=(const Result& other); + private: void assign(bool value); bool result; diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp index 17f3f6e00..02e2ea2c7 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp @@ -197,6 +197,7 @@ struct ProductionControls { InjectionControls injectionControls(const SummaryState& st) const; const GroupProductionProperties& productionProperties() const; const GroupInjectionProperties& injectionProperties() const; + const GroupType& getGroupType() const; ProductionCMode production_cmode() const; InjectionCMode injection_cmode() const; Phase injection_phase() const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp index d615b132c..39a81b62a 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp @@ -62,7 +62,13 @@ public: bool operator==(const GuideRateModel& other) const; bool operator!=(const GuideRateModel& other) const; Target target() const; - + double getA() const; + double getB() const; + double getC() const; + double getD() const; + double getE() const; + double getF() const; + static Target convert_target(Group::GuideRateTarget group_target); static Target convert_target(Well::GuideRateTarget well_target); static double pot(Target target, double oil_pot, double gas_pot, double wat_pot); diff --git a/src/opm/output/eclipse/AggregateActionxData.cpp b/src/opm/output/eclipse/AggregateActionxData.cpp index 4cc19f339..af5d38c26 100644 --- a/src/opm/output/eclipse/AggregateActionxData.cpp +++ b/src/opm/output/eclipse/AggregateActionxData.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -30,6 +31,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -42,7 +46,7 @@ #include // ##################################################################### -// Class Opm::RestartIO::Helpers::AggregateGroupData +// Class Opm::RestartIO::Helpers // --------------------------------------------------------------------- @@ -55,6 +59,25 @@ namespace { {"M", 11}, {"Y", 12}, }; + + /*const std::map lhsQuantityToItem_12 = { + {"F", 0}, + {"W", 0}, + {"G", 0}, + {"D", 0}, + {"M", 1}, + {"Y", 0}, + };*/ + + using cmp_enum = Opm::Action::Condition::Comparator; + const std::map cmpToIacn_12 = { + {cmp_enum::GREATER, 0}, + {cmp_enum::LESS, 1}, + {cmp_enum::GREATER_EQUAL, 0}, + {cmp_enum::LESS_EQUAL, 1}, + {cmp_enum::EQUAL, 1}, + {cmp_enum::INVALID, 0}, + }; const std::map monthToNo = { {"JAN", 1.}, @@ -72,35 +95,35 @@ namespace { }; - const std::map rhsQuantityToIndex = { - {"F", 1}, - {"W", 2}, - {"G", 3}, - }; - - using logic_enum = Opm::Action::Condition::Logical; - const std::map logicalToIndex_13 = { - {logic_enum::AND, 1}, - {logic_enum::OR, 2}, - {logic_enum::END, 0}, - }; - - const std::map logicalToIndex_17 = { - {logic_enum::AND, 1}, - {logic_enum::OR, 0}, - {logic_enum::END, 0}, - }; +const std::map rhsQuantityToIndex = { + {"F", 1}, + {"W", 2}, + {"G", 3}, +}; +using logic_enum = Opm::Action::Condition::Logical; +const std::map logicalToIndex_13 = { + {logic_enum::AND, 1}, + {logic_enum::OR, 2}, + {logic_enum::END, 0}, +}; - using cmp_enum = Opm::Action::Condition::Comparator; - const std::map cmpToIndex = { - {cmp_enum::GREATER, 1}, - {cmp_enum::LESS, 2}, - {cmp_enum::GREATER_EQUAL, 3}, - {cmp_enum::LESS_EQUAL, 4}, - {cmp_enum::EQUAL, 5}, - {cmp_enum::INVALID, 0}, - }; +const std::map logicalToIndex_17 = { + {logic_enum::AND, 1}, + {logic_enum::OR, 0}, + {logic_enum::END, 0}, +}; + + +using cmp_enum = Opm::Action::Condition::Comparator; +const std::map cmpToIndex = { + {cmp_enum::GREATER, 1}, + {cmp_enum::LESS, 2}, + {cmp_enum::GREATER_EQUAL, 3}, + {cmp_enum::LESS_EQUAL, 4}, + {cmp_enum::EQUAL, 5}, + {cmp_enum::INVALID, 0}, +}; namespace iACT { @@ -109,9 +132,12 @@ namespace { allocate(const std::vector& actDims) { using WV = Opm::RestartIO::Helpers::WindowedArray; + + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[1], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[1]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -122,8 +148,18 @@ namespace { iAct[0] = 0; //item [1]: The number of lines of schedule data including ENDACTIO iAct[1] = actx.keyword_strings().size(); - //item [2]: is unknown, (=1) - iAct[2] = 1; + //item [2]: is = 1 for condition and previous condition = AND, and combinations OR/AND + // is = 2 for all conditions and previous conditions = OR + // This is not implemented yet - only use 1 for all cases + const auto& actx_cond = actx.conditions(); + int i_temp = 2; + for (auto cond_it = actx_cond.begin(); cond_it < actx_cond.end(); cond_it++) { + const auto it_logic_17 = logicalToIndex_17.find(cond_it->logic); + if (it_logic_17 != logicalToIndex_17.end()) { + if (it_logic_17->first == logic_enum::AND) i_temp = 1; + } + } + iAct[2] = i_temp; //item [3]: is unknown, (=7) iAct[3] = 7; //item [4]: is unknown, (=0) @@ -146,9 +182,12 @@ namespace { allocate(const std::vector& actDims) { using WV = Opm::RestartIO::Helpers::WindowedArray; + + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[2], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[2]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -173,10 +212,12 @@ namespace { using WV = Opm::RestartIO::Helpers::WindowedArray< Opm::EclIO::PaddedOutputString<8> >; - + + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[3], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[3]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -198,10 +239,11 @@ namespace { using WV = Opm::RestartIO::Helpers::WindowedArray< Opm::EclIO::PaddedOutputString<8> >; - + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[4], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[4]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -243,9 +285,11 @@ namespace { Opm::EclIO::PaddedOutputString<8> >; + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[5], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[5]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -291,8 +335,6 @@ namespace { } } } // zAcn - -} namespace iACN { @@ -300,9 +342,12 @@ namespace { allocate(const std::vector& actDims) { using WV = Opm::RestartIO::Helpers::WindowedArray; + + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[6], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[6]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } @@ -352,13 +397,13 @@ namespace { iAcn[ind + 11] = it_rhsq->second; } - /*item[12] - index for lhs type - 1 - for MNTH - 0 - for all other types + /*item[12] - index for relational operator (<, =, > ) + 0 - for LHS quantity greater RHS quantity + 1 - for LHS quantity less than or equal to RHS quantity */ - std::string lhsQ = z_data.lhs.quantity; - if ( lhsQ == "MNTH") { - iAcn[ind + 12] = 1; + const auto it_lhs_it = cmpToIacn_12.find(z_data.cmp); + if (it_lhs_it != cmpToIacn_12.end()) { + iAcn[ind + 12] = it_lhs_it->second; } /*item [13] - relates to operator @@ -424,42 +469,62 @@ namespace { allocate(const std::vector& actDims) { using WV = Opm::RestartIO::Helpers::WindowedArray; + + int nwin = std::max(actDims[0], 1); + int nitPrWin = std::max(actDims[7], 1); return WV { - WV::NumWindows{ static_cast(actDims[0]) }, - WV::WindowSize{ static_cast(actDims[7]) } + WV::NumWindows{ static_cast(nwin) }, + WV::WindowSize{ static_cast(nitPrWin) } }; } + + Opm::Action::Result + act_res(const Opm::Schedule& sched, const Opm::SummaryState& smry, const std::size_t sim_step, std::vector::const_iterator act_x) { + Opm::Action::Result ar(false); + Opm::Action::Context context(smry); + auto sim_time = sched.simTime(sim_step); + if (act_x->ready(sim_time)) { + ar = act_x->eval(sim_time, context); + } + return {ar}; + } template - void staticContrib(const Opm::Action::ActionX& actx, - const Opm::SummaryState& st, - SACNArray& sAcn) + void staticContrib(std::vector::const_iterator actx_it, + const Opm::SummaryState& st, + const Opm::Schedule& sched, + const std::size_t simStep, + SACNArray& sAcn) { std::size_t ind = 0; int noEPZacn = 16; double undef_high_val = 1.0E+20; + const auto& wells = sched.getWells(simStep); + const auto ar = sACN::act_res(sched, st, simStep, actx_it); // write out the schedule Actionx conditions - const auto& actx_cond = actx.conditions(); + const auto& actx_cond = actx_it->conditions(); for (const auto& z_data : actx_cond) { // item [0 - 1] = 0 (unknown) sAcn[ind + 0] = 0.; sAcn[ind + 1] = 0.; - //item [2, 5, 7, 9]: value of condition 1 (zero if well, group or field variable + const std::string& lhsQtype = z_data.lhs.quantity.substr(0,1); const std::string& rhsQtype = z_data.rhs.quantity.substr(0,1); + + //item [2, 5, 7, 9]: value of condition 1 (zero if well, group or field variable const auto& it_rhsq = rhsQuantityToIndex.find(rhsQtype); if (it_rhsq == rhsQuantityToIndex.end()) { //come here if constant value condition double t_val = 0.; - if (rhsQtype == "M") { + if (lhsQtype == "M") { const auto& it_mnth = monthToNo.find(z_data.rhs.quantity); if (it_mnth != monthToNo.end()) { t_val = it_mnth->second; } else { std::cout << "Unknown Month: " << z_data.rhs.quantity << std::endl; - throw std::invalid_argument("Actionx: " + actx.name() + " Condition: " + z_data.lhs.quantity ); + throw std::invalid_argument("Actionx: " + actx_it->name() + " Condition: " + z_data.lhs.quantity ); } } else { @@ -470,39 +535,33 @@ namespace { sAcn[ind + 7] = sAcn[ind + 2]; sAcn[ind + 9] = sAcn[ind + 2]; } - //Treat well, group and field right hand side conditions + + + //Treat well, group and field right hand side conditions if (it_rhsq != rhsQuantityToIndex.end()) { //Well variable - if (it_rhsq->first == "W") { - sAcn[ind + 4] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); + if ((it_rhsq->first == "W") && (st.has_well_var(z_data.rhs.args[0], z_data.rhs.quantity))) { sAcn[ind + 5] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); - sAcn[ind + 6] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); sAcn[ind + 7] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); - sAcn[ind + 8] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); sAcn[ind + 9] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity); } //group variable - if (it_rhsq->first == "G") { - sAcn[ind + 4] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); + if ((it_rhsq->first == "G") && (st.has_group_var(z_data.rhs.args[0], z_data.rhs.quantity))) {; sAcn[ind + 5] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); - sAcn[ind + 6] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); sAcn[ind + 7] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); - sAcn[ind + 8] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); sAcn[ind + 9] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity); } //field variable - if (it_rhsq->first == "F") { - sAcn[ind + 4] = st.get(z_data.rhs.quantity); + if ((it_rhsq->first == "F") && (st.has(z_data.rhs.quantity))) { sAcn[ind + 5] = st.get(z_data.rhs.quantity); - sAcn[ind + 6] = st.get(z_data.rhs.quantity); sAcn[ind + 7] = st.get(z_data.rhs.quantity); - sAcn[ind + 8] = st.get(z_data.rhs.quantity); sAcn[ind + 9] = st.get(z_data.rhs.quantity); } } + + //treat cases with left hand side condition being: DAY, MNTH og YEAR variable - const std::string& lhsQtype = z_data.lhs.quantity.substr(0,1); const auto& it_lhsq = lhsQuantityToIndex.find(lhsQtype); if ((it_lhsq->first == "D") || (it_lhsq->first == "M") || (it_lhsq->first == "Y")) { sAcn[ind + 4] = undef_high_val; @@ -513,6 +572,41 @@ namespace { sAcn[ind + 9] = undef_high_val; } + //Treat well, group and field left hand side conditions + if (it_lhsq != lhsQuantityToIndex.end()) { + std::string wn = ""; + //Well variable + if (it_lhsq->first == "W") { + //find the well that violates action if relevant + for (const auto& well : wells) + { + if (ar.has_well(well.name())) { + //set well name + wn = well.name(); + break; + } + } + + if ((it_lhsq->first == "W") && (st.has_well_var(wn, z_data.lhs.quantity)) ) { + sAcn[ind + 4] = st.get_well_var(wn, z_data.lhs.quantity); + sAcn[ind + 6] = st.get_well_var(wn, z_data.lhs.quantity); + sAcn[ind + 8] = st.get_well_var(wn, z_data.lhs.quantity); + } + } + //group variable + if ((it_lhsq->first == "G") && (st.has_group_var(z_data.lhs.args[0], z_data.lhs.quantity))) { + sAcn[ind + 4] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity); + sAcn[ind + 6] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity); + sAcn[ind + 8] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity); + } + //field variable + if ((it_lhsq->first == "F") && (st.has(z_data.lhs.quantity))) { + sAcn[ind + 4] = st.get(z_data.lhs.quantity); + sAcn[ind + 6] = st.get(z_data.lhs.quantity); + sAcn[ind + 8] = st.get(z_data.lhs.quantity); + } + } + //increment index according to no of items pr condition ind += static_cast(noEPZacn); } @@ -520,7 +614,7 @@ namespace { } // sAcn - +} // ===================================================================== Opm::RestartIO::Helpers::AggregateActionxData:: @@ -543,7 +637,7 @@ captureDeclaredActionxData( const Opm::Schedule& sched, const std::vector& actDims, const std::size_t simStep) { - auto acts = sched.actions(simStep); + const auto acts = sched.actions(simStep); std::size_t act_ind = 0; for (auto actx_it = acts.begin(); actx_it < acts.end(); actx_it++) { { @@ -578,7 +672,7 @@ captureDeclaredActionxData( const Opm::Schedule& sched, { auto s_acn = this->sACN_[act_ind]; - sACN::staticContrib(*actx_it, st, s_acn); + sACN::staticContrib(actx_it, st, sched, simStep, s_acn); } act_ind +=1; diff --git a/src/opm/output/eclipse/AggregateConnectionData.cpp b/src/opm/output/eclipse/AggregateConnectionData.cpp index 3a5731e7e..5a39edc5c 100755 --- a/src/opm/output/eclipse/AggregateConnectionData.cpp +++ b/src/opm/output/eclipse/AggregateConnectionData.cpp @@ -191,6 +191,7 @@ namespace { sConn[Ix::item30] = -1.0e+20f; sConn[Ix::item31] = -1.0e+20f; + sConn[Ix::item41] = (conn.CF() > 0) ? 1 : 0; } } // SConn diff --git a/src/opm/output/eclipse/AggregateGroupData.cpp b/src/opm/output/eclipse/AggregateGroupData.cpp index 4b61a22d3..b3ab34b8f 100644 --- a/src/opm/output/eclipse/AggregateGroupData.cpp +++ b/src/opm/output/eclipse/AggregateGroupData.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -123,12 +124,14 @@ allocate(const std::vector& inteHead) } template -void staticContrib(const Opm::Schedule& sched, - const Opm::Group& group, - const int nwgmax, - const int ngmaxz, - const std::size_t simStep, - IGrpArray& iGrp) +void staticContrib(const Opm::Schedule& sched, + const Opm::Group& group, + const int nwgmax, + const int ngmaxz, + const std::size_t simStep, + const Opm::SummaryState& sumState, + const std::map cmodeToNum, + IGrpArray& iGrp) { if (group.wellgroup()) { int igrpCount = 0; @@ -151,6 +154,88 @@ void staticContrib(const Opm::Schedule& sched, //assign the number of child wells or child groups to // location nwgmax iGrp[nwgmax] = groupSize(group); + + /*IGRP[NWGMAX + 5] + = -1 group under higher group control + = 0 for NONE (no control) + = 1 group under rate control + */ + + if ((group.getGroupType() == Opm::Group::GroupType::NONE) || (group.getGroupType() == Opm::Group::GroupType::PRODUCTION) ) { + const auto& prod_cmode = group.production_cmode(); + std::cout << "IGRP[nwgmax + 5] group.name()" << group.name() << " prod_cmode " << static_cast(prod_cmode) << std::endl; + + if (prod_cmode == Opm::Group::ProductionCMode::FLD) { + iGrp[nwgmax + 5] = -1; + } + else if (prod_cmode == Opm::Group::ProductionCMode::NONE) { + iGrp[nwgmax + 5] = 0; + } + else { + iGrp[nwgmax + 5] = 1; + } + + // Set iGrp for [nwgmax + 7] + /* + = 0 for group with "FLD" or "NONE" + = 4 for "GRAT" FIELD + = -40000 for production group with "ORAT" + = -4000 for production group with "WRAT" + = -400 for production group with "GRAT" + = -40 for production group with "LRAT" + */ + + if ((prod_cmode == Opm::Group::ProductionCMode::NONE) || prod_cmode == Opm::Group::ProductionCMode::FLD) { + iGrp[nwgmax + 7] = 0; + } + else if ((prod_cmode == Opm::Group::ProductionCMode::ORAT)) { + iGrp[nwgmax + 7] = -40000; + } + else if ((prod_cmode == Opm::Group::ProductionCMode::WRAT)) { + iGrp[nwgmax + 7] = -4000; + } + else if ((prod_cmode == Opm::Group::ProductionCMode::GRAT)) { + iGrp[nwgmax + 7] = -400; + if (group.name() == "FIELD") { + iGrp[nwgmax + 7] = 4; + } + } + else if ((prod_cmode == Opm::Group::ProductionCMode::LRAT)) { + iGrp[nwgmax + 7] = -40; + } + } + //Set injection group status + //item[nwgmax + 16] - mode for operation for injection group + // 1 - RATE + // 2 - RESV + // 3 - REIN + // 4 - VREP + // 0 - ellers + + if (group.isInjectionGroup()) { + const auto& inj_cntl = group.injectionControls(sumState); + const auto& inj_mode = inj_cntl.cmode; + const auto& phs = inj_cntl.phase; + //Gas injection control + if (phs == Opm::Phase::WATER) { + const auto it = cmodeToNum.find(inj_mode); + if (it != cmodeToNum.end()) { + iGrp[nwgmax + 16] = it->second; + iGrp[nwgmax + 18] = iGrp[nwgmax + 16]; + iGrp[nwgmax + 19] = iGrp[nwgmax + 16]; + } + } + //Water injection control + else if (phs == Opm::Phase::GAS) { + const auto it = cmodeToNum.find(inj_mode); + if (it != cmodeToNum.end()) { + iGrp[nwgmax + 21] = it->second; + iGrp[nwgmax + 23] = iGrp[nwgmax + 21]; + iGrp[nwgmax + 24] = iGrp[nwgmax + 21]; + } + } + } + iGrp[nwgmax + 26] = groupType(group); //find group level ("FIELD" is level 0) and store the level in @@ -161,7 +246,7 @@ void staticContrib(const Opm::Schedule& sched, // if (group.name() != "FIELD") { - iGrp[nwgmax+ 5] = -1; + //iGrp[nwgmax+ 5] = -1; iGrp[nwgmax+12] = -1; iGrp[nwgmax+17] = -1; iGrp[nwgmax+22] = -1; @@ -192,6 +277,7 @@ void staticContrib(const Opm::Schedule& sched, else iGrp[nwgmax+28] = parent_group.insert_index(); } + } } // Igrp @@ -214,8 +300,15 @@ allocate(const std::vector& inteHead) } template -void staticContrib(SGrpArray& sGrp) +void staticContrib(const Opm::Group& group, + const Opm::SummaryState& sumState, + const Opm::UnitSystem& units, + SGrpArray& sGrp) { + using Isp = ::Opm::RestartIO::Helpers::VectorItems::SGroup::prod_index; + using Isi = ::Opm::RestartIO::Helpers::VectorItems::SGroup::inj_index; + using M = ::Opm::UnitSystem::measure; + const auto dflt = -1.0e+20f; const auto dflt_2 = -2.0e+20f; const auto infty = 1.0e+20f; @@ -256,6 +349,67 @@ void staticContrib(SGrpArray& sGrp) auto e = b + std::min(init.size(), sz); std::copy(b, e, std::begin(sGrp)); + + auto sgprop = [&units](const M u, const double x) -> float + { + return static_cast(units.from_si(u, x)); + }; + + if (group.isProductionGroup()) { + const auto& prod_cntl = group.productionControls(sumState); + + if (prod_cntl.oil_target > 0.) { + sGrp[Isp::OilRateLimit] = sgprop(M::liquid_surface_rate, prod_cntl.oil_target); + sGrp[37] = sGrp[Isp::OilRateLimit]; + sGrp[52] = sGrp[Isp::OilRateLimit]; // "ORAT" control + } + if (prod_cntl.water_target > 0.) { + sGrp[Isp::WatRateLimit > 0.] = sgprop(M::liquid_surface_rate, prod_cntl.water_target); + sGrp[38] = sGrp[Isp::WatRateLimit]; + sGrp[53] = sGrp[Isp::WatRateLimit]; //"WRAT" control + } + if (prod_cntl.gas_target > 0.) { + sGrp[Isp::GasRateLimit] = sgprop(M::gas_surface_rate, prod_cntl.gas_target); + sGrp[39] = sGrp[Isp::GasRateLimit]; + } + if (prod_cntl.liquid_target > 0.) { + sGrp[Isp::LiqRateLimit] = sgprop(M::liquid_surface_rate, prod_cntl.liquid_target); + sGrp[40] = sGrp[Isp::LiqRateLimit]; + } + } + + if (group.isInjectionGroup()) { + const auto& inj_cntl = group.injectionControls(sumState); + const auto& phs = inj_cntl.phase; + if (phs == Opm::Phase::GAS) { + if (inj_cntl.surface_max_rate > 0.) { + sGrp[Isi::gasSurfRateLimit] = sgprop(M::gas_surface_rate, inj_cntl.surface_max_rate); + } + if (inj_cntl.resv_max_rate > 0.) { + sGrp[Isi::gasResRateLimit > 0.] = sgprop(M::rate, inj_cntl.resv_max_rate); + } + if (inj_cntl.target_reinj_fraction > 0.) { + sGrp[Isi::gasReinjectionLimit] = inj_cntl.target_reinj_fraction; + } + if (inj_cntl.target_void_fraction > 0.) { + sGrp[Isi::gasVoidageLimit] = inj_cntl.target_void_fraction; + } + } + if (phs == Opm::Phase::WATER) { + if (inj_cntl.surface_max_rate > 0.) { + sGrp[Isi::waterSurfRateLimit] = sgprop(M::liquid_surface_rate, inj_cntl.surface_max_rate); + } + if (inj_cntl.resv_max_rate > 0.) { + sGrp[Isi::waterResRateLimit > 0.] = sgprop(M::rate, inj_cntl.resv_max_rate); + } + if (inj_cntl.target_reinj_fraction > 0.) { + sGrp[Isi::waterReinjectionLimit] = inj_cntl.target_reinj_fraction; + } + if (inj_cntl.target_void_fraction > 0.) { + sGrp[Isi::waterVoidageLimit] = inj_cntl.target_void_fraction; + } + } + } } } // SGrp @@ -355,6 +509,7 @@ AggregateGroupData(const std::vector& inteHead) void Opm::RestartIO::Helpers::AggregateGroupData:: captureDeclaredGroupData(const Opm::Schedule& sched, + const Opm::UnitSystem& units, const std::size_t simStep, const Opm::SummaryState& sumState, const std::vector& inteHead) @@ -367,21 +522,21 @@ captureDeclaredGroupData(const Opm::Schedule& sched, curGroups[ind] = std::addressof(group); } - groupLoop(curGroups, [&sched, simStep, this] + groupLoop(curGroups, [&sched, simStep, sumState, this] (const Group& group, const std::size_t groupID) -> void { auto ig = this->iGroup_[groupID]; IGrp::staticContrib(sched, group, this->nWGMax_, this->nGMaxz_, - simStep, ig); + simStep, sumState, this->cmodeToNum, ig); }); // Define Static Contributions to SGrp Array. groupLoop(curGroups, - [this](const Group& /* group */, const std::size_t groupID) -> void + [&sumState, &units, this](const Group& group , const std::size_t groupID) -> void { auto sw = this->sGroup_[groupID]; - SGrp::staticContrib(sw); + SGrp::staticContrib(group, sumState, units, sw); }); // Define Dynamic Contributions to XGrp Array. diff --git a/src/opm/output/eclipse/AggregateMSWData.cpp b/src/opm/output/eclipse/AggregateMSWData.cpp index 344021200..c6041170e 100644 --- a/src/opm/output/eclipse/AggregateMSWData.cpp +++ b/src/opm/output/eclipse/AggregateMSWData.cpp @@ -30,7 +30,7 @@ #include #include #include - +#include #include #include @@ -418,21 +418,24 @@ namespace { const std::size_t baseIndex, ISegArray& iSeg) { - namespace ISegValue = ::Opm::RestartIO::Helpers:: - VectorItems::ISeg::Value; + + using IsTyp = ::Opm::RestartIO::Helpers:: + VectorItems::ISeg::Value::SegmentType; + using IsStatus = ::Opm::RestartIO::Helpers:: + VectorItems::ISeg::Value::SICDStatus; using Ix = ::Opm::RestartIO::Helpers:: VectorItems::ISeg::index; const auto& sicd = segment.spiralICD(); - iSeg[baseIndex + Ix::SegmentType] = ISegValue::SegmentType::SICD; + iSeg[baseIndex + Ix::SegmentType] = IsTyp::SICD; iSeg[baseIndex + Ix::ICDScalingMode] = sicd->methodFlowScaling(); iSeg[baseIndex + Ix::ICDOpenShutFlag] = (sicd->status() == Opm::SpiralICD::Status::OPEN) - ? ISegValue::SICDStatus::Open - : ISegValue::SICDStatus::Shut; + ? IsStatus::Open + : IsStatus::Shut; } template @@ -467,6 +470,11 @@ namespace { const std::vector& inteHead, ISegArray& iSeg) { + using IsTyp = ::Opm::RestartIO::Helpers:: + VectorItems::ISeg::Value::SegmentType; + using Ix = ::Opm::RestartIO::Helpers:: + VectorItems::ISeg::index; + if (well.isMultiSegment()) { //loop over segment set and print out information const auto& welSegSet = well.getSegments(); @@ -474,6 +482,12 @@ namespace { const auto& noElmSeg = nisegz(inteHead); std::size_t segmentInd = 0; auto orderedSegmentNo = segmentOrder(welSegSet, segmentInd); + std::vector seg_reorder (welSegSet.size(),0); + for (int ind = 0; ind < welSegSet.size(); ind++ ){ + const auto s_no = welSegSet[orderedSegmentNo[ind]].segmentNumber(); + const auto s_ind = welSegSet.segmentNumberToIndex(s_no); + seg_reorder[s_ind] = ind+1; + } for (int ind = 0; ind < welSegSet.size(); ind++) { const auto& segment = welSegSet[ind]; @@ -487,11 +501,14 @@ namespace { iSeg[iS + 5] = sumNoInFlowBranches(welSegSet, ind); iSeg[iS + 6] = noConnectionsSegment(completionSet, welSegSet, ind); iSeg[iS + 7] = sumConnectionsSegment(completionSet, welSegSet, ind); - iSeg[iS + 8] = iSeg[iS+0]; + iSeg[iS + 8] = seg_reorder[ind]; if (! isRegular(segment)) { assignSegmentTypeCharacteristics(segment, iS, iSeg); } + else if (segment.segmentType() == Opm::Segment::SegmentType::REGULAR) { + iSeg[iS + Ix::SegmentType] = IsTyp::REGULAR; + } } } else { diff --git a/src/opm/output/eclipse/AggregateUDQData.cpp b/src/opm/output/eclipse/AggregateUDQData.cpp index f547dfffd..9f1053116 100644 --- a/src/opm/output/eclipse/AggregateUDQData.cpp +++ b/src/opm/output/eclipse/AggregateUDQData.cpp @@ -17,9 +17,12 @@ along with OPM. If not, see . */ +#include #include #include #include +#include +#include #include #include @@ -46,7 +49,7 @@ // Class Opm::RestartIO::Helpers::AggregateGroupData // --------------------------------------------------------------------- - +namespace VI = ::Opm::RestartIO::Helpers::VectorItems; namespace { // maximum number of groups @@ -56,12 +59,36 @@ namespace { } // maximum number of wells - /*std::size_t nwmaxz(const std::vector& inteHead) + std::size_t nwmaxz(const std::vector& inteHead) { return inteHead[163]; - }*/ + } + // Categorize function in terms of which token-types are used in formula + int define_type(const std::set tokens) { + int type = -4; + std::vector type_1 = { + Opm::UDQTokenType::elemental_func_sorta, + Opm::UDQTokenType::elemental_func_sortd, + Opm::UDQTokenType::elemental_func_undef, + Opm::UDQTokenType::scalar_func_sum, + Opm::UDQTokenType::scalar_func_avea, + Opm::UDQTokenType::scalar_func_aveg, + Opm::UDQTokenType::scalar_func_aveh, + Opm::UDQTokenType::scalar_func_max, + Opm::UDQTokenType::scalar_func_min, + Opm::UDQTokenType::binary_op_div + }; + + int num_type_1 = 0; + for (const auto& tok_type : type_1) { + num_type_1 += tokens.count(tok_type); + } + type = (num_type_1 > 0) ? -1 : -4; + return type; + } + namespace iUdq { @@ -80,8 +107,10 @@ namespace { void staticContrib(const Opm::UDQInput& udq_input, IUDQArray& iUdq) { if (udq_input.is()) { + const auto& udq_define = udq_input.get(); + const auto& tokens = udq_define.func_tokens(); iUdq[0] = 2; - iUdq[1] = -4; + iUdq[1] = define_type(tokens); } else { iUdq[0] = 0; iUdq[1] = -4; @@ -442,6 +471,8 @@ captureDeclaredUDQData(const Opm::Schedule& sched, const std::vector& inteHead) { const auto& udqCfg = sched.getUDQConfig(simStep); + const auto nudq = inteHead[VI::intehead::NO_WELL_UDQS] + inteHead[VI::intehead::NO_GROUP_UDQS] + inteHead[VI::intehead::NO_FIELD_UDQS]; + int cnt_udq = 0; for (const auto& udq_input : udqCfg.input()) { auto udq_index = udq_input.index.insert_index; { @@ -456,66 +487,119 @@ captureDeclaredUDQData(const Opm::Schedule& sched, auto z_udl = this->zUDL_[udq_index]; zUdl::staticContrib(udq_input, z_udl); } + cnt_udq += 1; } - + if (cnt_udq != nudq) { + std::stringstream str; + str << "Inconsistent total number of udqs: " << cnt_udq << " and sum of well, group and field udqs: " << nudq; + OpmLog::error(str.str()); + } + + auto udq_active = sched.udqActive(simStep); if (udq_active) { const auto& udq_records = udq_active.get_iuad(); + int cnt_iuad = 0; for (std::size_t index = 0; index < udq_records.size(); index++) { const auto& record = udq_records[index]; auto i_uad = this->iUAD_[index]; iUad::staticContrib(record, i_uad); + cnt_iuad += 1; + } + if (cnt_iuad != inteHead[VI::intehead::NO_IUADS]) { + std::stringstream str; + str << "Inconsistent number of iuad's: " << cnt_iuad << " number of iuad's from intehead " << inteHead[VI::intehead::NO_IUADS]; + OpmLog::error(str.str()); } const auto& iuap_records = udq_active.get_iuap(); + int cnt_iuap = 0; const auto iuap_vect = iuap_data(sched, simStep,iuap_records); for (std::size_t index = 0; index < iuap_vect.size(); index++) { const auto& wg_no = iuap_vect[index]; auto i_uap = this->iUAP_[index]; iUap::staticContrib(wg_no, i_uap); + cnt_iuap += 1; + } + if (cnt_iuap != inteHead[VI::intehead::NO_IUAPS]) { + std::stringstream str; + str << "Inconsistent number of iuap's: " << cnt_iuap << " number of iuap's from intehead " << inteHead[VI::intehead::NO_IUAPS]; + OpmLog::error(str.str()); } + } - Opm::RestartIO::Helpers::igphData igph_dat; - auto igph = igph_dat.ig_phase(sched, simStep, inteHead); - for (std::size_t index = 0; index < igph.size(); index++) { - auto i_igph = this->iGPH_[index]; - iGph::staticContrib(igph[index], i_igph); + if (inteHead[VI::intehead::NO_GROUP_UDQS] > 0) { + Opm::RestartIO::Helpers::igphData igph_dat; + int cnt_igph = 0; + auto igph = igph_dat.ig_phase(sched, simStep, inteHead); + for (std::size_t index = 0; index < igph.size(); index++) { + auto i_igph = this->iGPH_[index]; + iGph::staticContrib(igph[index], i_igph); + cnt_igph += 1; } -#if 0 + if (cnt_igph != inteHead[VI::intehead::NGMAXZ]) { + std::stringstream str; + str << "Inconsistent number of igph's: " << cnt_igph << " number of igph's from intehead " << inteHead[VI::intehead::NGMAXZ]; + OpmLog::error(str.str()); + } + } + std::size_t i_wudq = 0; const auto& wnames = sched.wellNames(simStep); const auto nwmax = nwmaxz(inteHead); + int cnt_dudw = 0; for (const auto& udq_input : udqCfg.input()) { if (udq_input.var_type() == UDQVarType::WELL_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudw = this->dUDW_[i_wudq]; dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw); i_wudq++; + cnt_dudw += 1; } } -#endif + if (cnt_dudw != inteHead[VI::intehead::NO_WELL_UDQS]) { + std::stringstream str; + str << "Inconsistent number of dudw's: " << cnt_dudw << " number of dudw's from intehead " << inteHead[VI::intehead::NO_WELL_UDQS]; + OpmLog::error(str.str()); + } + std::size_t i_gudq = 0; const auto curGroups = currentGroups(sched, simStep, inteHead); const auto ngmax = ngmaxz(inteHead); + int cnt_dudg = 0; for (const auto& udq_input : udqCfg.input()) { if (udq_input.var_type() == UDQVarType::GROUP_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudg = this->dUDG_[i_gudq]; dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg); i_gudq++; + cnt_dudg += 1; } } + if (cnt_dudg != inteHead[VI::intehead::NO_GROUP_UDQS]) { + std::stringstream str; + str << "Inconsistent number of dudg's: " << cnt_dudg << " number of dudg's from intehead " << inteHead[VI::intehead::NO_GROUP_UDQS]; + OpmLog::error(str.str()); + } std::size_t i_fudq = 0; + int cnt_dudf = 0; for (const auto& udq_input : udqCfg.input()) { if (udq_input.var_type() == UDQVarType::FIELD_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudf = this->dUDF_[i_fudq]; dUdf::staticContrib(st, udq, i_dudf); i_fudq++; + cnt_dudf += 1; } } + if (cnt_dudf != inteHead[VI::intehead::NO_FIELD_UDQS]) { + std::stringstream str; + str << "Inconsistent number of dudf's: " << cnt_dudf << " number of dudf's from intehead " << inteHead[VI::intehead::NO_FIELD_UDQS]; + OpmLog::error(str.str()); + } + } diff --git a/src/opm/output/eclipse/AggregateWellData.cpp b/src/opm/output/eclipse/AggregateWellData.cpp index cbb325afc..7acc47d71 100644 --- a/src/opm/output/eclipse/AggregateWellData.cpp +++ b/src/opm/output/eclipse/AggregateWellData.cpp @@ -31,6 +31,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -72,6 +77,9 @@ namespace { // Remove leading/trailing blanks. return s.substr(b, e - b + 1); } + + + template void wellLoop(const std::vector& wells, @@ -407,11 +415,11 @@ namespace { zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2) infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3) one , zero , zero , zero , zero , zero , // 24.. 29 ( 4) - zero , one , zero , zero, zero , zero , // 30.. 35 ( 5) + zero , one , zero , infty, zero , zero , // 30.. 35 ( 5) zero , zero , zero , zero , zero , zero , // 36.. 41 ( 6) zero , zero , zero , zero , zero , zero , // 42.. 47 ( 7) zero , zero , zero , zero , zero , zero , // 48.. 53 ( 8) - zero, zero , zero , zero , zero , zero , // 54.. 59 ( 9) + infty, zero , zero , zero , zero , zero , // 54.. 59 ( 9) zero , zero , zero , zero , zero , zero , // 60.. 65 (10) zero , zero , zero , zero , zero , zero , // 66.. 71 (11) zero , zero , zero , zero , zero , zero , // 72.. 77 (12) @@ -460,28 +468,28 @@ namespace { const auto& pc = well.productionControls(smry); const auto& predMode = well.predictionMode(); - if ((pc.oil_rate != 0.0) || (!predMode)) { + if (pc.oil_rate != 0.0) { sWell[Ix::OilRateTarget] = swprop(M::liquid_surface_rate, pc.oil_rate); } - if ((pc.water_rate != 0.0) || (!predMode)) { + if (pc.water_rate != 0.0) { sWell[Ix::WatRateTarget] = swprop(M::liquid_surface_rate, pc.water_rate); } - if ((pc.gas_rate != 0.0) || (!predMode)) { + if (pc.gas_rate != 0.0) { sWell[Ix::GasRateTarget] = swprop(M::gas_surface_rate, pc.gas_rate); sWell[Ix::HistGasRateTarget] = sWell[Ix::GasRateTarget]; } - if (pc.liquid_rate != 0.0 || (!predMode)) { + if (pc.liquid_rate != 0.0) { // check if this works - may need to be rewritten sWell[Ix::LiqRateTarget] = swprop(M::liquid_surface_rate, pc.liquid_rate); sWell[Ix::HistLiqRateTarget] = sWell[Ix::LiqRateTarget]; } - else { + else if (!predMode) { sWell[Ix::LiqRateTarget] = swprop(M::liquid_surface_rate, pc.oil_rate + pc.water_rate); } @@ -761,12 +769,31 @@ namespace { }; } + Opm::RestartIO::Helpers::ActionResStatus + act_res_stat(const Opm::Schedule& sched, const Opm::SummaryState& smry, const std::size_t sim_step) { + std::vector act_res; + std::vector act_name; + const auto acts = sched.actions(sim_step); + Opm::Action::Context context(smry); + auto sim_time = sched.simTime(sim_step); + for (const auto& action : acts.pending(sim_time)) { + act_res.push_back(action->eval(sim_time, context)); + act_name.push_back(action->name()); + } + return {act_res, act_name}; + } + template - void staticContrib(const Opm::Well& well, ZWellArray& zWell) + void staticContrib(const Opm::Well& well, const Opm::RestartIO::Helpers::ActionResStatus& actResStat, ZWellArray& zWell) { using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index; - zWell[Ix::WellName] = well.name(); + //loop over actions to assign action name for relevant wells + for (std::size_t ind = 0; ind < actResStat.result.size(); ind++) { + if (actResStat.result[ind].has_well(well.name())) { + zWell[Ix::ActionX] = actResStat.name[ind]; + } + } } } // ZWell } // Anonymous @@ -828,14 +855,16 @@ captureDeclaredWellData(const Schedule& sched, XWell::staticContrib(well, smry, units, xw); }); - // Static contributions to ZWEL array. - wellLoop(wells, - [this](const Well& well, const std::size_t wellID) -> void { - auto zw = this->zWell_[wellID]; - - ZWell::staticContrib(well, zw); - }); + const auto actResStat = ZWell::act_res_stat(sched, smry, sim_step); + // Static contributions to ZWEL array. + wellLoop(wells, + [&actResStat, this](const Well& well, const std::size_t wellID) -> void + { + auto zw = this->zWell_[wellID]; + ZWell::staticContrib(well, actResStat, zw); + }); + } } // --------------------------------------------------------------------- diff --git a/src/opm/output/eclipse/CreateDoubHead.cpp b/src/opm/output/eclipse/CreateDoubHead.cpp index 121ffb432..80f9eaf91 100755 --- a/src/opm/output/eclipse/CreateDoubHead.cpp +++ b/src/opm/output/eclipse/CreateDoubHead.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -67,6 +68,45 @@ namespace { return static_cast(Opm::Metric::Time); } + + + Opm::RestartIO::DoubHEAD::guideRate + computeGuideRate(const ::Opm::Schedule& sched, + const std::size_t lookup_step) + { + double a = 0.; + double b = 0.; + double c = 0.; + double d = 0.; + double e = 0.; + double f = 0.; + double delay = 0.; + double damping_fact = 0.; + + const auto& guideCFG = sched.guideRateConfig(lookup_step); + if (guideCFG.has_model()) { + const auto& guideRateModel = guideCFG.model(); + + a = guideRateModel.getA(); + b = guideRateModel.getB(); + c = guideRateModel.getC(); + d = guideRateModel.getD(); + e = guideRateModel.getE(); + f = guideRateModel.getF(); + delay = guideRateModel.update_delay(); + damping_fact = guideRateModel.damping_factor(); + } + return { + a, + b, + c, + d, + e, + f, + delay, + damping_fact + }; + } } // Anonymous // ##################################################################### @@ -82,14 +122,15 @@ createDoubHead(const EclipseState& es, const double nextTimeStep) { const auto& usys = es.getDeckUnitSystem(); - //const auto& rspec = es.runspec(); + const auto& rspec = es.runspec(); const auto tconv = getTimeConv(usys); auto dh = DoubHEAD{} .tuningParameters(sched.getTuning(), lookup_step, tconv) .timeStamp (computeTimeStamp(sched, simTime)) .drsdt (sched, lookup_step, tconv) - //.udq_param(rspec.udqParams()) + .udq_param(rspec.udqParams()) + .guide_rate_param(computeGuideRate(sched, lookup_step)) ; if (nextTimeStep > 0.0) { diff --git a/src/opm/output/eclipse/CreateInteHead.cpp b/src/opm/output/eclipse/CreateInteHead.cpp index e81cc0929..d9cf1c18a 100755 --- a/src/opm/output/eclipse/CreateInteHead.cpp +++ b/src/opm/output/eclipse/CreateInteHead.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,17 @@ #include namespace { + + using nph_enum = Opm::GuideRateModel::Target; + const std::map nph_enumToECL = { + {nph_enum::NONE, 0}, + {nph_enum::OIL, 1}, + {nph_enum::GAS, 3}, + {nph_enum::LIQ, 4}, + {nph_enum::RES, 6}, + {nph_enum::COMB, 9}, + }; + int maxConnPerWell(const Opm::Schedule& sched, const std::size_t lookup_step) { @@ -71,6 +83,65 @@ namespace { // Number of non-FIELD groups. return ngmax - 1; } + + int GroupControl(const Opm::Schedule& sched, + const std::size_t lookup_step) + { + int gctrl = 0; + + for (const auto& group_name : sched.groupNames(lookup_step)) { + const auto& group = sched.getGroup(group_name, lookup_step); + if (group.isProductionGroup()) { + std::cout << "CrIH group.name()" << group.name() << " group.production_cmode() " << static_cast(group.production_cmode()) << std::endl; + gctrl = 1; + } + if (group.isInjectionGroup()) { + std::cout << "CrIH group.name()" << group.name() << " group.injection_cmode() " << static_cast(group.injection_cmode()) << std::endl; + gctrl = 2; + } + } + + // Index for group control + return gctrl; + } + + + int noWellUdqs(const Opm::Schedule& sched, + const std::size_t simStep) + { + const auto& udqCfg = sched.getUDQConfig(simStep); + std::size_t i_wudq = 0; + for (const auto& udq_input : udqCfg.input()) { + if (udq_input.var_type() == Opm::UDQVarType::WELL_VAR) { + i_wudq++; + } + } + return i_wudq; + } + + + int noGroupUdqs(const Opm::Schedule& sched, + const std::size_t simStep) + { + const auto& udqCfg = sched.getUDQConfig(simStep); + const auto& input = udqCfg.input(); + return std::count_if(input.begin(), input.end(), [](const Opm::UDQInput inp) { return (inp.var_type() == Opm::UDQVarType::GROUP_VAR); }); + + } + + int noFieldUdqs(const Opm::Schedule& sched, + const std::size_t simStep) + { + const auto& udqCfg = sched.getUDQConfig(simStep); + std::size_t i_fudq = 0; + for (const auto& udq_input : udqCfg.input()) { + if (udq_input.var_type() == Opm::UDQVarType::FIELD_VAR) { + i_fudq++; + } + } + return i_fudq; +} + Opm::RestartIO::InteHEAD::WellTableDim getWellTableDims(const int nwgmax, @@ -189,14 +260,22 @@ namespace { }; } - /*Opm::RestartIO::InteHEAD::UdqParam - getUdqParam(const ::Opm::Runspec& rspec, const ::Opm::UDQConfig& udqcfg ) + + Opm::RestartIO::InteHEAD::UdqParam + getUdqParam(const ::Opm::Runspec& rspec, const Opm::Schedule& sched, + const std::size_t simStep ) { const auto& udq_par = rspec.udqParams(); - const auto r_seed = udq_par.rand_seed(); - const auto no_udq = udqcfg.size(); - - return { r_seed, static_cast(no_udq)}; + const auto& udqActive = sched.udqActive(simStep); + const auto r_seed = udq_par.rand_seed(); + const auto no_wudq = noWellUdqs(sched, simStep); + const auto no_gudq = noGroupUdqs(sched, simStep); + const auto no_fudq = noFieldUdqs(sched, simStep); + const auto no_iuads = udqActive.IUAD_size(); + const auto no_iuaps = udqActive.IUAP_size(); + + return { r_seed, static_cast(no_wudq), static_cast(no_gudq), static_cast(no_fudq), + static_cast(no_iuads), static_cast(no_iuaps)}; } Opm::RestartIO::InteHEAD::ActionParam @@ -208,7 +287,7 @@ namespace { const auto max_characters_per_line = rspec.actdims().max_characters(); return { static_cast(no_act), max_lines_pr_action, static_cast(max_cond_per_action), static_cast(max_characters_per_line)}; - }*/ + } Opm::RestartIO::InteHEAD::WellSegDims getWellSegDims(const ::Opm::Runspec& rspec, @@ -262,6 +341,30 @@ namespace { static_cast(nplmix), }; } + + Opm::RestartIO::InteHEAD::GuideRateNominatedPhase + setGuideRateNominatedPhase(const ::Opm::Schedule& sched, + const std::size_t lookup_step) + { + int nom_phase = 0; + + const auto& guideCFG = sched.guideRateConfig(lookup_step); + if (guideCFG.has_model()) { + const auto& guideRateModel = guideCFG.model(); + + const auto& targPhase = guideRateModel.target(); + const auto& allow_incr = guideRateModel.allow_increase(); + + const auto it_nph = nph_enumToECL.find(targPhase); + if (it_nph != nph_enumToECL.end()) { + nom_phase = it_nph->second; + } + //nominated phase has negative sign for allow increment set to 'NO' + if (!allow_incr) nom_phase *= -1; + } + + return {nom_phase}; + } } // Anonymous // ##################################################################### @@ -279,8 +382,7 @@ createInteHead(const EclipseState& es, { const auto nwgmax = maxGroupSize(sched, lookup_step); const auto ngmax = numGroupsInField(sched, lookup_step); - //const auto& udqCfg = sched.getUDQConfig(lookup_step); - //const auto& acts = sched.actions(lookup_step); + const auto& acts = sched.actions(lookup_step); const auto& rspec = es.runspec(); const auto& tdim = es.getTableManager(); const auto& rdim = tdim.getRegdims(); @@ -297,7 +399,7 @@ createInteHead(const EclipseState& es, // across a range of reference cases, but are not guaranteed to be // universally valid. .params_NWELZ (155, 122, 130, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL - .params_NCON (25, 40, 58) // n{isx}conz: number of data elements per completion in ICON + .params_NCON (25, 41, 58) // n{isx}conz: number of data elements per completion in ICON .params_GRPZ (getNGRPZ(nwgmax, ngmax, rspec)) // ncamax: max number of analytical aquifer connections // n{isx}aaqz: number of data elements per aquifer in {ISX}AAQ @@ -308,9 +410,12 @@ createInteHead(const EclipseState& es, .wellSegDimensions (getWellSegDims(rspec, sched, lookup_step)) .regionDimensions (getRegDims(tdim, rdim)) .ngroups ({ ngmax }) - .variousParam (201702, 100) // Output should be compatible with Eclipse 100, 2017.02 version. - //.udqParam_1 (getUdqParam(rspec, udqCfg)) - //.actionParam (getActionParam(rspec, acts)) + .params_NGCTRL (GroupControl(sched,lookup_step)) + .variousParam (201802, 100) // Output should be compatible with Eclipse 100, 2017.02 version. + .udqParam_1 (getUdqParam(rspec, sched, lookup_step )) + .actionParam (getActionParam(rspec, acts)) + .variousUDQ_ACTIONXParam() + .nominatedPhaseGuideRate(setGuideRateNominatedPhase(sched,lookup_step)) ; return ih.data(); diff --git a/src/opm/output/eclipse/CreateUdqDims.cpp b/src/opm/output/eclipse/CreateUdqDims.cpp index 4b46fa566..3017e4eaf 100755 --- a/src/opm/output/eclipse/CreateUdqDims.cpp +++ b/src/opm/output/eclipse/CreateUdqDims.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -39,6 +40,8 @@ #include #include +namespace VI = ::Opm::RestartIO::Helpers::VectorItems; + namespace { @@ -68,56 +71,10 @@ std::size_t entriesPerZUDL() std::size_t noIGphs(const std::vector& inteHead) { - std::size_t no_entries = inteHead[20]; + std::size_t no_entries = (inteHead[VI::intehead::NO_GROUP_UDQS] > 0) ? inteHead[20] : 0; return no_entries; } -// maximum number of wells -std::size_t nwmaxz(const std::vector& inteHead) -{ - return inteHead[163]; -} - -// maximum number of groups -std::size_t ngmaxz(const std::vector& inteHead) -{ - return inteHead[20]; -} - -int noWellUdqs(const Opm::Schedule& sched, - const std::size_t simStep) -{ - const auto& udqCfg = sched.getUDQConfig(simStep); - std::size_t i_wudq = 0; - for (const auto& udq_input : udqCfg.input()) { - if (udq_input.var_type() == Opm::UDQVarType::WELL_VAR) { - i_wudq++; - } - } - return i_wudq; -} - -int noGroupUdqs(const Opm::Schedule& sched, - const std::size_t simStep) -{ - const auto& udqCfg = sched.getUDQConfig(simStep); - const auto& input = udqCfg.input(); - return std::count_if(input.begin(), input.end(), [](const Opm::UDQInput inp) { return (inp.var_type() == Opm::UDQVarType::GROUP_VAR); }); - -} - -int noFieldUdqs(const Opm::Schedule& sched, - const std::size_t simStep) -{ - const auto& udqCfg = sched.getUDQConfig(simStep); - std::size_t i_fudq = 0; - for (const auto& udq_input : udqCfg.input()) { - if (udq_input.var_type() == Opm::UDQVarType::FIELD_VAR) { - i_fudq++; - } - } - return i_fudq; -} } // Anonymous @@ -132,23 +89,22 @@ createUdqDims(const Schedule& sched, const std::vector& inteHead) { const auto& udqCfg = sched.getUDQConfig(lookup_step); - const auto& udqActive = sched.udqActive(lookup_step); std::vector udqDims; udqDims.resize(13,0); udqDims[ 0] = udqCfg.size(); udqDims[ 1] = entriesPerIUDQ(); - udqDims[ 2] = udqActive.IUAD_size(); + udqDims[ 2] = inteHead[VI::intehead::NO_IUADS]; udqDims[ 3] = entriesPerIUAD(); udqDims[ 4] = entriesPerZUDN(); udqDims[ 5] = entriesPerZUDL(); udqDims[ 6] = noIGphs(inteHead); - udqDims[ 7] = udqActive.IUAP_size(); - udqDims[ 8] = nwmaxz(inteHead); - udqDims[ 9] = noWellUdqs(sched, lookup_step); - udqDims[10] = ngmaxz(inteHead); - udqDims[11] = noGroupUdqs(sched, lookup_step); - udqDims[12] = noFieldUdqs(sched, lookup_step); + udqDims[ 7] = inteHead[VI::intehead::NO_IUAPS]; + udqDims[ 8] = inteHead[VI::intehead::NWMAXZ]; + udqDims[ 9] = inteHead[VI::intehead::NO_WELL_UDQS]; + udqDims[10] = inteHead[VI::intehead::NGMAXZ]; + udqDims[11] = inteHead[VI::intehead::NO_GROUP_UDQS]; + udqDims[12] = inteHead[VI::intehead::NO_FIELD_UDQS]; return udqDims; } diff --git a/src/opm/output/eclipse/DoubHEAD.cpp b/src/opm/output/eclipse/DoubHEAD.cpp index 931cac014..df39aafb3 100755 --- a/src/opm/output/eclipse/DoubHEAD.cpp +++ b/src/opm/output/eclipse/DoubHEAD.cpp @@ -146,19 +146,19 @@ enum Index : std::vector::size_type { DdpLim = 84, DdsLim = 85, dh_086 = 86, - dh_087 = 87, - dh_088 = 88, - dh_089 = 89, + grpar_a = VI::doubhead::GRpar_a, + grpar_b = VI::doubhead::GRpar_b, + grpar_c = VI::doubhead::GRpar_c, // 90..99 - dh_090 = 90, - dh_091 = 91, - dh_092 = 92, + grpar_d = VI::doubhead::GRpar_d, + grpar_e = VI::doubhead::GRpar_e, + grpar_f = VI::doubhead::GRpar_f, dh_093 = 93, dh_094 = 94, dh_095 = 95, dh_096 = 96, - dh_097 = 97, + grpar_int = VI::doubhead::GRpar_int, dh_098 = 98, ThrUPT = 99, @@ -215,7 +215,7 @@ enum Index : std::vector::size_type { dh_141 = 141, dh_142 = 142, dh_143 = 143, - dh_144 = 144, + grpar_dmp = VI::doubhead::GRpar_damp, dh_145 = 145, dh_146 = 146, dh_147 = 147, @@ -396,8 +396,8 @@ Opm::RestartIO::DoubHEAD::DoubHEAD() this->data_[Index::dh_069] = -1.0; this->data_[Index::dh_080] = 1.0e+20; this->data_[Index::dh_081] = 1.0e+20; - this->data_[Index::dh_091] = 0.0; - this->data_[Index::dh_092] = 0.0; + this->data_[grpar_e] = 0.0; + this->data_[grpar_f] = 0.0; this->data_[Index::dh_093] = 0.0; this->data_[Index::dh_096] = 0.0; this->data_[Index::dh_105] = 1.0; @@ -627,3 +627,18 @@ Opm::RestartIO::DoubHEAD::udq_param(const UDQParams& udqPar) return *this; } + +Opm::RestartIO::DoubHEAD& +Opm::RestartIO::DoubHEAD::guide_rate_param(const guideRate& guide_rp) +{ + this->data_[grpar_a] = guide_rp.A; + this->data_[grpar_b] = guide_rp.B; + this->data_[grpar_c] = guide_rp.C; + this->data_[grpar_d] = guide_rp.D; + this->data_[grpar_e] = guide_rp.E; + this->data_[grpar_f] = guide_rp.F; + this->data_[grpar_int] = guide_rp.delay; + this->data_[grpar_dmp] = guide_rp.damping_fact; + + return *this; +} diff --git a/src/opm/output/eclipse/InteHEAD.cpp b/src/opm/output/eclipse/InteHEAD.cpp index 747e74b33..bc0440c3a 100644 --- a/src/opm/output/eclipse/InteHEAD.cpp +++ b/src/opm/output/eclipse/InteHEAD.cpp @@ -52,7 +52,7 @@ enum index : std::vector::size_type { ih_030 = 30 , // 0 0 ih_031 = 31 , // 0 0 NICONZ = VI::intehead::NICONZ, // 25 15 25 NICON = no of data elements per completion in ICON array (default 19) - NSCONZ = VI::intehead::NSCONZ, // 40 0 NSCONZ = number of data elements per completion in SCON array + NSCONZ = VI::intehead::NSCONZ, // 41 0 NSCONZ = number of data elements per completion in SCON array NXCONZ = VI::intehead::NXCONZ, // 58 0 58 NXCONZ = number of data elements per completion in XCON array ih_035 = 35 , // 0 0 NIGRPZ = VI::intehead::NIGRPZ, // 97+intehead_array[19] 0 97 + intehead[19] NIGRPZ = no of data elements per group in IGRP array @@ -70,14 +70,14 @@ enum index : std::vector::size_type { ih_048 = 48 , // 0 0 ih_049 = 49 , // 1 // has been determined by testing ih_050 = 50 , // 1 // has been determined by testing - ih_051 = 51 , // 0 0 + NGCONT = VI::intehead::NGCTRL, // 0 - no group control, 1 if GCONPROD, 2 if GCONINJE ih_052 = 52 , // 0 0 ih_053 = 53 , // 0 0 ih_054 = 54 , // 0 0 ih_055 = 55 , // 0 0 ih_056 = 56 , // 0 0 ih_057 = 57 , // 0 0 - ih_058 = 58 , // 0 0 + NGRNPHASE = VI::intehead::NGRNPH, // Parameter to determine the nominated phase for the guiderate ih_059 = 59 , // 0 0 ih_060 = 60 , // 0 0 ih_061 = 61 , // 0 0 @@ -281,11 +281,11 @@ enum index : std::vector::size_type { ih_259 = 259 , // 0 ih_260 = 260 , // 0 ih_261 = 261 , // 0 - ih_262 = 262 , // 0 - ih_263 = 263 , // 0 + NOFUDQS = VI::intehead::NO_FIELD_UDQS, // 0 + NOGUDQS = VI::intehead::NO_GROUP_UDQS, // 0 ih_264 = 264 , // 0 ih_265 = 265 , // 0 - NOUDQS = VI::intehead::NO_UDQS, // 0 + NOWUDQS = VI::intehead::NO_WELL_UDQS, // 0 UDQPAR_1 = VI::intehead::UDQPAR_1, // 0 ih_268 = 268 , // 0 ih_269 = 269 , // 0 @@ -309,8 +309,8 @@ enum index : std::vector::size_type { ih_287 = 287 , // 0 ih_288 = 288 , // 0 ih_289 = 289 , // 0 - ih_290 = 290 , // 0 - ih_291 = 291 , // 0 + NOIUADS = VI::intehead::NO_IUADS, // 0 + NOIUAPS = VI::intehead::NO_IUAPS, // 0 ih_292 = 292 , // 0 ih_293 = 293 , // 0 ih_294 = 294 , // 0 @@ -501,7 +501,7 @@ Opm::RestartIO::InteHEAD::wellTableDimensions(const WellTableDim& wtdim) this->data_[NGMAXZ] = wtdim.maxGroupInField + 1; - //this->data_[NWMAXZ] = wtdim.maxWellsInField; + this->data_[NWMAXZ] = wtdim.maxWellsInField; return *this; } @@ -571,6 +571,15 @@ params_GRPZ(const std::array& grpz) return *this; } +Opm::RestartIO::InteHEAD& +Opm::RestartIO::InteHEAD:: +params_NGCTRL(const int gct) +{ + this -> data_[NGCONT] = gct; + + return *this; +} + Opm::RestartIO::InteHEAD& Opm::RestartIO::InteHEAD:: params_NAAQZ(const int ncamax, @@ -682,9 +691,13 @@ Opm::RestartIO::InteHEAD& Opm::RestartIO::InteHEAD:: udqParam_1(const UdqParam& udq_par) { - this -> data_[UDQPAR_1] = - udq_par.udqParam_1; - this -> data_[R_SEED] = - udq_par.udqParam_1; - this -> data_[NOUDQS] = udq_par.no_udqs; + this -> data_[UDQPAR_1] = - udq_par.udqParam_1; + this -> data_[R_SEED] = - udq_par.udqParam_1; + this -> data_[NOWUDQS] = udq_par.no_wudqs; + this -> data_[NOGUDQS] = udq_par.no_gudqs; + this -> data_[NOFUDQS] = udq_par.no_fudqs; + this -> data_[NOIUADS] = udq_par.no_iuads; + this -> data_[NOIUAPS] = udq_par.no_iuaps; return *this; } @@ -702,6 +715,31 @@ actionParam(const ActionParam& act_par) return *this; } + +//InteHEAD parameters which meaning are currently not known, but which are needed for Eclipse restart runs with UDQ and ACTIONX data +Opm::RestartIO::InteHEAD& +Opm::RestartIO::InteHEAD:: +variousUDQ_ACTIONXParam() +{ + this -> data_[159] = 4; + this -> data_[160] = 5; + this -> data_[161] = 9; + this -> data_[246] = 26; + this -> data_[247] = 16; + this -> data_[248] = 13; + + return *this; +} + +Opm::RestartIO::InteHEAD& +Opm::RestartIO::InteHEAD:: +nominatedPhaseGuideRate(GuideRateNominatedPhase nphase) +{ + this -> data_[NGRNPHASE] = nphase.nominated_phase; + + return *this; +} + // ===================================================================== // Free functions (calendar/time utilities) // ===================================================================== diff --git a/src/opm/output/eclipse/RestartIO.cpp b/src/opm/output/eclipse/RestartIO.cpp index c3c95d2c4..d25b2c702 100644 --- a/src/opm/output/eclipse/RestartIO.cpp +++ b/src/opm/output/eclipse/RestartIO.cpp @@ -29,6 +29,8 @@ #include #include #include +#include + #include #include @@ -232,6 +234,7 @@ namespace { } void writeGroup(int sim_step, + const UnitSystem& units, const Schedule& schedule, const Opm::SummaryState& sumState, const std::vector& ih, @@ -242,7 +245,7 @@ namespace { auto groupData = Helpers::AggregateGroupData(ih); - groupData.captureDeclaredGroupData(schedule, simStep, sumState, ih); + groupData.captureDeclaredGroupData(schedule, units, simStep, sumState, ih); rstFile.write("IGRP", groupData.getIGroup()); rstFile.write("SGRP", groupData.getSGroup()); @@ -278,10 +281,6 @@ namespace { const std::vector& ih, EclIO::OutputStream::Restart& rstFile) { - //return; - //need to add test if UDQ-data exist and UDQ - active exist etc. - // do not write unless data exists and copy E100 logic. - // write UDQ - data to restart file const std::size_t simStep = static_cast (sim_step); @@ -302,6 +301,30 @@ namespace { } } + void writeActionx(int sim_step, + const EclipseState& es, + const Schedule& schedule, + const SummaryState& sum_state, + EclIO::OutputStream::Restart& rstFile) + { + // write ACTIONX - data to restart file + const std::size_t simStep = static_cast (sim_step); + + const auto actDims = Opm::RestartIO::Helpers::createActionxDims(es.runspec(), schedule, simStep); + auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); + actionxData.captureDeclaredActionxData(schedule, sum_state, actDims, simStep); + + if (actDims[0] >= 1) { + rstFile.write("IACT", actionxData.getIACT()); + rstFile.write("SACT", actionxData.getSACT()); + rstFile.write("ZACT", actionxData.getZACT()); + rstFile.write("ZLACT", actionxData.getZLACT()); + rstFile.write("ZACN", actionxData.getZACN()); + rstFile.write("IACN", actionxData.getIACN()); + rstFile.write("SACN", actionxData.getSACN()); + } + } + void writeWell(int sim_step, const bool ecl_compatible_rst, const Phases& phases, @@ -538,7 +561,7 @@ void save(EclIO::OutputStream::Restart& rstFile, writeHeader(sim_step, nextStepSize(value), seconds_elapsed, schedule, grid, es, rstFile); - writeGroup(sim_step, schedule, sumState, inteHD, rstFile); + writeGroup(sim_step, units, schedule, sumState, inteHD, rstFile); // Write well and MSW data only when applicable (i.e., when present) { @@ -563,6 +586,8 @@ void save(EclIO::OutputStream::Restart& rstFile, } } + writeActionx(sim_step, es, schedule, sumState, rstFile); + writeSolution(value, schedule, sumState, sim_step, ecl_compatible_rst, write_double, inteHD, rstFile); if (! ecl_compatible_rst) { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp index 202c6a2f4..0ba760609 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp @@ -18,6 +18,7 @@ */ #include +#include #include @@ -43,11 +44,10 @@ Result::Result(bool result_arg, const WellSet& wells) : Result::Result(const Result& src) { this->result = src.result; - if (src.matching_wells) + if (src.matching_wells) this->matching_wells.reset( new WellSet(*src.matching_wells) ); } - Result::operator bool() const { return this->result; } @@ -59,7 +59,6 @@ std::vector Result::wells() const { return {}; } - Result& Result::operator|=(const Result& other) { this->result = this->result || other.result; @@ -84,6 +83,14 @@ Result& Result::operator&=(const Result& other) { return *this; } +Result& Result::operator=(const Result& src) +{ + this->result = src.result; + if (src.matching_wells) this->matching_wells.reset( new WellSet(*src.matching_wells) ); + + return *this; +} + void Result::assign(bool value) { this->result = value; } @@ -94,7 +101,7 @@ void Result::add_well(const std::string& well) { this->matching_wells->add(well); } -bool Result::has_well(const std::string& well) { +bool Result::has_well(const std::string& well) const { if (!this->matching_wells) return false; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/Group.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/Group.cpp index 01ff008d4..faf4484e0 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Group/Group.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/Group.cpp @@ -309,6 +309,9 @@ Phase Group::injection_phase() const { return this->injection_properties.phase; } +const Group::GroupType& Group::getGroupType() const { + return this-> group_type; +} bool Group::ProductionControls::has_control(Group::ProductionCMode control) const { return (this->production_controls & static_cast(control)) != 0; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp index beb59cc2b..ad94b4a64 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp @@ -175,6 +175,30 @@ double GuideRateModel::damping_factor() const { return this->damping_factor_; } +double GuideRateModel::getA() const { + return this->A; +} + +double GuideRateModel::getB() const { + return this->B; +} + +double GuideRateModel::getC() const { + return this->C; +} + +double GuideRateModel::getD() const { + return this->D; +} + +double GuideRateModel::getE() const { + return this->E; +} + +double GuideRateModel::getF() const { + return this->F; +} + bool GuideRateModel::allow_increase() const { return this->allow_increase_; } diff --git a/tests/UDQ_ACTIONX_TEST1.DATA b/tests/UDQ_ACTIONX_TEST1.DATA index 8b5d2e1bf..8fafc22d0 100644 --- a/tests/UDQ_ACTIONX_TEST1.DATA +++ b/tests/UDQ_ACTIONX_TEST1.DATA @@ -415,7 +415,7 @@ ACTIONX ACT02 11 / FMWPR > 25 AND / WGPR 'OPL02' > GGPR 'LOWER' AND / -MNTH > MAY / +MNTH > NOV / / WELOPEN '?' 'SHUT' 0 0 0 2* / @@ -441,19 +441,12 @@ WELOPEN / ENDACTIO -WELOPEN - 'OPL01' 'OPEN' 5* / -/ -DATES - 1 'OCT' 2018 / -/ - --start files/actionxprod.tmpl ACTIONX ACT01 10 / FMWPR > 45 AND / WUPR3 'OP*' > 46 OR / -MNTH > JUN / +MNTH > OCT / / WELOPEN '?' SHUT 0 0 0 2* / @@ -466,6 +459,14 @@ WELOPEN / ENDACTIO +WELOPEN + 'OPL01' 'OPEN' 5* / +/ + +DATES + 1 'OCT' 2018 / +/ + WELOPEN 'WIL01' 'OPEN' 5* / diff --git a/tests/test_AggregateActionxData.cpp b/tests/test_AggregateActionxData.cpp index e61a30bbf..fc9e4f817 100644 --- a/tests/test_AggregateActionxData.cpp +++ b/tests/test_AggregateActionxData.cpp @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep); -#if 0 + /*rstFile.write("INTEHEAD", ih); rstFile.write("IUDQ", udqData.getIUDQ()); rstFile.write("IUAD", udqData.getIUAD()); rstFile.write("IGPH", udqData.getIGPH()); @@ -162,10 +162,8 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) rstFile.write("ZLACT", actionxData.getZLACT()); rstFile.write("ZACN", actionxData.getZACN()); rstFile.write("IACN", actionxData.getIACN()); - rstFile.write("SACN", actionxData.getSACN()); -#endif - -#if 0 + rstFile.write("SACN", actionxData.getSACN()); */ + { /* Check of InteHEAD and DoubHEAD data for UDQ variables @@ -201,8 +199,6 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) } -#endif - { /* IACT @@ -526,11 +522,11 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); BOOST_CHECK_EQUAL(sAcn[start + 2] , 17); BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 4] , 24); BOOST_CHECK_EQUAL(sAcn[start + 5] , 17); - BOOST_CHECK_EQUAL(sAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 6] , 24); BOOST_CHECK_EQUAL(sAcn[start + 7] , 17); - BOOST_CHECK_EQUAL(sAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 8] , 24); BOOST_CHECK_EQUAL(sAcn[start + 9] , 17); BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); @@ -576,12 +572,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(sAcn[start + 15] , 0); } - - - -#if 0 - -#endif + } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_AggregateActionxData_2.cpp b/tests/test_AggregateActionxData_2.cpp new file mode 100644 index 000000000..848032f59 --- /dev/null +++ b/tests/test_AggregateActionxData_2.cpp @@ -0,0 +1,564 @@ +#define BOOST_TEST_MODULE UDQ-ACTIONX_Data + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace { + + Opm::Deck first_sim(std::string fname) { + return Opm::Parser{}.parseFile(fname); + } +} + +Opm::SummaryState sum_state_TEST1() + { + auto state = Opm::SummaryState{std::chrono::system_clock::now()}; + state.update_well_var("OPU01", "WWPR", 21.); + state.update_well_var("OPU02", "WWPR", 22.); + state.update_well_var("OPL01", "WWPR", 23.); + state.update_well_var("OPL02", "WWPR", 24.); + + state.update_well_var("OPU01", "WGPR", 230.); + state.update_well_var("OPU02", "WGPR", 231.); + state.update_well_var("OPL01", "WGPR", 232.); + state.update_well_var("OPL02", "WGPR", 233.); + + state.update_group_var("UPPER", "GWPR", 36.); + state.update_group_var("LOWER", "GWPR", 37.); + state.update_group_var("TEST", "GWPR", 73.); + + state.update_group_var("UPPER", "GGPR", 460.); + state.update_group_var("LOWER", "GGPR", 461.); + state.update_group_var("TEST", "GGPR", 821.); + + + state.update_group_var("TEST", "GMWPR", 4); + + state.update("FWPR", 73.); + + state.update("FMWPR", 4); + + + return state; +} + +//int main(int argc, char* argv[]) +struct SimulationCase +{ + explicit SimulationCase(const Opm::Deck& deck) + : es { deck } + , grid { deck } + , sched{ deck, es } + {} + + // Order requirement: 'es' must be declared/initialised before 'sched'. + Opm::EclipseState es; + Opm::EclipseGrid grid; + Opm::Schedule sched; + +}; + +BOOST_AUTO_TEST_SUITE(Aggregate_Actionx) + + + +// test constructed UDQ-Actionx restart data +BOOST_AUTO_TEST_CASE (Declared_Actionx_data) +{ + const auto simCase = SimulationCase{first_sim("UDQ_ACTIONX_TEST1.DATA")}; + + Opm::EclipseState es = simCase.es; + Opm::Runspec rspec = es.runspec(); + Opm::SummaryState st = sum_state_TEST1(); + Opm::Schedule sched = simCase.sched; + Opm::EclipseGrid grid = simCase.grid; + const auto& ioConfig = es.getIOConfig(); + //const auto& restart = es.cfg().restart(); + + + // Report Step 1: 2008-10-10 --> 2011-01-20 + const auto rptStep = std::size_t{1}; + std::string outputDir = "./"; + std::string baseName = "UDQ_ACTIONX_TEST1"; + Opm::EclIO::OutputStream::Restart rstFile { + Opm::EclIO::OutputStream::ResultSet { outputDir, baseName }, + rptStep, + Opm::EclIO::OutputStream::Formatted { ioConfig.getFMTOUT() }, + Opm::EclIO::OutputStream::Unified { ioConfig.getUNIFOUT() } + }; + + double secs_elapsed = 3.1536E07; + const auto ih = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, + secs_elapsed, rptStep, rptStep); + //set dummy value for next_step_size + const double next_step_size= 0.1; + const auto dh = Opm::RestartIO::Helpers::createDoubHead(es, sched, rptStep, + secs_elapsed, next_step_size); + + const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih); + auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims); + udqData.captureDeclaredUDQData(sched, rptStep, st, ih); + + const auto actDims = Opm::RestartIO::Helpers::createActionxDims(rspec, sched, rptStep); + auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); + actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep); + + /*rstFile.write("INTEHEAD", ih); + rstFile.write("IUDQ", udqData.getIUDQ()); + rstFile.write("IUAD", udqData.getIUAD()); + rstFile.write("IGPH", udqData.getIGPH()); + rstFile.write("IUAP", udqData.getIUAP()); + rstFile.write("ZUDN", udqData.getZUDN()); + rstFile.write("ZUDL", udqData.getZUDL()); + + rstFile.write("IACT", actionxData.getIACT()); + rstFile.write("SACT", actionxData.getSACT()); + rstFile.write("ZACT", actionxData.getZACT()); + rstFile.write("ZLACT", actionxData.getZLACT()); + rstFile.write("ZACN", actionxData.getZACN()); + rstFile.write("IACN", actionxData.getIACN()); + rstFile.write("SACN", actionxData.getSACN()); */ + + { + /* + Check of InteHEAD and DoubHEAD data for UDQ variables + + INTEHEAD + + Intehead[156] - The number of ACTIONS + Intehead[157] - The max number of lines of schedule data including ENDACTIO keyword for any ACTION + + ---------------------------------------------------------------------------------------------------------------------] + + */ + const auto rptStep_1 = std::size_t{0}; + const auto ih_1 = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, + secs_elapsed, rptStep, rptStep_1); + + BOOST_CHECK_EQUAL(ih_1[156] , 2); + BOOST_CHECK_EQUAL(ih_1[157] , 7); + + + const auto rptStep_2 = std::size_t{1}; + const auto ih_2 = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, + secs_elapsed, rptStep, rptStep_2); + BOOST_CHECK_EQUAL(ih_2[156] , 3); + BOOST_CHECK_EQUAL(ih_2[157] , 7); + + const auto rptStep_3 = std::size_t{2}; + const auto ih_3 = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, + secs_elapsed, rptStep, rptStep_3); + + BOOST_CHECK_EQUAL(ih_3[156] , 3); + BOOST_CHECK_EQUAL(ih_3[157] , 10); + + } + + { + /* + IACT + --length is equal to 9*the number of ACTIONX keywords + //item [0]: is unknown, (=0) + //item [1]: The number of lines of schedule data including ENDACTIO + //item [2]: is unknown, (=1) + //item [3]: is unknown, (=7) + //item [4]: is unknown, (=0) + //item [5]: The number of times the action is triggered + //item [6]: is unknown, (=0) + //item [7]: is unknown, (=0) + //item [8]: The number of times the action is triggered + */ + + + const auto& iAct = actionxData.getIACT(); + + auto start = 0*actDims[1]; + BOOST_CHECK_EQUAL(iAct[start + 0] , 0); + BOOST_CHECK_EQUAL(iAct[start + 1] , 4); + BOOST_CHECK_EQUAL(iAct[start + 2] , 1); + BOOST_CHECK_EQUAL(iAct[start + 3] , 7); + BOOST_CHECK_EQUAL(iAct[start + 4] , 0); + BOOST_CHECK_EQUAL(iAct[start + 5] , 10); + BOOST_CHECK_EQUAL(iAct[start + 6] , 0); + BOOST_CHECK_EQUAL(iAct[start + 7] , 0); + BOOST_CHECK_EQUAL(iAct[start + 8] , 3); + + + start = 1*actDims[1]; + BOOST_CHECK_EQUAL(iAct[start + 0] , 0); + BOOST_CHECK_EQUAL(iAct[start + 1] , 7); + BOOST_CHECK_EQUAL(iAct[start + 2] , 1); + BOOST_CHECK_EQUAL(iAct[start + 3] , 7); + BOOST_CHECK_EQUAL(iAct[start + 4] , 0); + BOOST_CHECK_EQUAL(iAct[start + 5] , 11); + BOOST_CHECK_EQUAL(iAct[start + 6] , 0); + BOOST_CHECK_EQUAL(iAct[start + 7] , 0); + BOOST_CHECK_EQUAL(iAct[start + 8] , 3); + + start = 2*actDims[1]; + BOOST_CHECK_EQUAL(iAct[start + 0] , 0); + BOOST_CHECK_EQUAL(iAct[start + 1] , 4); + BOOST_CHECK_EQUAL(iAct[start + 2] , 1); + BOOST_CHECK_EQUAL(iAct[start + 3] , 7); + BOOST_CHECK_EQUAL(iAct[start + 4] , 0); + BOOST_CHECK_EQUAL(iAct[start + 5] , 13); + BOOST_CHECK_EQUAL(iAct[start + 6] , 0); + BOOST_CHECK_EQUAL(iAct[start + 7] , 0); + BOOST_CHECK_EQUAL(iAct[start + 8] , 3); + + } + + { + /* + ZACT + --length 4 times 8-chars pr ACTIONX keyword + + Name of action 4 times 8 chars (up to 8 chars for name) + + */ + + const auto& zAct = actionxData.getZACT(); + + auto start = 0*actDims[3]; + BOOST_CHECK_EQUAL(zAct[start + 0].c_str() , "ACT01 "); + + start = 1*actDims[3]; + BOOST_CHECK_EQUAL(zAct[start + 0].c_str() , "ACT02 "); + + start = 2*actDims[3]; + BOOST_CHECK_EQUAL(zAct[start + 0].c_str() , "ACT03 "); + + } + + { + /* + ZLACT + -- length = ACTDIMS_item3*(max-over-action of number of lines of data pr ACTION) + + */ + + const auto& zLact = actionxData.getZLACT(); + + //First action + auto start_a = 0*actDims[4]; + auto start = start_a + 0*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "WELOPEN "); + + start = start_a + 1*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , " '?' '"); + BOOST_CHECK_EQUAL(zLact[start + 1].c_str() , "SHUT' 0 "); + BOOST_CHECK_EQUAL(zLact[start + 2].c_str() , "0 0 / "); + + start = start_a + 2*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "/ "); + + start = start_a + 3*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "ENDACTIO"); + + //Second action + start_a = 1*actDims[4]; + start = start_a + 0*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "WELOPEN "); + + start = start_a + 1*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , " '?' '"); + BOOST_CHECK_EQUAL(zLact[start + 1].c_str() , "SHUT' 0 "); + BOOST_CHECK_EQUAL(zLact[start + 2].c_str() , "0 0 / "); + + start = start_a + 2*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "/ "); + + start = start_a + 3*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "WELOPEN "); + + start = start_a + 4*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , " 'OPL0"); + BOOST_CHECK_EQUAL(zLact[start + 1].c_str() , "1' 'OPEN"); + BOOST_CHECK_EQUAL(zLact[start + 2].c_str() , "' / "); + + start = start_a + 5*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "/ "); + + + start = start_a + 6*actDims[8]; + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "ENDACTIO"); + + + } + + { + /* + ZACN + //(Max number of conditions pr ACTIONX) * ((max no characters pr line = 104) / (8 - characters pr string)(104/8 = 13) + + */ + + const auto& zAcn = actionxData.getZACN(); + + //First action + auto start_a = 0*actDims[5]; + auto start = start_a + 0*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "WWPR "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , "OP* "); + + start = start_a + 1*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "GMWPR "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 4].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 5].c_str() , "T* "); + + start = start_a + 2*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 4].c_str() , " "); + + + + //Second action + start_a = 1*actDims[5]; + start = start_a + 0*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "FMWPR "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); + + start = start_a + 1*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "WGPR "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , "GGPR "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , "OPL02 "); + BOOST_CHECK_EQUAL(zAcn[start + 4].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 5].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 6].c_str() , "LOWER "); + + start = start_a + 2*13; + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 4].c_str() , " "); + } + + { + /* + IACN + 26*Max number of conditions pr ACTIONX + + */ + + + const auto& iAcn = actionxData.getIACN(); + + auto start_a = 0*actDims[6]; + auto start = start_a + 0*26; + BOOST_CHECK_EQUAL(iAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 2] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 5] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 2); + BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 2); + BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 17] , 0); + + start = start_a + 1*26; + BOOST_CHECK_EQUAL(iAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 2] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 5] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 3); + BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 17] , 0); + + start_a = 1*actDims[6]; + start = start_a + 0*26; + BOOST_CHECK_EQUAL(iAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 2] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 5] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 17] , 0); + + start = start_a + 1*26; + BOOST_CHECK_EQUAL(iAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 2] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 5] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 2); + BOOST_CHECK_EQUAL(iAcn[start + 11] , 3); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 17] , 0); + + start = start_a + 2*26; + BOOST_CHECK_EQUAL(iAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 2] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 5] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 11); + BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); + BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 17] , 1); + + } + + + + { + /* + SACN + 26*Max number of conditions pr ACTIONX + + */ + + + const auto& sAcn = actionxData.getSACN(); + + auto start_a = 0*actDims[6]; + auto start = start_a + 0*16; + BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 4] , 24); + BOOST_CHECK_EQUAL(sAcn[start + 5] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 6] , 24); + BOOST_CHECK_EQUAL(sAcn[start + 7] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 8] , 24); + BOOST_CHECK_EQUAL(sAcn[start + 9] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 13] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 15] , 0); + + start = start_a + 1*16; + BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 4] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 5] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 6] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 7] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 8] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 9] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 13] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 15] , 0); + + start = start_a + 2*16; + BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 3); + BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 4] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 5] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 6] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 7] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 8] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 9] , 1.E+20); + BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 12] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 13] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 14] , 0); + BOOST_CHECK_EQUAL(sAcn[start + 15] , 0); + + } + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_AggregateGroupData.cpp b/tests/test_AggregateGroupData.cpp index a7c214938..cc3262dac 100644 --- a/tests/test_AggregateGroupData.cpp +++ b/tests/test_AggregateGroupData.cpp @@ -498,10 +498,10 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data) BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{4}); const auto smry = sim_state(); + const auto& units = simCase.es.getUnits(); auto agrpd = Opm::RestartIO::Helpers::AggregateGroupData{ih.value}; - agrpd.captureDeclaredGroupData(simCase.sched, - rptStep, smry, - ih.value); + agrpd.captureDeclaredGroupData(simCase.sched, units, rptStep, smry, + ih.value); // IGRP (PROD) { diff --git a/tests/test_AggregateUDQData.cpp b/tests/test_AggregateUDQData.cpp index 58d015a5f..5e9c26328 100644 --- a/tests/test_AggregateUDQData.cpp +++ b/tests/test_AggregateUDQData.cpp @@ -187,10 +187,10 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data) */ - /*BOOST_CHECK_EQUAL(ih[267] , -1); + BOOST_CHECK_EQUAL(ih[267] , -1); BOOST_CHECK_EQUAL(dh[212] , 1.0E+20); BOOST_CHECK_EQUAL(dh[213] , 0.0); - BOOST_CHECK_EQUAL(dh[214] , 1.0E-4); */ + BOOST_CHECK_EQUAL(dh[214] , 1.0E-4); } From ae47d39a1a32c08050a857b8d81e1be77b887780 Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Sun, 15 Dec 2019 20:55:07 +0100 Subject: [PATCH 2/6] further corrections --- src/opm/output/eclipse/AggregateMSWData.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/opm/output/eclipse/AggregateMSWData.cpp b/src/opm/output/eclipse/AggregateMSWData.cpp index c6041170e..fd8e95f4c 100644 --- a/src/opm/output/eclipse/AggregateMSWData.cpp +++ b/src/opm/output/eclipse/AggregateMSWData.cpp @@ -418,24 +418,21 @@ namespace { const std::size_t baseIndex, ISegArray& iSeg) { - - using IsTyp = ::Opm::RestartIO::Helpers:: - VectorItems::ISeg::Value::SegmentType; - using IsStatus = ::Opm::RestartIO::Helpers:: - VectorItems::ISeg::Value::SICDStatus; + namespace ISegValue = ::Opm::RestartIO::Helpers:: + VectorItems::ISeg::Value; using Ix = ::Opm::RestartIO::Helpers:: VectorItems::ISeg::index; const auto& sicd = segment.spiralICD(); - iSeg[baseIndex + Ix::SegmentType] = IsTyp::SICD; + iSeg[baseIndex + Ix::SegmentType] = ISegValue::SegmentType::SICD; iSeg[baseIndex + Ix::ICDScalingMode] = sicd->methodFlowScaling(); iSeg[baseIndex + Ix::ICDOpenShutFlag] = (sicd->status() == Opm::SpiralICD::Status::OPEN) - ? IsStatus::Open - : IsStatus::Shut; + ? ISegValue::SICDStatus::Open + : ISegValue::SICDStatus::Shut; } template @@ -472,6 +469,7 @@ namespace { { using IsTyp = ::Opm::RestartIO::Helpers:: VectorItems::ISeg::Value::SegmentType; + using Ix = ::Opm::RestartIO::Helpers:: VectorItems::ISeg::index; @@ -506,7 +504,7 @@ namespace { if (! isRegular(segment)) { assignSegmentTypeCharacteristics(segment, iS, iSeg); } - else if (segment.segmentType() == Opm::Segment::SegmentType::REGULAR) { + if (segment.segmentType() == Opm::Segment::SegmentType::REGULAR) { iSeg[iS + Ix::SegmentType] = IsTyp::REGULAR; } } From cf82a90815bd8f8a3d2ea87f27462a3245493f66 Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Mon, 16 Dec 2019 14:34:36 +0100 Subject: [PATCH 3/6] Add changes for WHISTCTL data in ECL restart --- opm/output/eclipse/InteHEAD.hpp | 1 + opm/output/eclipse/VectorItems/intehead.hpp | 2 ++ .../EclipseState/Schedule/Schedule.hpp | 1 + src/opm/output/eclipse/CreateInteHead.cpp | 26 +++++++++++++++++++ src/opm/output/eclipse/InteHEAD.cpp | 11 +++++++- .../EclipseState/Schedule/Schedule.cpp | 5 ++++ 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/opm/output/eclipse/InteHEAD.hpp b/opm/output/eclipse/InteHEAD.hpp index 5969615d9..5ec859400 100755 --- a/opm/output/eclipse/InteHEAD.hpp +++ b/opm/output/eclipse/InteHEAD.hpp @@ -143,6 +143,7 @@ namespace Opm { namespace RestartIO { InteHEAD& actionParam(const ActionParam& act_par); InteHEAD& variousUDQ_ACTIONXParam(); InteHEAD& nominatedPhaseGuideRate(GuideRateNominatedPhase nphase); + InteHEAD& whistControlMode(int mode); const std::vector& data() const { diff --git a/opm/output/eclipse/VectorItems/intehead.hpp b/opm/output/eclipse/VectorItems/intehead.hpp index 458b8cb30..5e40d16f0 100644 --- a/opm/output/eclipse/VectorItems/intehead.hpp +++ b/opm/output/eclipse/VectorItems/intehead.hpp @@ -83,6 +83,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems DAY = 64, // Calendar day of report step (1..31) MONTH = 65, // Calendar month of report step (1..12) YEAR = 66, // Calendar year of report step + + WHISTC = 71, // Calendar year of report step NOOFACTIONS = 156, // The number of actions in the dataset MAXNOLINES = 157, // Maximum number of lines of schedule data for ACTION keyword - including ENDACTIO diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index f1071daed..3dd60bea0 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -184,6 +184,7 @@ namespace Opm std::vector getChildGroups2(const std::string& group_name, size_t timeStep) const; std::vector getChildWells2(const std::string& group_name, size_t timeStep) const; const OilVaporizationProperties& getOilVaporizationProperties(size_t timestep) const; + const Well::ProducerCMode& getGlobalWhistctlMmode(size_t timestep) const; const UDQActive& udqActive(size_t timeStep) const; const WellTestConfig& wtestConfig(size_t timestep) const; diff --git a/src/opm/output/eclipse/CreateInteHead.cpp b/src/opm/output/eclipse/CreateInteHead.cpp index d9cf1c18a..ec686eeba 100755 --- a/src/opm/output/eclipse/CreateInteHead.cpp +++ b/src/opm/output/eclipse/CreateInteHead.cpp @@ -55,6 +55,17 @@ namespace { {nph_enum::COMB, 9}, }; + using prod_cmode = Opm::Well::ProducerCMode; + const std::map prod_cmodeToECL = { + {prod_cmode::NONE, 0}, + {prod_cmode::ORAT, 1}, + {prod_cmode::WRAT, 2}, + {prod_cmode::GRAT, 3}, + {prod_cmode::LRAT, 4}, + {prod_cmode::RESV, 5}, + {prod_cmode::BHP, 7}, + }; + int maxConnPerWell(const Opm::Schedule& sched, const std::size_t lookup_step) { @@ -365,6 +376,20 @@ namespace { return {nom_phase}; } + + int getWhistctlMode(const ::Opm::Schedule& sched, + const std::size_t lookup_step) + { + int mode = 0; + const auto& w_hist_ctl_mode = sched.getGlobalWhistctlMmode(lookup_step); + const auto it_ctl = prod_cmodeToECL.find(w_hist_ctl_mode); + if (it_ctl != prod_cmodeToECL.end()) { + mode = it_ctl->second; + } + + return mode; + } + } // Anonymous // ##################################################################### @@ -416,6 +441,7 @@ createInteHead(const EclipseState& es, .actionParam (getActionParam(rspec, acts)) .variousUDQ_ACTIONXParam() .nominatedPhaseGuideRate(setGuideRateNominatedPhase(sched,lookup_step)) + .whistControlMode(getWhistctlMode(sched,lookup_step)) ; return ih.data(); diff --git a/src/opm/output/eclipse/InteHEAD.cpp b/src/opm/output/eclipse/InteHEAD.cpp index bc0440c3a..79eb90dd2 100644 --- a/src/opm/output/eclipse/InteHEAD.cpp +++ b/src/opm/output/eclipse/InteHEAD.cpp @@ -90,7 +90,7 @@ enum index : std::vector::size_type { REPORT_STEP = 68 , // The sequence/report number for for this restart file. ih_069 = 69 , // 0 0 ih_070 = 70 , // 0 0 - ih_071 = 71 , // 0 0 + NWHISTCTL = VI::intehead::WHISTC, // index for WHISTCTL keyword ih_072 = 72 , // 0 0 ih_073 = 73 , // 0 0 ih_074 = 74 , // 0 0 @@ -740,6 +740,15 @@ nominatedPhaseGuideRate(GuideRateNominatedPhase nphase) return *this; } +Opm::RestartIO::InteHEAD& +Opm::RestartIO::InteHEAD:: +whistControlMode(int mode) +{ + this -> data_[NWHISTCTL] = mode; + + return *this; +} + // ===================================================================== // Free functions (calendar/time utilities) // ===================================================================== diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 582dbd8d3..2b69af9c0 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -2601,6 +2601,11 @@ void Schedule::handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep, c const OilVaporizationProperties& Schedule::getOilVaporizationProperties(size_t timestep) const { return m_oilvaporizationproperties.get(timestep); } + + const Well::ProducerCMode& Schedule::getGlobalWhistctlMmode(size_t timestep) const { + return global_whistctl_mode.get(timestep); + } + bool Schedule::hasOilVaporizationProperties() const { for( size_t i = 0; i < this->m_timeMap.size(); ++i ) From 3fa8c25b47c63365064e1f7dd0bbb0c1f05f7d0b Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Tue, 17 Dec 2019 11:24:28 +0100 Subject: [PATCH 4/6] remove debug print --- src/opm/output/eclipse/AggregateGroupData.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/opm/output/eclipse/AggregateGroupData.cpp b/src/opm/output/eclipse/AggregateGroupData.cpp index b3ab34b8f..eb6bd0934 100644 --- a/src/opm/output/eclipse/AggregateGroupData.cpp +++ b/src/opm/output/eclipse/AggregateGroupData.cpp @@ -163,7 +163,6 @@ void staticContrib(const Opm::Schedule& sched, if ((group.getGroupType() == Opm::Group::GroupType::NONE) || (group.getGroupType() == Opm::Group::GroupType::PRODUCTION) ) { const auto& prod_cmode = group.production_cmode(); - std::cout << "IGRP[nwgmax + 5] group.name()" << group.name() << " prod_cmode " << static_cast(prod_cmode) << std::endl; if (prod_cmode == Opm::Group::ProductionCMode::FLD) { iGrp[nwgmax + 5] = -1; From 1e0a43c4f8b5f795fb5dc96fefca8e9feb606b2c Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Tue, 17 Dec 2019 16:34:45 +0100 Subject: [PATCH 5/6] corrections to unit tests --- src/opm/output/eclipse/CreateInteHead.cpp | 2 - tests/test_AggregateActionxData.cpp | 82 +++++++---------------- tests/test_AggregateConnectionData.cpp | 2 +- tests/test_AggregateWellData.cpp | 2 +- 4 files changed, 28 insertions(+), 60 deletions(-) diff --git a/src/opm/output/eclipse/CreateInteHead.cpp b/src/opm/output/eclipse/CreateInteHead.cpp index ec686eeba..9a301f9e9 100755 --- a/src/opm/output/eclipse/CreateInteHead.cpp +++ b/src/opm/output/eclipse/CreateInteHead.cpp @@ -103,11 +103,9 @@ namespace { for (const auto& group_name : sched.groupNames(lookup_step)) { const auto& group = sched.getGroup(group_name, lookup_step); if (group.isProductionGroup()) { - std::cout << "CrIH group.name()" << group.name() << " group.production_cmode() " << static_cast(group.production_cmode()) << std::endl; gctrl = 1; } if (group.isInjectionGroup()) { - std::cout << "CrIH group.name()" << group.name() << " group.injection_cmode() " << static_cast(group.injection_cmode()) << std::endl; gctrl = 2; } } diff --git a/tests/test_AggregateActionxData.cpp b/tests/test_AggregateActionxData.cpp index fc9e4f817..be868f597 100644 --- a/tests/test_AggregateActionxData.cpp +++ b/tests/test_AggregateActionxData.cpp @@ -40,21 +40,7 @@ namespace { return Opm::Parser{}.parseFile(fname); } } -/* -Opm::SummaryState sum_state_TEST1_FLOW() - { - auto state = Opm::SummaryState{std::chrono::system_clock::now()}; - state.update_well_var("OPU01", "WUPR3", 4); - state.update_well_var("OPU02", "WUPR3", 3); - state.update_well_var("OPL01", "WUPR3", 1); - state.update_well_var("OPL02", "WUPR3", 2); - - state.update("FMWPR", 4); - - return state; -} -*/ Opm::SummaryState sum_state_TEST1() { auto state = Opm::SummaryState{std::chrono::system_clock::now()}; @@ -143,26 +129,10 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih); auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims); udqData.captureDeclaredUDQData(sched, rptStep, st, ih); - + const auto actDims = Opm::RestartIO::Helpers::createActionxDims(rspec, sched, rptStep); auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep); - - /*rstFile.write("INTEHEAD", ih); - rstFile.write("IUDQ", udqData.getIUDQ()); - rstFile.write("IUAD", udqData.getIUAD()); - rstFile.write("IGPH", udqData.getIGPH()); - rstFile.write("IUAP", udqData.getIUAP()); - rstFile.write("ZUDN", udqData.getZUDN()); - rstFile.write("ZUDL", udqData.getZUDL()); - - rstFile.write("IACT", actionxData.getIACT()); - rstFile.write("SACT", actionxData.getSACT()); - rstFile.write("ZACT", actionxData.getZACT()); - rstFile.write("ZLACT", actionxData.getZLACT()); - rstFile.write("ZACN", actionxData.getZACN()); - rstFile.write("IACN", actionxData.getIACN()); - rstFile.write("SACN", actionxData.getSACN()); */ { /* @@ -188,7 +158,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) const auto ih_2 = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, secs_elapsed, rptStep, rptStep_2); BOOST_CHECK_EQUAL(ih_2[156] , 3); - BOOST_CHECK_EQUAL(ih_2[157] , 7); + BOOST_CHECK_EQUAL(ih_2[157] , 10); const auto rptStep_3 = std::size_t{2}; const auto ih_3 = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, @@ -219,7 +189,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) auto start = 0*actDims[1]; BOOST_CHECK_EQUAL(iAct[start + 0] , 0); - BOOST_CHECK_EQUAL(iAct[start + 1] , 4); + BOOST_CHECK_EQUAL(iAct[start + 1] , 10); BOOST_CHECK_EQUAL(iAct[start + 2] , 1); BOOST_CHECK_EQUAL(iAct[start + 3] , 7); BOOST_CHECK_EQUAL(iAct[start + 4] , 0); @@ -298,7 +268,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "/ "); start = start_a + 3*actDims[8]; - BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "ENDACTIO"); + BOOST_CHECK_EQUAL(zLact[start + 0].c_str() , "WELOPEN "); //Second action start_a = 1*actDims[4]; @@ -343,18 +313,18 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) //First action auto start_a = 0*actDims[5]; auto start = start_a + 0*13; - BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "WWPR "); + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "FMWPR "); BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); - BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , "OP* "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); start = start_a + 1*13; - BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "GMWPR "); + BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , "WUPR3 "); BOOST_CHECK_EQUAL(zAcn[start + 1].c_str() , " "); BOOST_CHECK_EQUAL(zAcn[start + 2].c_str() , "> "); - BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , " "); + BOOST_CHECK_EQUAL(zAcn[start + 3].c_str() , "OP* "); BOOST_CHECK_EQUAL(zAcn[start + 4].c_str() , " "); - BOOST_CHECK_EQUAL(zAcn[start + 5].c_str() , "T* "); + BOOST_CHECK_EQUAL(zAcn[start + 5].c_str() , " "); start = start_a + 2*13; BOOST_CHECK_EQUAL(zAcn[start + 0].c_str() , " "); @@ -412,10 +382,10 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); - BOOST_CHECK_EQUAL(iAcn[start + 10] , 2); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 1); BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); - BOOST_CHECK_EQUAL(iAcn[start + 13] , 2); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 1); BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); @@ -432,10 +402,10 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(iAcn[start + 7] , 0); BOOST_CHECK_EQUAL(iAcn[start + 8] , 0); BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); - BOOST_CHECK_EQUAL(iAcn[start + 10] , 3); + BOOST_CHECK_EQUAL(iAcn[start + 10] , 2); BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); - BOOST_CHECK_EQUAL(iAcn[start + 13] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 13] , 2); BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); BOOST_CHECK_EQUAL(iAcn[start + 16] , 1); @@ -495,7 +465,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) BOOST_CHECK_EQUAL(iAcn[start + 9] , 0); BOOST_CHECK_EQUAL(iAcn[start + 10] , 11); BOOST_CHECK_EQUAL(iAcn[start + 11] , 8); - BOOST_CHECK_EQUAL(iAcn[start + 12] , 1); + BOOST_CHECK_EQUAL(iAcn[start + 12] , 0); BOOST_CHECK_EQUAL(iAcn[start + 13] , 0); BOOST_CHECK_EQUAL(iAcn[start + 14] , 0); BOOST_CHECK_EQUAL(iAcn[start + 15] , 0); @@ -520,14 +490,14 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) auto start = start_a + 0*16; BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 2] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 45); BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 4] , 24); - BOOST_CHECK_EQUAL(sAcn[start + 5] , 17); - BOOST_CHECK_EQUAL(sAcn[start + 6] , 24); - BOOST_CHECK_EQUAL(sAcn[start + 7] , 17); - BOOST_CHECK_EQUAL(sAcn[start + 8] , 24); - BOOST_CHECK_EQUAL(sAcn[start + 9] , 17); + BOOST_CHECK_EQUAL(sAcn[start + 4] , 4); + BOOST_CHECK_EQUAL(sAcn[start + 5] , 45); + BOOST_CHECK_EQUAL(sAcn[start + 6] , 4); + BOOST_CHECK_EQUAL(sAcn[start + 7] , 45); + BOOST_CHECK_EQUAL(sAcn[start + 8] , 4); + BOOST_CHECK_EQUAL(sAcn[start + 9] , 45); BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); BOOST_CHECK_EQUAL(sAcn[start + 12] , 0); @@ -538,14 +508,14 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) start = start_a + 1*16; BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 2] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 46); BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); BOOST_CHECK_EQUAL(sAcn[start + 4] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 5] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 5] , 46); BOOST_CHECK_EQUAL(sAcn[start + 6] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 7] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 7] , 46); BOOST_CHECK_EQUAL(sAcn[start + 8] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 9] , 14); + BOOST_CHECK_EQUAL(sAcn[start + 9] , 46); BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); BOOST_CHECK_EQUAL(sAcn[start + 11] , 0); BOOST_CHECK_EQUAL(sAcn[start + 12] , 0); @@ -556,7 +526,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) start = start_a + 2*16; BOOST_CHECK_EQUAL(sAcn[start + 0] , 0); BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); - BOOST_CHECK_EQUAL(sAcn[start + 2] , 3); + BOOST_CHECK_EQUAL(sAcn[start + 2] , 10); BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); BOOST_CHECK_EQUAL(sAcn[start + 4] , 1.E+20); BOOST_CHECK_EQUAL(sAcn[start + 5] , 1.E+20); diff --git a/tests/test_AggregateConnectionData.cpp b/tests/test_AggregateConnectionData.cpp index 24155db4b..a2fc26271 100644 --- a/tests/test_AggregateConnectionData.cpp +++ b/tests/test_AggregateConnectionData.cpp @@ -51,7 +51,7 @@ struct MockIH const int nsegWell = 1, // E100 const int ncwMax = 20, const int iConnPerConn = 25, // NICONZ - const int sConnPerConn = 40, // NSCONZ + const int sConnPerConn = 41, // NSCONZ const int xConnPerConn = 58); // NXCONZ diff --git a/tests/test_AggregateWellData.cpp b/tests/test_AggregateWellData.cpp index 079cd445c..e8b500466 100644 --- a/tests/test_AggregateWellData.cpp +++ b/tests/test_AggregateWellData.cpp @@ -452,7 +452,7 @@ BOOST_AUTO_TEST_CASE (Declared_Well_Data) BOOST_CHECK_CLOSE(swell[i0 + Ix::GasRateTarget], 1.0e20f, 1.0e-7f); // LRAT limit derived from ORAT + WRAT (= ORAT + 0.0) - BOOST_CHECK_CLOSE(swell[i0 + Ix::LiqRateTarget], 20.0e3f, 1.0e-7f); + BOOST_CHECK_CLOSE(swell[i0 + Ix::LiqRateTarget], 1.0e20f, 1.0e-7f); // No direct limit, extract value from 'smry' (WVPR:OP_1) BOOST_CHECK_CLOSE(swell[i0 + Ix::ResVRateTarget], 1.0e20f, 1.0e-7f); From b519d825f263c81ae928359753e798e616268df3 Mon Sep 17 00:00:00 2001 From: Jostein Alvestad Date: Wed, 18 Dec 2019 13:27:34 +0100 Subject: [PATCH 6/6] corrections to test_msim_ACTIONX and SCON[40] --- src/opm/output/eclipse/AggregateConnectionData.cpp | 2 +- tests/msim/actionx1.include | 2 +- tests/msim/actionx2.include | 2 +- tests/msim/uda.include | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opm/output/eclipse/AggregateConnectionData.cpp b/src/opm/output/eclipse/AggregateConnectionData.cpp index 5a39edc5c..79fbbb458 100755 --- a/src/opm/output/eclipse/AggregateConnectionData.cpp +++ b/src/opm/output/eclipse/AggregateConnectionData.cpp @@ -191,7 +191,7 @@ namespace { sConn[Ix::item30] = -1.0e+20f; sConn[Ix::item31] = -1.0e+20f; - sConn[Ix::item41] = (conn.CF() > 0) ? 1 : 0; + sConn[Ix::item41] = (conn.ctfAssignedFromInput()) ? 1 : 0; } } // SConn diff --git a/tests/msim/actionx1.include b/tests/msim/actionx1.include index 5be8ad39f..f9bd4a74f 100644 --- a/tests/msim/actionx1.include +++ b/tests/msim/actionx1.include @@ -56,7 +56,7 @@ WELLDIMS -- - we are dealing with only one 'group' -- Item 4: maximum number of wells in any one group -- - there must be two wells in a group as there are two wells in total - 2 1 1 2 / + 5 1 1 2 / UNIFOUT diff --git a/tests/msim/actionx2.include b/tests/msim/actionx2.include index 9f239be4d..5734cbdf9 100644 --- a/tests/msim/actionx2.include +++ b/tests/msim/actionx2.include @@ -56,7 +56,7 @@ WELLDIMS -- - we are dealing with only one 'group' -- Item 4: maximum number of wells in any one group -- - there must be two wells in a group as there are two wells in total - 2 1 1 2 / + 5 1 1 2 / UNIFOUT diff --git a/tests/msim/uda.include b/tests/msim/uda.include index 9d9827d8c..52808c542 100644 --- a/tests/msim/uda.include +++ b/tests/msim/uda.include @@ -40,7 +40,7 @@ START 1 'DEC' 2014 / WELLDIMS - 2 1 1 2 / + 5 1 1 2 / UNIFOUT