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
This commit is contained in:
Jostein Alvestad 2019-10-16 15:47:03 +02:00
parent 132665e469
commit 0c9a2cbbf6
33 changed files with 1523 additions and 275 deletions

View File

@ -23,7 +23,7 @@
#include <opm/output/eclipse/WindowedArray.hpp> #include <opm/output/eclipse/WindowedArray.hpp>
#include <opm/io/eclipse/PaddedOutputString.hpp> #include <opm/io/eclipse/PaddedOutputString.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <vector> #include <vector>
@ -32,7 +32,8 @@
namespace Opm { namespace Opm {
class Schedule; class Schedule;
class SummaryState; class SummaryState;
class Group; //class Group;
class UnitSystem;
} // Opm } // Opm
namespace Opm { namespace RestartIO { namespace Helpers { namespace Opm { namespace RestartIO { namespace Helpers {
@ -42,10 +43,11 @@ class AggregateGroupData
public: public:
explicit AggregateGroupData(const std::vector<int>& inteHead); explicit AggregateGroupData(const std::vector<int>& inteHead);
void captureDeclaredGroupData(const Opm::Schedule& sched, void captureDeclaredGroupData(const Opm::Schedule& sched,
const std::size_t simStep, const Opm::UnitSystem& units,
const Opm::SummaryState& sumState, const std::size_t simStep,
const std::vector<int>& inteHead); const Opm::SummaryState& sumState,
const std::vector<int>& inteHead);
const std::vector<int>& getIGroup() const const std::vector<int>& getIGroup() const
{ {
@ -104,6 +106,19 @@ public:
{"GGPTH", 143}, {"GGPTH", 143},
{"GGITH", 144}, {"GGITH", 144},
}; };
using inj_cmode_enum = Opm::Group::InjectionCMode;
const std::map<inj_cmode_enum, int> 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<std::string, size_t> fieldKeyToIndex = { const std::map<std::string, size_t> fieldKeyToIndex = {
{"FOPR", 0}, {"FOPR", 0},

View File

@ -23,6 +23,7 @@
#include <opm/output/eclipse/WindowedArray.hpp> #include <opm/output/eclipse/WindowedArray.hpp>
#include <opm/io/eclipse/PaddedOutputString.hpp> #include <opm/io/eclipse/PaddedOutputString.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp>
#include <cstddef> #include <cstddef>
#include <string> #include <string>
@ -39,6 +40,11 @@ namespace Opm { namespace data {
}} // Opm::data }} // Opm::data
namespace Opm { namespace RestartIO { namespace Helpers { namespace Opm { namespace RestartIO { namespace Helpers {
struct ActionResStatus {
std::vector<Opm::Action::Result> result;
std::vector<std::string> name;
};
class AggregateWellData class AggregateWellData
{ {

View File

@ -40,6 +40,17 @@ namespace Opm { namespace RestartIO {
std::chrono::duration<double, std::chrono::seconds::period> elapsed; std::chrono::duration<double, std::chrono::seconds::period> elapsed;
}; };
struct guideRate {
double A;
double B;
double C;
double D;
double E;
double F;
double delay;
double damping_fact;
};
DoubHEAD(); DoubHEAD();
~DoubHEAD() = default; ~DoubHEAD() = default;
@ -61,6 +72,7 @@ namespace Opm { namespace RestartIO {
const double cnvT); const double cnvT);
DoubHEAD& udq_param(const UDQParams& udqPar); DoubHEAD& udq_param(const UDQParams& udqPar);
DoubHEAD& guide_rate_param(const guideRate& guide_rp);
const std::vector<double>& data() const const std::vector<double>& data() const
{ {

View File

@ -93,7 +93,11 @@ namespace Opm { namespace RestartIO {
struct UdqParam { struct UdqParam {
int udqParam_1; int udqParam_1;
int no_udqs; int no_wudqs;
int no_gudqs;
int no_fudqs;
int no_iuads;
int no_iuaps;
}; };
struct ActionParam { struct ActionParam {
@ -102,6 +106,11 @@ namespace Opm { namespace RestartIO {
int max_no_conditions_per_action; int max_no_conditions_per_action;
int max_no_characters_per_line; int max_no_characters_per_line;
}; };
struct GuideRateNominatedPhase {
int nominated_phase;
};
InteHEAD(); InteHEAD();
~InteHEAD() = default; ~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_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_NCON(const int niconz, const int nsconz, const int nxconz);
InteHEAD& params_GRPZ(const std::array<int, 4>& grpz); InteHEAD& params_GRPZ(const std::array<int, 4>& 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& 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& stepParam(const int tstep, const int report_step);
InteHEAD& tuningParam(const TuningPar& tunpar); InteHEAD& tuningParam(const TuningPar& tunpar);
@ -131,6 +141,8 @@ namespace Opm { namespace RestartIO {
InteHEAD& ngroups(const Group& gr); InteHEAD& ngroups(const Group& gr);
InteHEAD& udqParam_1(const UdqParam& udqpar); InteHEAD& udqParam_1(const UdqParam& udqpar);
InteHEAD& actionParam(const ActionParam& act_par); InteHEAD& actionParam(const ActionParam& act_par);
InteHEAD& variousUDQ_ACTIONXParam();
InteHEAD& nominatedPhaseGuideRate(GuideRateNominatedPhase nphase);
const std::vector<int>& data() const const std::vector<int>& data() const
{ {

View File

@ -57,6 +57,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
item30 = 29, // Unknown item30 = 29, // Unknown
item31 = 30, // Unknown item31 = 30, // Unknown
item41 = 40, // = 0 for connection factor not defined, = 1 for connection factor defined
}; };
} // SConn } // SConn

View File

@ -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 . // 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. // Promote items from that list to this in order to make them public.
enum doubhead : std::vector<double>::size_type { enum doubhead : std::vector<double>::size_type {
TsInit = 1, // Maximum Length of Next Timestep TsInit = 1, // Maximum Length of Next Timestep
TsMaxz = 2, // Maximum Length of Timestep After Next TsMaxz = 2, // Maximum Length of Timestep After Next
TsMinz = 3, // Minumum Length of All Timesteps TsMinz = 3, // Minumum Length of All Timesteps
UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities) GRpar_a = 87, // Guiderate parameter A
UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data) GRpar_b = 88, // Guiderate parameter B
UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions) 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 }}}} // Opm::RestartIO::Helpers::VectorItems

View File

@ -24,6 +24,30 @@
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems { namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
namespace SGroup {
enum prod_index : std::vector<float>::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<float>::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 { namespace XGroup {
enum index : std::vector<double>::size_type { enum index : std::vector<double>::size_type {
OilPrRate = 0, // Group's oil production rate OilPrRate = 0, // Group's oil production rate

View File

@ -75,6 +75,10 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
NICAQZ = 45, // Number of data elements per aquifer connection in ICAQ array NICAQZ = 45, // Number of data elements per aquifer connection in ICAQ array
NSCAQZ = 46, // Number of data elements per aquifer connection in SCAQ 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 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) DAY = 64, // Calendar day of report step (1..31)
MONTH = 65, // Calendar month of report step (1..12) 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 NILBRZ = 180, // Number of entries per segment in ILBR array
MAX_ACT_COND = 245, // Maximum number of conditions pr action MAX_ACT_COND = 245, // Maximum number of conditions pr action
MAX_AN_AQUIFERS = 252, // Maximum number of analytic aquifers MAX_AN_AQUIFERS = 252, // Maximum number of analytic aquifers
NO_UDQS = 266, // No of UDQ data (parameters) NO_FIELD_UDQS = 262, // No of Field UDQ data (parameters) /
UDQPAR_1 = 267, // Integer seed value for the RAND 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, RSEED = 296,
}; };
}}}} // Opm::RestartIO::Helpers::VectorItems }}}} // Opm::RestartIO::Helpers::VectorItems

View File

@ -39,6 +39,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
namespace Value { namespace Value {
enum SegmentType : int { enum SegmentType : int {
REGULAR = -1,
AICD = -8, AICD = -8,
SICD = -7, SICD = -7,
Valve = -5, Valve = -5,

View File

@ -180,6 +180,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
namespace ZWell { namespace ZWell {
enum index : std::vector<const char*>::size_type { enum index : std::vector<const char*>::size_type {
WellName = 0, // Well name WellName = 0, // Well name
ActionX = 2, // ActionX name
}; };
} // ZWell } // ZWell
}}}} // Opm::RestartIO::Helpers::VectorItems }}}} // Opm::RestartIO::Helpers::VectorItems

View File

@ -95,11 +95,15 @@ public:
explicit operator bool() const; explicit operator bool() const;
std::vector<std::string> wells() const; std::vector<std::string> wells() const;
bool has_well(const std::string& well);
bool has_well(const std::string& well) const;
void add_well(const std::string& well); void add_well(const std::string& well);
Result& operator|=(const Result& other); Result& operator|=(const Result& other);
Result& operator=(const Result& src);
Result& operator&=(const Result& other); Result& operator&=(const Result& other);
private: private:
void assign(bool value); void assign(bool value);
bool result; bool result;

View File

@ -197,6 +197,7 @@ struct ProductionControls {
InjectionControls injectionControls(const SummaryState& st) const; InjectionControls injectionControls(const SummaryState& st) const;
const GroupProductionProperties& productionProperties() const; const GroupProductionProperties& productionProperties() const;
const GroupInjectionProperties& injectionProperties() const; const GroupInjectionProperties& injectionProperties() const;
const GroupType& getGroupType() const;
ProductionCMode production_cmode() const; ProductionCMode production_cmode() const;
InjectionCMode injection_cmode() const; InjectionCMode injection_cmode() const;
Phase injection_phase() const; Phase injection_phase() const;

View File

@ -62,7 +62,13 @@ public:
bool operator==(const GuideRateModel& other) const; bool operator==(const GuideRateModel& other) const;
bool operator!=(const GuideRateModel& other) const; bool operator!=(const GuideRateModel& other) const;
Target target() 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(Group::GuideRateTarget group_target);
static Target convert_target(Well::GuideRateTarget well_target); static Target convert_target(Well::GuideRateTarget well_target);
static double pot(Target target, double oil_pot, double gas_pot, double wat_pot); static double pot(Target target, double oil_pot, double gas_pot, double wat_pot);

View File

@ -19,6 +19,7 @@
#include <opm/output/eclipse/AggregateActionxData.hpp> #include <opm/output/eclipse/AggregateActionxData.hpp>
#include <opm/output/eclipse/AggregateGroupData.hpp> #include <opm/output/eclipse/AggregateGroupData.hpp>
#include <opm/output/eclipse/AggregateWellData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp> #include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
@ -30,6 +31,9 @@
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQAssign.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
@ -42,7 +46,7 @@
#include <iostream> #include <iostream>
// ##################################################################### // #####################################################################
// Class Opm::RestartIO::Helpers::AggregateGroupData // Class Opm::RestartIO::Helpers
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -55,6 +59,25 @@ namespace {
{"M", 11}, {"M", 11},
{"Y", 12}, {"Y", 12},
}; };
/*const std::map<std::string, int> lhsQuantityToItem_12 = {
{"F", 0},
{"W", 0},
{"G", 0},
{"D", 0},
{"M", 1},
{"Y", 0},
};*/
using cmp_enum = Opm::Action::Condition::Comparator;
const std::map<cmp_enum, int> 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<std::string, double> monthToNo = { const std::map<std::string, double> monthToNo = {
{"JAN", 1.}, {"JAN", 1.},
@ -72,35 +95,35 @@ namespace {
}; };
const std::map<std::string, int> rhsQuantityToIndex = { const std::map<std::string, int> rhsQuantityToIndex = {
{"F", 1}, {"F", 1},
{"W", 2}, {"W", 2},
{"G", 3}, {"G", 3},
}; };
using logic_enum = Opm::Action::Condition::Logical;
const std::map<logic_enum, int> logicalToIndex_13 = {
{logic_enum::AND, 1},
{logic_enum::OR, 2},
{logic_enum::END, 0},
};
const std::map<logic_enum, int> logicalToIndex_17 = {
{logic_enum::AND, 1},
{logic_enum::OR, 0},
{logic_enum::END, 0},
};
using logic_enum = Opm::Action::Condition::Logical;
const std::map<logic_enum, int> logicalToIndex_13 = {
{logic_enum::AND, 1},
{logic_enum::OR, 2},
{logic_enum::END, 0},
};
using cmp_enum = Opm::Action::Condition::Comparator; const std::map<logic_enum, int> logicalToIndex_17 = {
const std::map<cmp_enum, int> cmpToIndex = { {logic_enum::AND, 1},
{cmp_enum::GREATER, 1}, {logic_enum::OR, 0},
{cmp_enum::LESS, 2}, {logic_enum::END, 0},
{cmp_enum::GREATER_EQUAL, 3}, };
{cmp_enum::LESS_EQUAL, 4},
{cmp_enum::EQUAL, 5},
{cmp_enum::INVALID, 0}, using cmp_enum = Opm::Action::Condition::Comparator;
}; const std::map<cmp_enum, int> 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 { namespace iACT {
@ -109,9 +132,12 @@ namespace {
allocate(const std::vector<int>& actDims) allocate(const std::vector<int>& actDims)
{ {
using WV = Opm::RestartIO::Helpers::WindowedArray<int>; using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[1], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[1]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -122,8 +148,18 @@ namespace {
iAct[0] = 0; iAct[0] = 0;
//item [1]: The number of lines of schedule data including ENDACTIO //item [1]: The number of lines of schedule data including ENDACTIO
iAct[1] = actx.keyword_strings().size(); iAct[1] = actx.keyword_strings().size();
//item [2]: is unknown, (=1) //item [2]: is = 1 for condition and previous condition = AND, and combinations OR/AND
iAct[2] = 1; // 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) //item [3]: is unknown, (=7)
iAct[3] = 7; iAct[3] = 7;
//item [4]: is unknown, (=0) //item [4]: is unknown, (=0)
@ -146,9 +182,12 @@ namespace {
allocate(const std::vector<int>& actDims) allocate(const std::vector<int>& actDims)
{ {
using WV = Opm::RestartIO::Helpers::WindowedArray<float>; using WV = Opm::RestartIO::Helpers::WindowedArray<float>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[2], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[2]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -173,10 +212,12 @@ namespace {
using WV = Opm::RestartIO::Helpers::WindowedArray< using WV = Opm::RestartIO::Helpers::WindowedArray<
Opm::EclIO::PaddedOutputString<8> Opm::EclIO::PaddedOutputString<8>
>; >;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[3], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[3]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -198,10 +239,11 @@ namespace {
using WV = Opm::RestartIO::Helpers::WindowedArray< using WV = Opm::RestartIO::Helpers::WindowedArray<
Opm::EclIO::PaddedOutputString<8> Opm::EclIO::PaddedOutputString<8>
>; >;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[4], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[4]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -243,9 +285,11 @@ namespace {
Opm::EclIO::PaddedOutputString<8> Opm::EclIO::PaddedOutputString<8>
>; >;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[5], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[5]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -291,8 +335,6 @@ namespace {
} }
} }
} // zAcn } // zAcn
}
namespace iACN { namespace iACN {
@ -300,9 +342,12 @@ namespace {
allocate(const std::vector<int>& actDims) allocate(const std::vector<int>& actDims)
{ {
using WV = Opm::RestartIO::Helpers::WindowedArray<int>; using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[6], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[6]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
@ -352,13 +397,13 @@ namespace {
iAcn[ind + 11] = it_rhsq->second; iAcn[ind + 11] = it_rhsq->second;
} }
/*item[12] - index for lhs type /*item[12] - index for relational operator (<, =, > )
1 - for MNTH 0 - for LHS quantity greater RHS quantity
0 - for all other types 1 - for LHS quantity less than or equal to RHS quantity
*/ */
std::string lhsQ = z_data.lhs.quantity; const auto it_lhs_it = cmpToIacn_12.find(z_data.cmp);
if ( lhsQ == "MNTH") { if (it_lhs_it != cmpToIacn_12.end()) {
iAcn[ind + 12] = 1; iAcn[ind + 12] = it_lhs_it->second;
} }
/*item [13] - relates to operator /*item [13] - relates to operator
@ -424,42 +469,62 @@ namespace {
allocate(const std::vector<int>& actDims) allocate(const std::vector<int>& actDims)
{ {
using WV = Opm::RestartIO::Helpers::WindowedArray<double>; using WV = Opm::RestartIO::Helpers::WindowedArray<double>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[7], 1);
return WV { return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) }, WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(actDims[7]) } WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
}; };
} }
Opm::Action::Result
act_res(const Opm::Schedule& sched, const Opm::SummaryState& smry, const std::size_t sim_step, std::vector<Opm::Action::ActionX>::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 <class SACNArray> template <class SACNArray>
void staticContrib(const Opm::Action::ActionX& actx, void staticContrib(std::vector<Opm::Action::ActionX>::const_iterator actx_it,
const Opm::SummaryState& st, const Opm::SummaryState& st,
SACNArray& sAcn) const Opm::Schedule& sched,
const std::size_t simStep,
SACNArray& sAcn)
{ {
std::size_t ind = 0; std::size_t ind = 0;
int noEPZacn = 16; int noEPZacn = 16;
double undef_high_val = 1.0E+20; 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 // 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) { for (const auto& z_data : actx_cond) {
// item [0 - 1] = 0 (unknown) // item [0 - 1] = 0 (unknown)
sAcn[ind + 0] = 0.; sAcn[ind + 0] = 0.;
sAcn[ind + 1] = 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); 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); const auto& it_rhsq = rhsQuantityToIndex.find(rhsQtype);
if (it_rhsq == rhsQuantityToIndex.end()) { if (it_rhsq == rhsQuantityToIndex.end()) {
//come here if constant value condition //come here if constant value condition
double t_val = 0.; double t_val = 0.;
if (rhsQtype == "M") { if (lhsQtype == "M") {
const auto& it_mnth = monthToNo.find(z_data.rhs.quantity); const auto& it_mnth = monthToNo.find(z_data.rhs.quantity);
if (it_mnth != monthToNo.end()) { if (it_mnth != monthToNo.end()) {
t_val = it_mnth->second; t_val = it_mnth->second;
} }
else { else {
std::cout << "Unknown Month: " << z_data.rhs.quantity << std::endl; 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 { else {
@ -470,39 +535,33 @@ namespace {
sAcn[ind + 7] = sAcn[ind + 2]; sAcn[ind + 7] = sAcn[ind + 2];
sAcn[ind + 9] = 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()) { if (it_rhsq != rhsQuantityToIndex.end()) {
//Well variable //Well variable
if (it_rhsq->first == "W") { if ((it_rhsq->first == "W") && (st.has_well_var(z_data.rhs.args[0], z_data.rhs.quantity))) {
sAcn[ind + 4] = st.get_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 + 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 + 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); sAcn[ind + 9] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
} }
//group variable //group variable
if (it_rhsq->first == "G") { if ((it_rhsq->first == "G") && (st.has_group_var(z_data.rhs.args[0], z_data.rhs.quantity))) {;
sAcn[ind + 4] = st.get_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 + 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 + 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); sAcn[ind + 9] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
} }
//field variable //field variable
if (it_rhsq->first == "F") { if ((it_rhsq->first == "F") && (st.has(z_data.rhs.quantity))) {
sAcn[ind + 4] = st.get(z_data.rhs.quantity);
sAcn[ind + 5] = st.get(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 + 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); sAcn[ind + 9] = st.get(z_data.rhs.quantity);
} }
} }
//treat cases with left hand side condition being: DAY, MNTH og YEAR variable //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); const auto& it_lhsq = lhsQuantityToIndex.find(lhsQtype);
if ((it_lhsq->first == "D") || (it_lhsq->first == "M") || (it_lhsq->first == "Y")) { if ((it_lhsq->first == "D") || (it_lhsq->first == "M") || (it_lhsq->first == "Y")) {
sAcn[ind + 4] = undef_high_val; sAcn[ind + 4] = undef_high_val;
@ -513,6 +572,41 @@ namespace {
sAcn[ind + 9] = undef_high_val; 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 //increment index according to no of items pr condition
ind += static_cast<std::size_t>(noEPZacn); ind += static_cast<std::size_t>(noEPZacn);
} }
@ -520,7 +614,7 @@ namespace {
} // sAcn } // sAcn
}
// ===================================================================== // =====================================================================
Opm::RestartIO::Helpers::AggregateActionxData:: Opm::RestartIO::Helpers::AggregateActionxData::
@ -543,7 +637,7 @@ captureDeclaredActionxData( const Opm::Schedule& sched,
const std::vector<int>& actDims, const std::vector<int>& actDims,
const std::size_t simStep) const std::size_t simStep)
{ {
auto acts = sched.actions(simStep); const auto acts = sched.actions(simStep);
std::size_t act_ind = 0; std::size_t act_ind = 0;
for (auto actx_it = acts.begin(); actx_it < acts.end(); actx_it++) { 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]; 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; act_ind +=1;

View File

@ -191,6 +191,7 @@ namespace {
sConn[Ix::item30] = -1.0e+20f; sConn[Ix::item30] = -1.0e+20f;
sConn[Ix::item31] = -1.0e+20f; sConn[Ix::item31] = -1.0e+20f;
sConn[Ix::item41] = (conn.CF() > 0) ? 1 : 0;
} }
} // SConn } // SConn

View File

@ -19,6 +19,7 @@
#include <opm/output/eclipse/AggregateGroupData.hpp> #include <opm/output/eclipse/AggregateGroupData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp> #include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/VectorItems/group.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp> #include <opm/parser/eclipse/EclipseState/Runspec.hpp>
@ -123,12 +124,14 @@ allocate(const std::vector<int>& inteHead)
} }
template <class IGrpArray> template <class IGrpArray>
void staticContrib(const Opm::Schedule& sched, void staticContrib(const Opm::Schedule& sched,
const Opm::Group& group, const Opm::Group& group,
const int nwgmax, const int nwgmax,
const int ngmaxz, const int ngmaxz,
const std::size_t simStep, const std::size_t simStep,
IGrpArray& iGrp) const Opm::SummaryState& sumState,
const std::map<Opm::Group::InjectionCMode, int> cmodeToNum,
IGrpArray& iGrp)
{ {
if (group.wellgroup()) { if (group.wellgroup()) {
int igrpCount = 0; int igrpCount = 0;
@ -151,6 +154,88 @@ void staticContrib(const Opm::Schedule& sched,
//assign the number of child wells or child groups to //assign the number of child wells or child groups to
// location nwgmax // location nwgmax
iGrp[nwgmax] = groupSize(group); 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<int>(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); iGrp[nwgmax + 26] = groupType(group);
//find group level ("FIELD" is level 0) and store the level in //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") if (group.name() != "FIELD")
{ {
iGrp[nwgmax+ 5] = -1; //iGrp[nwgmax+ 5] = -1;
iGrp[nwgmax+12] = -1; iGrp[nwgmax+12] = -1;
iGrp[nwgmax+17] = -1; iGrp[nwgmax+17] = -1;
iGrp[nwgmax+22] = -1; iGrp[nwgmax+22] = -1;
@ -192,6 +277,7 @@ void staticContrib(const Opm::Schedule& sched,
else else
iGrp[nwgmax+28] = parent_group.insert_index(); iGrp[nwgmax+28] = parent_group.insert_index();
} }
} }
} // Igrp } // Igrp
@ -214,8 +300,15 @@ allocate(const std::vector<int>& inteHead)
} }
template <class SGrpArray> template <class SGrpArray>
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 = -1.0e+20f;
const auto dflt_2 = -2.0e+20f; const auto dflt_2 = -2.0e+20f;
const auto infty = 1.0e+20f; const auto infty = 1.0e+20f;
@ -256,6 +349,67 @@ void staticContrib(SGrpArray& sGrp)
auto e = b + std::min(init.size(), sz); auto e = b + std::min(init.size(), sz);
std::copy(b, e, std::begin(sGrp)); std::copy(b, e, std::begin(sGrp));
auto sgprop = [&units](const M u, const double x) -> float
{
return static_cast<float>(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 } // SGrp
@ -355,6 +509,7 @@ AggregateGroupData(const std::vector<int>& inteHead)
void void
Opm::RestartIO::Helpers::AggregateGroupData:: Opm::RestartIO::Helpers::AggregateGroupData::
captureDeclaredGroupData(const Opm::Schedule& sched, captureDeclaredGroupData(const Opm::Schedule& sched,
const Opm::UnitSystem& units,
const std::size_t simStep, const std::size_t simStep,
const Opm::SummaryState& sumState, const Opm::SummaryState& sumState,
const std::vector<int>& inteHead) const std::vector<int>& inteHead)
@ -367,21 +522,21 @@ captureDeclaredGroupData(const Opm::Schedule& sched,
curGroups[ind] = std::addressof(group); 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 (const Group& group, const std::size_t groupID) -> void
{ {
auto ig = this->iGroup_[groupID]; auto ig = this->iGroup_[groupID];
IGrp::staticContrib(sched, group, this->nWGMax_, this->nGMaxz_, IGrp::staticContrib(sched, group, this->nWGMax_, this->nGMaxz_,
simStep, ig); simStep, sumState, this->cmodeToNum, ig);
}); });
// Define Static Contributions to SGrp Array. // Define Static Contributions to SGrp Array.
groupLoop(curGroups, 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]; auto sw = this->sGroup_[groupID];
SGrp::staticContrib(sw); SGrp::staticContrib(group, sumState, units, sw);
}); });
// Define Dynamic Contributions to XGrp Array. // Define Dynamic Contributions to XGrp Array.

View File

@ -30,7 +30,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp> #include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <algorithm> #include <algorithm>
@ -418,21 +418,24 @@ namespace {
const std::size_t baseIndex, const std::size_t baseIndex,
ISegArray& iSeg) 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:: using Ix = ::Opm::RestartIO::Helpers::
VectorItems::ISeg::index; VectorItems::ISeg::index;
const auto& sicd = segment.spiralICD(); 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::ICDScalingMode] = sicd->methodFlowScaling();
iSeg[baseIndex + Ix::ICDOpenShutFlag] = iSeg[baseIndex + Ix::ICDOpenShutFlag] =
(sicd->status() == Opm::SpiralICD::Status::OPEN) (sicd->status() == Opm::SpiralICD::Status::OPEN)
? ISegValue::SICDStatus::Open ? IsStatus::Open
: ISegValue::SICDStatus::Shut; : IsStatus::Shut;
} }
template <class ISegArray> template <class ISegArray>
@ -467,6 +470,11 @@ namespace {
const std::vector<int>& inteHead, const std::vector<int>& inteHead,
ISegArray& iSeg) ISegArray& iSeg)
{ {
using IsTyp = ::Opm::RestartIO::Helpers::
VectorItems::ISeg::Value::SegmentType;
using Ix = ::Opm::RestartIO::Helpers::
VectorItems::ISeg::index;
if (well.isMultiSegment()) { if (well.isMultiSegment()) {
//loop over segment set and print out information //loop over segment set and print out information
const auto& welSegSet = well.getSegments(); const auto& welSegSet = well.getSegments();
@ -474,6 +482,12 @@ namespace {
const auto& noElmSeg = nisegz(inteHead); const auto& noElmSeg = nisegz(inteHead);
std::size_t segmentInd = 0; std::size_t segmentInd = 0;
auto orderedSegmentNo = segmentOrder(welSegSet, segmentInd); auto orderedSegmentNo = segmentOrder(welSegSet, segmentInd);
std::vector<int> 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++) { for (int ind = 0; ind < welSegSet.size(); ind++) {
const auto& segment = welSegSet[ind]; const auto& segment = welSegSet[ind];
@ -487,11 +501,14 @@ namespace {
iSeg[iS + 5] = sumNoInFlowBranches(welSegSet, ind); iSeg[iS + 5] = sumNoInFlowBranches(welSegSet, ind);
iSeg[iS + 6] = noConnectionsSegment(completionSet, welSegSet, ind); iSeg[iS + 6] = noConnectionsSegment(completionSet, welSegSet, ind);
iSeg[iS + 7] = sumConnectionsSegment(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)) { if (! isRegular(segment)) {
assignSegmentTypeCharacteristics(segment, iS, iSeg); assignSegmentTypeCharacteristics(segment, iS, iSeg);
} }
else if (segment.segmentType() == Opm::Segment::SegmentType::REGULAR) {
iSeg[iS + Ix::SegmentType] = IsTyp::REGULAR;
}
} }
} }
else { else {

View File

@ -17,9 +17,12 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/output/eclipse/AggregateUDQData.hpp> #include <opm/output/eclipse/AggregateUDQData.hpp>
#include <opm/output/eclipse/AggregateGroupData.hpp> #include <opm/output/eclipse/AggregateGroupData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp> #include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/InteHEAD.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp> #include <opm/parser/eclipse/EclipseState/Runspec.hpp>
@ -46,7 +49,7 @@
// Class Opm::RestartIO::Helpers::AggregateGroupData // Class Opm::RestartIO::Helpers::AggregateGroupData
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace { namespace {
// maximum number of groups // maximum number of groups
@ -56,12 +59,36 @@ namespace {
} }
// maximum number of wells // maximum number of wells
/*std::size_t nwmaxz(const std::vector<int>& inteHead) std::size_t nwmaxz(const std::vector<int>& inteHead)
{ {
return inteHead[163]; return inteHead[163];
}*/ }
// Categorize function in terms of which token-types are used in formula
int define_type(const std::set<Opm::UDQTokenType> tokens) {
int type = -4;
std::vector <Opm::UDQTokenType> 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 { namespace iUdq {
@ -80,8 +107,10 @@ namespace {
void staticContrib(const Opm::UDQInput& udq_input, IUDQArray& iUdq) void staticContrib(const Opm::UDQInput& udq_input, IUDQArray& iUdq)
{ {
if (udq_input.is<Opm::UDQDefine>()) { if (udq_input.is<Opm::UDQDefine>()) {
const auto& udq_define = udq_input.get<Opm::UDQDefine>();
const auto& tokens = udq_define.func_tokens();
iUdq[0] = 2; iUdq[0] = 2;
iUdq[1] = -4; iUdq[1] = define_type(tokens);
} else { } else {
iUdq[0] = 0; iUdq[0] = 0;
iUdq[1] = -4; iUdq[1] = -4;
@ -442,6 +471,8 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
const std::vector<int>& inteHead) const std::vector<int>& inteHead)
{ {
const auto& udqCfg = sched.getUDQConfig(simStep); 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()) { for (const auto& udq_input : udqCfg.input()) {
auto udq_index = udq_input.index.insert_index; auto udq_index = udq_input.index.insert_index;
{ {
@ -456,66 +487,119 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
auto z_udl = this->zUDL_[udq_index]; auto z_udl = this->zUDL_[udq_index];
zUdl::staticContrib(udq_input, z_udl); 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); auto udq_active = sched.udqActive(simStep);
if (udq_active) { if (udq_active) {
const auto& udq_records = udq_active.get_iuad(); const auto& udq_records = udq_active.get_iuad();
int cnt_iuad = 0;
for (std::size_t index = 0; index < udq_records.size(); index++) { for (std::size_t index = 0; index < udq_records.size(); index++) {
const auto& record = udq_records[index]; const auto& record = udq_records[index];
auto i_uad = this->iUAD_[index]; auto i_uad = this->iUAD_[index];
iUad::staticContrib(record, i_uad); 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(); const auto& iuap_records = udq_active.get_iuap();
int cnt_iuap = 0;
const auto iuap_vect = iuap_data(sched, simStep,iuap_records); const auto iuap_vect = iuap_data(sched, simStep,iuap_records);
for (std::size_t index = 0; index < iuap_vect.size(); index++) { for (std::size_t index = 0; index < iuap_vect.size(); index++) {
const auto& wg_no = iuap_vect[index]; const auto& wg_no = iuap_vect[index];
auto i_uap = this->iUAP_[index]; auto i_uap = this->iUAP_[index];
iUap::staticContrib(wg_no, i_uap); 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; if (inteHead[VI::intehead::NO_GROUP_UDQS] > 0) {
auto igph = igph_dat.ig_phase(sched, simStep, inteHead); Opm::RestartIO::Helpers::igphData igph_dat;
for (std::size_t index = 0; index < igph.size(); index++) { int cnt_igph = 0;
auto i_igph = this->iGPH_[index]; auto igph = igph_dat.ig_phase(sched, simStep, inteHead);
iGph::staticContrib(igph[index], i_igph); 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; std::size_t i_wudq = 0;
const auto& wnames = sched.wellNames(simStep); const auto& wnames = sched.wellNames(simStep);
const auto nwmax = nwmaxz(inteHead); const auto nwmax = nwmaxz(inteHead);
int cnt_dudw = 0;
for (const auto& udq_input : udqCfg.input()) { for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::WELL_VAR) { if (udq_input.var_type() == UDQVarType::WELL_VAR) {
const std::string& udq = udq_input.keyword(); const std::string& udq = udq_input.keyword();
auto i_dudw = this->dUDW_[i_wudq]; auto i_dudw = this->dUDW_[i_wudq];
dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw); dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw);
i_wudq++; 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; std::size_t i_gudq = 0;
const auto curGroups = currentGroups(sched, simStep, inteHead); const auto curGroups = currentGroups(sched, simStep, inteHead);
const auto ngmax = ngmaxz(inteHead); const auto ngmax = ngmaxz(inteHead);
int cnt_dudg = 0;
for (const auto& udq_input : udqCfg.input()) { for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::GROUP_VAR) { if (udq_input.var_type() == UDQVarType::GROUP_VAR) {
const std::string& udq = udq_input.keyword(); const std::string& udq = udq_input.keyword();
auto i_dudg = this->dUDG_[i_gudq]; auto i_dudg = this->dUDG_[i_gudq];
dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg); dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg);
i_gudq++; 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; std::size_t i_fudq = 0;
int cnt_dudf = 0;
for (const auto& udq_input : udqCfg.input()) { for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::FIELD_VAR) { if (udq_input.var_type() == UDQVarType::FIELD_VAR) {
const std::string& udq = udq_input.keyword(); const std::string& udq = udq_input.keyword();
auto i_dudf = this->dUDF_[i_fudq]; auto i_dudf = this->dUDF_[i_fudq];
dUdf::staticContrib(st, udq, i_dudf); dUdf::staticContrib(st, udq, i_dudf);
i_fudq++; 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());
}
} }

View File

@ -31,6 +31,11 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp> #include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Units/Units.hpp> #include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp>
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -72,6 +77,9 @@ namespace {
// Remove leading/trailing blanks. // Remove leading/trailing blanks.
return s.substr(b, e - b + 1); return s.substr(b, e - b + 1);
} }
template <typename WellOp> template <typename WellOp>
void wellLoop(const std::vector<Opm::Well>& wells, void wellLoop(const std::vector<Opm::Well>& wells,
@ -407,11 +415,11 @@ namespace {
zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2) zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2)
infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3) infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3)
one , zero , zero , zero , zero , zero , // 24.. 29 ( 4) 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 , // 36.. 41 ( 6)
zero , zero , zero , zero , zero , zero , // 42.. 47 ( 7) zero , zero , zero , zero , zero , zero , // 42.. 47 ( 7)
zero , zero , zero , zero , zero , zero , // 48.. 53 ( 8) 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 , // 60.. 65 (10)
zero , zero , zero , zero , zero , zero , // 66.. 71 (11) zero , zero , zero , zero , zero , zero , // 66.. 71 (11)
zero , zero , zero , zero , zero , zero , // 72.. 77 (12) zero , zero , zero , zero , zero , zero , // 72.. 77 (12)
@ -460,28 +468,28 @@ namespace {
const auto& pc = well.productionControls(smry); const auto& pc = well.productionControls(smry);
const auto& predMode = well.predictionMode(); const auto& predMode = well.predictionMode();
if ((pc.oil_rate != 0.0) || (!predMode)) { if (pc.oil_rate != 0.0) {
sWell[Ix::OilRateTarget] = sWell[Ix::OilRateTarget] =
swprop(M::liquid_surface_rate, pc.oil_rate); swprop(M::liquid_surface_rate, pc.oil_rate);
} }
if ((pc.water_rate != 0.0) || (!predMode)) { if (pc.water_rate != 0.0) {
sWell[Ix::WatRateTarget] = sWell[Ix::WatRateTarget] =
swprop(M::liquid_surface_rate, pc.water_rate); swprop(M::liquid_surface_rate, pc.water_rate);
} }
if ((pc.gas_rate != 0.0) || (!predMode)) { if (pc.gas_rate != 0.0) {
sWell[Ix::GasRateTarget] = sWell[Ix::GasRateTarget] =
swprop(M::gas_surface_rate, pc.gas_rate); swprop(M::gas_surface_rate, pc.gas_rate);
sWell[Ix::HistGasRateTarget] = sWell[Ix::GasRateTarget]; 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] = sWell[Ix::LiqRateTarget] =
swprop(M::liquid_surface_rate, pc.liquid_rate); swprop(M::liquid_surface_rate, pc.liquid_rate);
sWell[Ix::HistLiqRateTarget] = sWell[Ix::LiqRateTarget]; sWell[Ix::HistLiqRateTarget] = sWell[Ix::LiqRateTarget];
} }
else { else if (!predMode) {
sWell[Ix::LiqRateTarget] = sWell[Ix::LiqRateTarget] =
swprop(M::liquid_surface_rate, pc.oil_rate + pc.water_rate); 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<Opm::Action::Result> act_res;
std::vector<std::string> 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 <class ZWellArray> template <class ZWellArray>
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; using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
zWell[Ix::WellName] = well.name(); 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 } // ZWell
} // Anonymous } // Anonymous
@ -828,14 +855,16 @@ captureDeclaredWellData(const Schedule& sched,
XWell::staticContrib(well, smry, units, xw); 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]; const auto actResStat = ZWell::act_res_stat(sched, smry, sim_step);
// Static contributions to ZWEL array.
ZWell::staticContrib(well, zw); wellLoop(wells,
}); [&actResStat, this](const Well& well, const std::size_t wellID) -> void
{
auto zw = this->zWell_[wellID];
ZWell::staticContrib(well, actResStat, zw);
});
}
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------

View File

@ -24,6 +24,7 @@
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp> #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp> #include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Units/Units.hpp> #include <opm/parser/eclipse/Units/Units.hpp>
@ -67,6 +68,45 @@ namespace {
return static_cast<double>(Opm::Metric::Time); return static_cast<double>(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 } // Anonymous
// ##################################################################### // #####################################################################
@ -82,14 +122,15 @@ createDoubHead(const EclipseState& es,
const double nextTimeStep) const double nextTimeStep)
{ {
const auto& usys = es.getDeckUnitSystem(); const auto& usys = es.getDeckUnitSystem();
//const auto& rspec = es.runspec(); const auto& rspec = es.runspec();
const auto tconv = getTimeConv(usys); const auto tconv = getTimeConv(usys);
auto dh = DoubHEAD{} auto dh = DoubHEAD{}
.tuningParameters(sched.getTuning(), lookup_step, tconv) .tuningParameters(sched.getTuning(), lookup_step, tconv)
.timeStamp (computeTimeStamp(sched, simTime)) .timeStamp (computeTimeStamp(sched, simTime))
.drsdt (sched, lookup_step, tconv) .drsdt (sched, lookup_step, tconv)
//.udq_param(rspec.udqParams()) .udq_param(rspec.udqParams())
.guide_rate_param(computeGuideRate(sched, lookup_step))
; ;
if (nextTimeStep > 0.0) { if (nextTimeStep > 0.0) {

View File

@ -28,6 +28,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
@ -43,6 +44,17 @@
#include <vector> #include <vector>
namespace { namespace {
using nph_enum = Opm::GuideRateModel::Target;
const std::map<nph_enum, int> 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, int maxConnPerWell(const Opm::Schedule& sched,
const std::size_t lookup_step) const std::size_t lookup_step)
{ {
@ -71,6 +83,65 @@ namespace {
// Number of non-FIELD groups. // Number of non-FIELD groups.
return ngmax - 1; 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<int>(group.production_cmode()) << std::endl;
gctrl = 1;
}
if (group.isInjectionGroup()) {
std::cout << "CrIH group.name()" << group.name() << " group.injection_cmode() " << static_cast<int>(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 Opm::RestartIO::InteHEAD::WellTableDim
getWellTableDims(const int nwgmax, 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& udq_par = rspec.udqParams();
const auto r_seed = udq_par.rand_seed(); const auto& udqActive = sched.udqActive(simStep);
const auto no_udq = udqcfg.size(); const auto r_seed = udq_par.rand_seed();
const auto no_wudq = noWellUdqs(sched, simStep);
return { r_seed, static_cast<int>(no_udq)}; 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<int>(no_wudq), static_cast<int>(no_gudq), static_cast<int>(no_fudq),
static_cast<int>(no_iuads), static_cast<int>(no_iuaps)};
} }
Opm::RestartIO::InteHEAD::ActionParam Opm::RestartIO::InteHEAD::ActionParam
@ -208,7 +287,7 @@ namespace {
const auto max_characters_per_line = rspec.actdims().max_characters(); const auto max_characters_per_line = rspec.actdims().max_characters();
return { static_cast<int>(no_act), max_lines_pr_action, static_cast<int>(max_cond_per_action), static_cast<int>(max_characters_per_line)}; return { static_cast<int>(no_act), max_lines_pr_action, static_cast<int>(max_cond_per_action), static_cast<int>(max_characters_per_line)};
}*/ }
Opm::RestartIO::InteHEAD::WellSegDims Opm::RestartIO::InteHEAD::WellSegDims
getWellSegDims(const ::Opm::Runspec& rspec, getWellSegDims(const ::Opm::Runspec& rspec,
@ -262,6 +341,30 @@ namespace {
static_cast<int>(nplmix), static_cast<int>(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 } // Anonymous
// ##################################################################### // #####################################################################
@ -279,8 +382,7 @@ createInteHead(const EclipseState& es,
{ {
const auto nwgmax = maxGroupSize(sched, lookup_step); const auto nwgmax = maxGroupSize(sched, lookup_step);
const auto ngmax = numGroupsInField(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& rspec = es.runspec();
const auto& tdim = es.getTableManager(); const auto& tdim = es.getTableManager();
const auto& rdim = tdim.getRegdims(); 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 // across a range of reference cases, but are not guaranteed to be
// universally valid. // universally valid.
.params_NWELZ (155, 122, 130, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL .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)) .params_GRPZ (getNGRPZ(nwgmax, ngmax, rspec))
// ncamax: max number of analytical aquifer connections // ncamax: max number of analytical aquifer connections
// n{isx}aaqz: number of data elements per aquifer in {ISX}AAQ // 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)) .wellSegDimensions (getWellSegDims(rspec, sched, lookup_step))
.regionDimensions (getRegDims(tdim, rdim)) .regionDimensions (getRegDims(tdim, rdim))
.ngroups ({ ngmax }) .ngroups ({ ngmax })
.variousParam (201702, 100) // Output should be compatible with Eclipse 100, 2017.02 version. .params_NGCTRL (GroupControl(sched,lookup_step))
//.udqParam_1 (getUdqParam(rspec, udqCfg)) .variousParam (201802, 100) // Output should be compatible with Eclipse 100, 2017.02 version.
//.actionParam (getActionParam(rspec, acts)) .udqParam_1 (getUdqParam(rspec, sched, lookup_step ))
.actionParam (getActionParam(rspec, acts))
.variousUDQ_ACTIONXParam()
.nominatedPhaseGuideRate(setGuideRateNominatedPhase(sched,lookup_step))
; ;
return ih.data(); return ih.data();

View File

@ -20,6 +20,7 @@
#include <opm/output/eclipse/AggregateUDQData.hpp> #include <opm/output/eclipse/AggregateUDQData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp> #include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/output/eclipse/InteHEAD.hpp> #include <opm/output/eclipse/InteHEAD.hpp>
#include <opm/output/eclipse/DoubHEAD.hpp> #include <opm/output/eclipse/DoubHEAD.hpp>
@ -39,6 +40,8 @@
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace { namespace {
@ -68,56 +71,10 @@ std::size_t entriesPerZUDL()
std::size_t noIGphs(const std::vector<int>& inteHead) std::size_t noIGphs(const std::vector<int>& 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; return no_entries;
} }
// maximum number of wells
std::size_t nwmaxz(const std::vector<int>& inteHead)
{
return inteHead[163];
}
// maximum number of groups
std::size_t ngmaxz(const std::vector<int>& 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 } // Anonymous
@ -132,23 +89,22 @@ createUdqDims(const Schedule& sched,
const std::vector<int>& inteHead) const std::vector<int>& inteHead)
{ {
const auto& udqCfg = sched.getUDQConfig(lookup_step); const auto& udqCfg = sched.getUDQConfig(lookup_step);
const auto& udqActive = sched.udqActive(lookup_step);
std::vector<int> udqDims; std::vector<int> udqDims;
udqDims.resize(13,0); udqDims.resize(13,0);
udqDims[ 0] = udqCfg.size(); udqDims[ 0] = udqCfg.size();
udqDims[ 1] = entriesPerIUDQ(); udqDims[ 1] = entriesPerIUDQ();
udqDims[ 2] = udqActive.IUAD_size(); udqDims[ 2] = inteHead[VI::intehead::NO_IUADS];
udqDims[ 3] = entriesPerIUAD(); udqDims[ 3] = entriesPerIUAD();
udqDims[ 4] = entriesPerZUDN(); udqDims[ 4] = entriesPerZUDN();
udqDims[ 5] = entriesPerZUDL(); udqDims[ 5] = entriesPerZUDL();
udqDims[ 6] = noIGphs(inteHead); udqDims[ 6] = noIGphs(inteHead);
udqDims[ 7] = udqActive.IUAP_size(); udqDims[ 7] = inteHead[VI::intehead::NO_IUAPS];
udqDims[ 8] = nwmaxz(inteHead); udqDims[ 8] = inteHead[VI::intehead::NWMAXZ];
udqDims[ 9] = noWellUdqs(sched, lookup_step); udqDims[ 9] = inteHead[VI::intehead::NO_WELL_UDQS];
udqDims[10] = ngmaxz(inteHead); udqDims[10] = inteHead[VI::intehead::NGMAXZ];
udqDims[11] = noGroupUdqs(sched, lookup_step); udqDims[11] = inteHead[VI::intehead::NO_GROUP_UDQS];
udqDims[12] = noFieldUdqs(sched, lookup_step); udqDims[12] = inteHead[VI::intehead::NO_FIELD_UDQS];
return udqDims; return udqDims;
} }

View File

@ -146,19 +146,19 @@ enum Index : std::vector<double>::size_type {
DdpLim = 84, DdpLim = 84,
DdsLim = 85, DdsLim = 85,
dh_086 = 86, dh_086 = 86,
dh_087 = 87, grpar_a = VI::doubhead::GRpar_a,
dh_088 = 88, grpar_b = VI::doubhead::GRpar_b,
dh_089 = 89, grpar_c = VI::doubhead::GRpar_c,
// 90..99 // 90..99
dh_090 = 90, grpar_d = VI::doubhead::GRpar_d,
dh_091 = 91, grpar_e = VI::doubhead::GRpar_e,
dh_092 = 92, grpar_f = VI::doubhead::GRpar_f,
dh_093 = 93, dh_093 = 93,
dh_094 = 94, dh_094 = 94,
dh_095 = 95, dh_095 = 95,
dh_096 = 96, dh_096 = 96,
dh_097 = 97, grpar_int = VI::doubhead::GRpar_int,
dh_098 = 98, dh_098 = 98,
ThrUPT = 99, ThrUPT = 99,
@ -215,7 +215,7 @@ enum Index : std::vector<double>::size_type {
dh_141 = 141, dh_141 = 141,
dh_142 = 142, dh_142 = 142,
dh_143 = 143, dh_143 = 143,
dh_144 = 144, grpar_dmp = VI::doubhead::GRpar_damp,
dh_145 = 145, dh_145 = 145,
dh_146 = 146, dh_146 = 146,
dh_147 = 147, dh_147 = 147,
@ -396,8 +396,8 @@ Opm::RestartIO::DoubHEAD::DoubHEAD()
this->data_[Index::dh_069] = -1.0; this->data_[Index::dh_069] = -1.0;
this->data_[Index::dh_080] = 1.0e+20; this->data_[Index::dh_080] = 1.0e+20;
this->data_[Index::dh_081] = 1.0e+20; this->data_[Index::dh_081] = 1.0e+20;
this->data_[Index::dh_091] = 0.0; this->data_[grpar_e] = 0.0;
this->data_[Index::dh_092] = 0.0; this->data_[grpar_f] = 0.0;
this->data_[Index::dh_093] = 0.0; this->data_[Index::dh_093] = 0.0;
this->data_[Index::dh_096] = 0.0; this->data_[Index::dh_096] = 0.0;
this->data_[Index::dh_105] = 1.0; this->data_[Index::dh_105] = 1.0;
@ -627,3 +627,18 @@ Opm::RestartIO::DoubHEAD::udq_param(const UDQParams& udqPar)
return *this; 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;
}

View File

@ -52,7 +52,7 @@ enum index : std::vector<int>::size_type {
ih_030 = 30 , // 0 0 ih_030 = 30 , // 0 0
ih_031 = 31 , // 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) 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 NXCONZ = VI::intehead::NXCONZ, // 58 0 58 NXCONZ = number of data elements per completion in XCON array
ih_035 = 35 , // 0 0 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 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<int>::size_type {
ih_048 = 48 , // 0 0 ih_048 = 48 , // 0 0
ih_049 = 49 , // 1 // has been determined by testing ih_049 = 49 , // 1 // has been determined by testing
ih_050 = 50 , // 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_052 = 52 , // 0 0
ih_053 = 53 , // 0 0 ih_053 = 53 , // 0 0
ih_054 = 54 , // 0 0 ih_054 = 54 , // 0 0
ih_055 = 55 , // 0 0 ih_055 = 55 , // 0 0
ih_056 = 56 , // 0 0 ih_056 = 56 , // 0 0
ih_057 = 57 , // 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_059 = 59 , // 0 0
ih_060 = 60 , // 0 0 ih_060 = 60 , // 0 0
ih_061 = 61 , // 0 0 ih_061 = 61 , // 0 0
@ -281,11 +281,11 @@ enum index : std::vector<int>::size_type {
ih_259 = 259 , // 0 ih_259 = 259 , // 0
ih_260 = 260 , // 0 ih_260 = 260 , // 0
ih_261 = 261 , // 0 ih_261 = 261 , // 0
ih_262 = 262 , // 0 NOFUDQS = VI::intehead::NO_FIELD_UDQS, // 0
ih_263 = 263 , // 0 NOGUDQS = VI::intehead::NO_GROUP_UDQS, // 0
ih_264 = 264 , // 0 ih_264 = 264 , // 0
ih_265 = 265 , // 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 UDQPAR_1 = VI::intehead::UDQPAR_1, // 0
ih_268 = 268 , // 0 ih_268 = 268 , // 0
ih_269 = 269 , // 0 ih_269 = 269 , // 0
@ -309,8 +309,8 @@ enum index : std::vector<int>::size_type {
ih_287 = 287 , // 0 ih_287 = 287 , // 0
ih_288 = 288 , // 0 ih_288 = 288 , // 0
ih_289 = 289 , // 0 ih_289 = 289 , // 0
ih_290 = 290 , // 0 NOIUADS = VI::intehead::NO_IUADS, // 0
ih_291 = 291 , // 0 NOIUAPS = VI::intehead::NO_IUAPS, // 0
ih_292 = 292 , // 0 ih_292 = 292 , // 0
ih_293 = 293 , // 0 ih_293 = 293 , // 0
ih_294 = 294 , // 0 ih_294 = 294 , // 0
@ -501,7 +501,7 @@ Opm::RestartIO::InteHEAD::wellTableDimensions(const WellTableDim& wtdim)
this->data_[NGMAXZ] = wtdim.maxGroupInField + 1; this->data_[NGMAXZ] = wtdim.maxGroupInField + 1;
//this->data_[NWMAXZ] = wtdim.maxWellsInField; this->data_[NWMAXZ] = wtdim.maxWellsInField;
return *this; return *this;
} }
@ -571,6 +571,15 @@ params_GRPZ(const std::array<int, 4>& grpz)
return *this; 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&
Opm::RestartIO::InteHEAD:: Opm::RestartIO::InteHEAD::
params_NAAQZ(const int ncamax, params_NAAQZ(const int ncamax,
@ -682,9 +691,13 @@ Opm::RestartIO::InteHEAD&
Opm::RestartIO::InteHEAD:: Opm::RestartIO::InteHEAD::
udqParam_1(const UdqParam& udq_par) udqParam_1(const UdqParam& udq_par)
{ {
this -> data_[UDQPAR_1] = - udq_par.udqParam_1; this -> data_[UDQPAR_1] = - udq_par.udqParam_1;
this -> data_[R_SEED] = - udq_par.udqParam_1; this -> data_[R_SEED] = - udq_par.udqParam_1;
this -> data_[NOUDQS] = udq_par.no_udqs; 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; return *this;
} }
@ -702,6 +715,31 @@ actionParam(const ActionParam& act_par)
return *this; 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) // Free functions (calendar/time utilities)
// ===================================================================== // =====================================================================

View File

@ -29,6 +29,8 @@
#include <opm/output/eclipse/AggregateConnectionData.hpp> #include <opm/output/eclipse/AggregateConnectionData.hpp>
#include <opm/output/eclipse/AggregateMSWData.hpp> #include <opm/output/eclipse/AggregateMSWData.hpp>
#include <opm/output/eclipse/AggregateUDQData.hpp> #include <opm/output/eclipse/AggregateUDQData.hpp>
#include <opm/output/eclipse/AggregateActionxData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp> #include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp> #include <opm/output/eclipse/VectorItems/intehead.hpp>
@ -232,6 +234,7 @@ namespace {
} }
void writeGroup(int sim_step, void writeGroup(int sim_step,
const UnitSystem& units,
const Schedule& schedule, const Schedule& schedule,
const Opm::SummaryState& sumState, const Opm::SummaryState& sumState,
const std::vector<int>& ih, const std::vector<int>& ih,
@ -242,7 +245,7 @@ namespace {
auto groupData = Helpers::AggregateGroupData(ih); 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("IGRP", groupData.getIGroup());
rstFile.write("SGRP", groupData.getSGroup()); rstFile.write("SGRP", groupData.getSGroup());
@ -278,10 +281,6 @@ namespace {
const std::vector<int>& ih, const std::vector<int>& ih,
EclIO::OutputStream::Restart& rstFile) 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 // write UDQ - data to restart file
const std::size_t simStep = static_cast<size_t> (sim_step); const std::size_t simStep = static_cast<size_t> (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<size_t> (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, void writeWell(int sim_step,
const bool ecl_compatible_rst, const bool ecl_compatible_rst,
const Phases& phases, const Phases& phases,
@ -538,7 +561,7 @@ void save(EclIO::OutputStream::Restart& rstFile,
writeHeader(sim_step, nextStepSize(value), seconds_elapsed, writeHeader(sim_step, nextStepSize(value), seconds_elapsed,
schedule, grid, es, rstFile); 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) // 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); writeSolution(value, schedule, sumState, sim_step, ecl_compatible_rst, write_double, inteHD, rstFile);
if (! ecl_compatible_rst) { if (! ecl_compatible_rst) {

View File

@ -18,6 +18,7 @@
*/ */
#include <vector> #include <vector>
#include <algorithm>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.hpp>
@ -43,11 +44,10 @@ Result::Result(bool result_arg, const WellSet& wells) :
Result::Result(const Result& src) Result::Result(const Result& src)
{ {
this->result = src.result; this->result = src.result;
if (src.matching_wells) if (src.matching_wells)
this->matching_wells.reset( new WellSet(*src.matching_wells) ); this->matching_wells.reset( new WellSet(*src.matching_wells) );
} }
Result::operator bool() const { Result::operator bool() const {
return this->result; return this->result;
} }
@ -59,7 +59,6 @@ std::vector<std::string> Result::wells() const {
return {}; return {};
} }
Result& Result::operator|=(const Result& other) { Result& Result::operator|=(const Result& other) {
this->result = this->result || other.result; this->result = this->result || other.result;
@ -84,6 +83,14 @@ Result& Result::operator&=(const Result& other) {
return *this; 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) { void Result::assign(bool value) {
this->result = value; this->result = value;
} }
@ -94,7 +101,7 @@ void Result::add_well(const std::string& well) {
this->matching_wells->add(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) if (!this->matching_wells)
return false; return false;

View File

@ -309,6 +309,9 @@ Phase Group::injection_phase() const {
return this->injection_properties.phase; return this->injection_properties.phase;
} }
const Group::GroupType& Group::getGroupType() const {
return this-> group_type;
}
bool Group::ProductionControls::has_control(Group::ProductionCMode control) const { bool Group::ProductionControls::has_control(Group::ProductionCMode control) const {
return (this->production_controls & static_cast<int>(control)) != 0; return (this->production_controls & static_cast<int>(control)) != 0;

View File

@ -175,6 +175,30 @@ double GuideRateModel::damping_factor() const {
return this->damping_factor_; 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 { bool GuideRateModel::allow_increase() const {
return this->allow_increase_; return this->allow_increase_;
} }

View File

@ -415,7 +415,7 @@ ACTIONX
ACT02 11 / ACT02 11 /
FMWPR > 25 AND / FMWPR > 25 AND /
WGPR 'OPL02' > GGPR 'LOWER' AND / WGPR 'OPL02' > GGPR 'LOWER' AND /
MNTH > MAY / MNTH > NOV /
/ /
WELOPEN WELOPEN
'?' 'SHUT' 0 0 0 2* / '?' 'SHUT' 0 0 0 2* /
@ -441,19 +441,12 @@ WELOPEN
/ /
ENDACTIO ENDACTIO
WELOPEN
'OPL01' 'OPEN' 5* /
/
DATES
1 'OCT' 2018 /
/
--start files/actionxprod.tmpl --start files/actionxprod.tmpl
ACTIONX ACTIONX
ACT01 10 / ACT01 10 /
FMWPR > 45 AND / FMWPR > 45 AND /
WUPR3 'OP*' > 46 OR / WUPR3 'OP*' > 46 OR /
MNTH > JUN / MNTH > OCT /
/ /
WELOPEN WELOPEN
'?' SHUT 0 0 0 2* / '?' SHUT 0 0 0 2* /
@ -466,6 +459,14 @@ WELOPEN
/ /
ENDACTIO ENDACTIO
WELOPEN
'OPL01' 'OPEN' 5* /
/
DATES
1 'OCT' 2018 /
/
WELOPEN WELOPEN
'WIL01' 'OPEN' 5* / 'WIL01' 'OPEN' 5* /

View File

@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims);
actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep); actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep);
#if 0 /*rstFile.write("INTEHEAD", ih);
rstFile.write("IUDQ", udqData.getIUDQ()); rstFile.write("IUDQ", udqData.getIUDQ());
rstFile.write("IUAD", udqData.getIUAD()); rstFile.write("IUAD", udqData.getIUAD());
rstFile.write("IGPH", udqData.getIGPH()); rstFile.write("IGPH", udqData.getIGPH());
@ -162,10 +162,8 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
rstFile.write("ZLACT", actionxData.getZLACT()); rstFile.write("ZLACT", actionxData.getZLACT());
rstFile.write("ZACN", actionxData.getZACN()); rstFile.write("ZACN", actionxData.getZACN());
rstFile.write("IACN", actionxData.getIACN()); rstFile.write("IACN", actionxData.getIACN());
rstFile.write("SACN", actionxData.getSACN()); rstFile.write("SACN", actionxData.getSACN()); */
#endif
#if 0
{ {
/* /*
Check of InteHEAD and DoubHEAD data for UDQ variables Check of InteHEAD and DoubHEAD data for UDQ variables
@ -201,8 +199,6 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
} }
#endif
{ {
/* /*
IACT IACT
@ -526,11 +522,11 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
BOOST_CHECK_EQUAL(sAcn[start + 1] , 0); BOOST_CHECK_EQUAL(sAcn[start + 1] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 2] , 17); BOOST_CHECK_EQUAL(sAcn[start + 2] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 3] , 0); 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 + 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 + 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 + 9] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 10] , 0); BOOST_CHECK_EQUAL(sAcn[start + 10] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 11] , 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); BOOST_CHECK_EQUAL(sAcn[start + 15] , 0);
} }
#if 0
#endif
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,564 @@
#define BOOST_TEST_MODULE UDQ-ACTIONX_Data
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/output/eclipse/AggregateUDQData.hpp>
#include <opm/output/eclipse/AggregateActionxData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/InteHEAD.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/output/eclipse/DoubHEAD.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/io/eclipse/OutputStream.hpp>
#include <stdexcept>
#include <utility>
#include <exception>
#include <iostream>
#include <string>
#include <vector>
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()

View File

@ -498,10 +498,10 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data)
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{4}); BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{4});
const auto smry = sim_state(); const auto smry = sim_state();
const auto& units = simCase.es.getUnits();
auto agrpd = Opm::RestartIO::Helpers::AggregateGroupData{ih.value}; auto agrpd = Opm::RestartIO::Helpers::AggregateGroupData{ih.value};
agrpd.captureDeclaredGroupData(simCase.sched, agrpd.captureDeclaredGroupData(simCase.sched, units, rptStep, smry,
rptStep, smry, ih.value);
ih.value);
// IGRP (PROD) // IGRP (PROD)
{ {

View File

@ -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[212] , 1.0E+20);
BOOST_CHECK_EQUAL(dh[213] , 0.0); BOOST_CHECK_EQUAL(dh[213] , 0.0);
BOOST_CHECK_EQUAL(dh[214] , 1.0E-4); */ BOOST_CHECK_EQUAL(dh[214] , 1.0E-4);
} }