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/io/eclipse/PaddedOutputString.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
#include <cstddef>
#include <string>
#include <vector>
@ -32,7 +32,8 @@
namespace Opm {
class Schedule;
class SummaryState;
class Group;
//class Group;
class UnitSystem;
} // Opm
namespace Opm { namespace RestartIO { namespace Helpers {
@ -43,6 +44,7 @@ public:
explicit AggregateGroupData(const std::vector<int>& inteHead);
void captureDeclaredGroupData(const Opm::Schedule& sched,
const Opm::UnitSystem& units,
const std::size_t simStep,
const Opm::SummaryState& sumState,
const std::vector<int>& inteHead);
@ -105,6 +107,19 @@ public:
{"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 = {
{"FOPR", 0},
{"FWPR", 1},

View File

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

View File

@ -40,6 +40,17 @@ namespace Opm { namespace RestartIO {
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() = default;
@ -61,6 +72,7 @@ namespace Opm { namespace RestartIO {
const double cnvT);
DoubHEAD& udq_param(const UDQParams& udqPar);
DoubHEAD& guide_rate_param(const guideRate& guide_rp);
const std::vector<double>& data() const
{

View File

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

View File

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

View File

@ -30,6 +30,14 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
TsInit = 1, // Maximum Length of Next Timestep
TsMaxz = 2, // Maximum Length of Timestep After Next
TsMinz = 3, // Minumum Length of All Timesteps
GRpar_a = 87, // Guiderate parameter A
GRpar_b = 88, // Guiderate parameter B
GRpar_c = 89, // Guiderate parameter C
GRpar_d = 90, // Guiderate parameter D
GRpar_e = 91, // Guiderate parameter E
GRpar_f = 92, // Guiderate parameter F
GRpar_int = 97, // Guiderate parameter delay interval
GRpar_damp = 144, // Guiderate parameter damping factor
UdqPar_2 = 212, // UDQPARAM item number 2 (Permitted range (+/-) of user-defined quantities)
UdqPar_3 = 213, // UDQPARAM item number 3 (Value given to undefined elements when outputting data)
UdqPar_4 = 214, // UDQPARAM item number 4 (fractional equality tolerance used in ==, <= etc. functions)

View File

@ -24,6 +24,30 @@
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 {
enum index : std::vector<double>::size_type {
OilPrRate = 0, // Group's oil production rate

View File

@ -76,6 +76,10 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
NSCAQZ = 46, // Number of data elements per aquifer connection in SCAQ array
NACAQZ = 47, // Number of data elements per aquifer connection in ACAQ array
NGCTRL = 51, // Index indicating if group control is used or not (1 - if group control, 0 if not)
NGRNPH = 58, // Index indicating if group control is used or not (1 - if group control, 0 if not)
DAY = 64, // Calendar day of report step (1..31)
MONTH = 65, // Calendar month of report step (1..12)
YEAR = 66, // Calendar year of report step
@ -96,11 +100,14 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
NILBRZ = 180, // Number of entries per segment in ILBR array
MAX_ACT_COND = 245, // Maximum number of conditions pr action
MAX_AN_AQUIFERS = 252, // Maximum number of analytic aquifers
NO_UDQS = 266, // No of UDQ data (parameters)
UDQPAR_1 = 267, // Integer seed value for the RAND
NO_FIELD_UDQS = 262, // No of Field UDQ data (parameters) /
NO_GROUP_UDQS = 263, // No of Group UDQ data (parameters) /
NO_WELL_UDQS = 266, // No of Well UDQ data (parameters) /
UDQPAR_1 = 267, // Integer seed value for the RAND /
NO_IUADS = 290, // No IUADs
NO_IUAPS = 291, // No IUAPs
RSEED = 296,
};
}}}} // Opm::RestartIO::Helpers::VectorItems

View File

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

View File

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

View File

@ -95,11 +95,15 @@ public:
explicit operator bool() 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);
Result& operator|=(const Result& other);
Result& operator=(const Result& src);
Result& operator&=(const Result& other);
private:
void assign(bool value);
bool result;

View File

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

View File

@ -62,6 +62,12 @@ public:
bool operator==(const GuideRateModel& other) const;
bool operator!=(const GuideRateModel& other) const;
Target target() const;
double getA() const;
double getB() const;
double getC() const;
double getD() const;
double getE() const;
double getF() const;
static Target convert_target(Group::GuideRateTarget group_target);
static Target convert_target(Well::GuideRateTarget well_target);

View File

@ -19,6 +19,7 @@
#include <opm/output/eclipse/AggregateActionxData.hpp>
#include <opm/output/eclipse/AggregateGroupData.hpp>
#include <opm/output/eclipse/AggregateWellData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.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/UDQDefine.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/UDQ/UDQEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
@ -42,7 +46,7 @@
#include <iostream>
// #####################################################################
// Class Opm::RestartIO::Helpers::AggregateGroupData
// Class Opm::RestartIO::Helpers
// ---------------------------------------------------------------------
@ -56,6 +60,25 @@ namespace {
{"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 = {
{"JAN", 1.},
{"FEB", 2.},
@ -109,9 +132,12 @@ namespace {
allocate(const std::vector<int>& actDims)
{
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[1], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[1]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -122,8 +148,18 @@ namespace {
iAct[0] = 0;
//item [1]: The number of lines of schedule data including ENDACTIO
iAct[1] = actx.keyword_strings().size();
//item [2]: is unknown, (=1)
iAct[2] = 1;
//item [2]: is = 1 for condition and previous condition = AND, and combinations OR/AND
// is = 2 for all conditions and previous conditions = OR
// This is not implemented yet - only use 1 for all cases
const auto& actx_cond = actx.conditions();
int i_temp = 2;
for (auto cond_it = actx_cond.begin(); cond_it < actx_cond.end(); cond_it++) {
const auto it_logic_17 = logicalToIndex_17.find(cond_it->logic);
if (it_logic_17 != logicalToIndex_17.end()) {
if (it_logic_17->first == logic_enum::AND) i_temp = 1;
}
}
iAct[2] = i_temp;
//item [3]: is unknown, (=7)
iAct[3] = 7;
//item [4]: is unknown, (=0)
@ -146,9 +182,12 @@ namespace {
allocate(const std::vector<int>& actDims)
{
using WV = Opm::RestartIO::Helpers::WindowedArray<float>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[2], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[2]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -174,9 +213,11 @@ namespace {
Opm::EclIO::PaddedOutputString<8>
>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[3], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[3]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -198,10 +239,11 @@ namespace {
using WV = Opm::RestartIO::Helpers::WindowedArray<
Opm::EclIO::PaddedOutputString<8>
>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[4], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[4]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -243,9 +285,11 @@ namespace {
Opm::EclIO::PaddedOutputString<8>
>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[5], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[5]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -292,17 +336,18 @@ namespace {
}
} // zAcn
}
namespace iACN {
Opm::RestartIO::Helpers::WindowedArray<int>
allocate(const std::vector<int>& actDims)
{
using WV = Opm::RestartIO::Helpers::WindowedArray<int>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[6], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[6]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
WV::WindowSize{ static_cast<std::size_t>(nitPrWin) }
};
}
@ -352,13 +397,13 @@ namespace {
iAcn[ind + 11] = it_rhsq->second;
}
/*item[12] - index for lhs type
1 - for MNTH
0 - for all other types
/*item[12] - index for relational operator (<, =, > )
0 - for LHS quantity greater RHS quantity
1 - for LHS quantity less than or equal to RHS quantity
*/
std::string lhsQ = z_data.lhs.quantity;
if ( lhsQ == "MNTH") {
iAcn[ind + 12] = 1;
const auto it_lhs_it = cmpToIacn_12.find(z_data.cmp);
if (it_lhs_it != cmpToIacn_12.end()) {
iAcn[ind + 12] = it_lhs_it->second;
}
/*item [13] - relates to operator
@ -424,42 +469,62 @@ namespace {
allocate(const std::vector<int>& actDims)
{
using WV = Opm::RestartIO::Helpers::WindowedArray<double>;
int nwin = std::max(actDims[0], 1);
int nitPrWin = std::max(actDims[7], 1);
return WV {
WV::NumWindows{ static_cast<std::size_t>(actDims[0]) },
WV::WindowSize{ static_cast<std::size_t>(actDims[7]) }
WV::NumWindows{ static_cast<std::size_t>(nwin) },
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>
void staticContrib(const Opm::Action::ActionX& actx,
void staticContrib(std::vector<Opm::Action::ActionX>::const_iterator actx_it,
const Opm::SummaryState& st,
const Opm::Schedule& sched,
const std::size_t simStep,
SACNArray& sAcn)
{
std::size_t ind = 0;
int noEPZacn = 16;
double undef_high_val = 1.0E+20;
const auto& wells = sched.getWells(simStep);
const auto ar = sACN::act_res(sched, st, simStep, actx_it);
// write out the schedule Actionx conditions
const auto& actx_cond = actx.conditions();
const auto& actx_cond = actx_it->conditions();
for (const auto& z_data : actx_cond) {
// item [0 - 1] = 0 (unknown)
sAcn[ind + 0] = 0.;
sAcn[ind + 1] = 0.;
//item [2, 5, 7, 9]: value of condition 1 (zero if well, group or field variable
const std::string& lhsQtype = z_data.lhs.quantity.substr(0,1);
const std::string& rhsQtype = z_data.rhs.quantity.substr(0,1);
//item [2, 5, 7, 9]: value of condition 1 (zero if well, group or field variable
const auto& it_rhsq = rhsQuantityToIndex.find(rhsQtype);
if (it_rhsq == rhsQuantityToIndex.end()) {
//come here if constant value condition
double t_val = 0.;
if (rhsQtype == "M") {
if (lhsQtype == "M") {
const auto& it_mnth = monthToNo.find(z_data.rhs.quantity);
if (it_mnth != monthToNo.end()) {
t_val = it_mnth->second;
}
else {
std::cout << "Unknown Month: " << z_data.rhs.quantity << std::endl;
throw std::invalid_argument("Actionx: " + actx.name() + " Condition: " + z_data.lhs.quantity );
throw std::invalid_argument("Actionx: " + actx_it->name() + " Condition: " + z_data.lhs.quantity );
}
}
else {
@ -470,39 +535,33 @@ namespace {
sAcn[ind + 7] = sAcn[ind + 2];
sAcn[ind + 9] = sAcn[ind + 2];
}
//Treat well, group and field right hand side conditions
if (it_rhsq != rhsQuantityToIndex.end()) {
//Well variable
if (it_rhsq->first == "W") {
sAcn[ind + 4] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
if ((it_rhsq->first == "W") && (st.has_well_var(z_data.rhs.args[0], z_data.rhs.quantity))) {
sAcn[ind + 5] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 6] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 7] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 8] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 9] = st.get_well_var(z_data.rhs.args[0], z_data.rhs.quantity);
}
//group variable
if (it_rhsq->first == "G") {
sAcn[ind + 4] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
if ((it_rhsq->first == "G") && (st.has_group_var(z_data.rhs.args[0], z_data.rhs.quantity))) {;
sAcn[ind + 5] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 6] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 7] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 8] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
sAcn[ind + 9] = st.get_group_var(z_data.rhs.args[0], z_data.rhs.quantity);
}
//field variable
if (it_rhsq->first == "F") {
sAcn[ind + 4] = st.get(z_data.rhs.quantity);
if ((it_rhsq->first == "F") && (st.has(z_data.rhs.quantity))) {
sAcn[ind + 5] = st.get(z_data.rhs.quantity);
sAcn[ind + 6] = st.get(z_data.rhs.quantity);
sAcn[ind + 7] = st.get(z_data.rhs.quantity);
sAcn[ind + 8] = st.get(z_data.rhs.quantity);
sAcn[ind + 9] = st.get(z_data.rhs.quantity);
}
}
//treat cases with left hand side condition being: DAY, MNTH og YEAR variable
const std::string& lhsQtype = z_data.lhs.quantity.substr(0,1);
const auto& it_lhsq = lhsQuantityToIndex.find(lhsQtype);
if ((it_lhsq->first == "D") || (it_lhsq->first == "M") || (it_lhsq->first == "Y")) {
sAcn[ind + 4] = undef_high_val;
@ -513,6 +572,41 @@ namespace {
sAcn[ind + 9] = undef_high_val;
}
//Treat well, group and field left hand side conditions
if (it_lhsq != lhsQuantityToIndex.end()) {
std::string wn = "";
//Well variable
if (it_lhsq->first == "W") {
//find the well that violates action if relevant
for (const auto& well : wells)
{
if (ar.has_well(well.name())) {
//set well name
wn = well.name();
break;
}
}
if ((it_lhsq->first == "W") && (st.has_well_var(wn, z_data.lhs.quantity)) ) {
sAcn[ind + 4] = st.get_well_var(wn, z_data.lhs.quantity);
sAcn[ind + 6] = st.get_well_var(wn, z_data.lhs.quantity);
sAcn[ind + 8] = st.get_well_var(wn, z_data.lhs.quantity);
}
}
//group variable
if ((it_lhsq->first == "G") && (st.has_group_var(z_data.lhs.args[0], z_data.lhs.quantity))) {
sAcn[ind + 4] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity);
sAcn[ind + 6] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity);
sAcn[ind + 8] = st.get_group_var(z_data.lhs.args[0], z_data.lhs.quantity);
}
//field variable
if ((it_lhsq->first == "F") && (st.has(z_data.lhs.quantity))) {
sAcn[ind + 4] = st.get(z_data.lhs.quantity);
sAcn[ind + 6] = st.get(z_data.lhs.quantity);
sAcn[ind + 8] = st.get(z_data.lhs.quantity);
}
}
//increment index according to no of items pr condition
ind += static_cast<std::size_t>(noEPZacn);
}
@ -520,7 +614,7 @@ namespace {
} // sAcn
}
// =====================================================================
Opm::RestartIO::Helpers::AggregateActionxData::
@ -543,7 +637,7 @@ captureDeclaredActionxData( const Opm::Schedule& sched,
const std::vector<int>& actDims,
const std::size_t simStep)
{
auto acts = sched.actions(simStep);
const auto acts = sched.actions(simStep);
std::size_t act_ind = 0;
for (auto actx_it = acts.begin(); actx_it < acts.end(); actx_it++) {
{
@ -578,7 +672,7 @@ captureDeclaredActionxData( const Opm::Schedule& sched,
{
auto s_acn = this->sACN_[act_ind];
sACN::staticContrib(*actx_it, st, s_acn);
sACN::staticContrib(actx_it, st, sched, simStep, s_acn);
}
act_ind +=1;

View File

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

View File

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

View File

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

View File

@ -17,9 +17,12 @@
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/AggregateGroupData.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/Runspec.hpp>
@ -46,7 +49,7 @@
// Class Opm::RestartIO::Helpers::AggregateGroupData
// ---------------------------------------------------------------------
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace {
// maximum number of groups
@ -56,12 +59,36 @@ namespace {
}
// maximum number of wells
/*std::size_t nwmaxz(const std::vector<int>& inteHead)
std::size_t nwmaxz(const std::vector<int>& inteHead)
{
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 {
@ -80,8 +107,10 @@ namespace {
void staticContrib(const Opm::UDQInput& udq_input, IUDQArray& iUdq)
{
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[1] = -4;
iUdq[1] = define_type(tokens);
} else {
iUdq[0] = 0;
iUdq[1] = -4;
@ -442,6 +471,8 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
const std::vector<int>& inteHead)
{
const auto& udqCfg = sched.getUDQConfig(simStep);
const auto nudq = inteHead[VI::intehead::NO_WELL_UDQS] + inteHead[VI::intehead::NO_GROUP_UDQS] + inteHead[VI::intehead::NO_FIELD_UDQS];
int cnt_udq = 0;
for (const auto& udq_input : udqCfg.input()) {
auto udq_index = udq_input.index.insert_index;
{
@ -456,66 +487,119 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
auto z_udl = this->zUDL_[udq_index];
zUdl::staticContrib(udq_input, z_udl);
}
cnt_udq += 1;
}
if (cnt_udq != nudq) {
std::stringstream str;
str << "Inconsistent total number of udqs: " << cnt_udq << " and sum of well, group and field udqs: " << nudq;
OpmLog::error(str.str());
}
auto udq_active = sched.udqActive(simStep);
if (udq_active) {
const auto& udq_records = udq_active.get_iuad();
int cnt_iuad = 0;
for (std::size_t index = 0; index < udq_records.size(); index++) {
const auto& record = udq_records[index];
auto i_uad = this->iUAD_[index];
iUad::staticContrib(record, i_uad);
cnt_iuad += 1;
}
if (cnt_iuad != inteHead[VI::intehead::NO_IUADS]) {
std::stringstream str;
str << "Inconsistent number of iuad's: " << cnt_iuad << " number of iuad's from intehead " << inteHead[VI::intehead::NO_IUADS];
OpmLog::error(str.str());
}
const auto& iuap_records = udq_active.get_iuap();
int cnt_iuap = 0;
const auto iuap_vect = iuap_data(sched, simStep,iuap_records);
for (std::size_t index = 0; index < iuap_vect.size(); index++) {
const auto& wg_no = iuap_vect[index];
auto i_uap = this->iUAP_[index];
iUap::staticContrib(wg_no, i_uap);
cnt_iuap += 1;
}
if (cnt_iuap != inteHead[VI::intehead::NO_IUAPS]) {
std::stringstream str;
str << "Inconsistent number of iuap's: " << cnt_iuap << " number of iuap's from intehead " << inteHead[VI::intehead::NO_IUAPS];
OpmLog::error(str.str());
}
}
if (inteHead[VI::intehead::NO_GROUP_UDQS] > 0) {
Opm::RestartIO::Helpers::igphData igph_dat;
int cnt_igph = 0;
auto igph = igph_dat.ig_phase(sched, simStep, inteHead);
for (std::size_t index = 0; index < igph.size(); index++) {
auto i_igph = this->iGPH_[index];
iGph::staticContrib(igph[index], i_igph);
cnt_igph += 1;
}
#if 0
if (cnt_igph != inteHead[VI::intehead::NGMAXZ]) {
std::stringstream str;
str << "Inconsistent number of igph's: " << cnt_igph << " number of igph's from intehead " << inteHead[VI::intehead::NGMAXZ];
OpmLog::error(str.str());
}
}
std::size_t i_wudq = 0;
const auto& wnames = sched.wellNames(simStep);
const auto nwmax = nwmaxz(inteHead);
int cnt_dudw = 0;
for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::WELL_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudw = this->dUDW_[i_wudq];
dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw);
i_wudq++;
cnt_dudw += 1;
}
}
#endif
if (cnt_dudw != inteHead[VI::intehead::NO_WELL_UDQS]) {
std::stringstream str;
str << "Inconsistent number of dudw's: " << cnt_dudw << " number of dudw's from intehead " << inteHead[VI::intehead::NO_WELL_UDQS];
OpmLog::error(str.str());
}
std::size_t i_gudq = 0;
const auto curGroups = currentGroups(sched, simStep, inteHead);
const auto ngmax = ngmaxz(inteHead);
int cnt_dudg = 0;
for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::GROUP_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudg = this->dUDG_[i_gudq];
dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg);
i_gudq++;
cnt_dudg += 1;
}
}
if (cnt_dudg != inteHead[VI::intehead::NO_GROUP_UDQS]) {
std::stringstream str;
str << "Inconsistent number of dudg's: " << cnt_dudg << " number of dudg's from intehead " << inteHead[VI::intehead::NO_GROUP_UDQS];
OpmLog::error(str.str());
}
std::size_t i_fudq = 0;
int cnt_dudf = 0;
for (const auto& udq_input : udqCfg.input()) {
if (udq_input.var_type() == UDQVarType::FIELD_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudf = this->dUDF_[i_fudq];
dUdf::staticContrib(st, udq, i_dudf);
i_fudq++;
cnt_dudf += 1;
}
}
if (cnt_dudf != inteHead[VI::intehead::NO_FIELD_UDQS]) {
std::stringstream str;
str << "Inconsistent number of dudf's: " << cnt_dudf << " number of dudf's from intehead " << inteHead[VI::intehead::NO_FIELD_UDQS];
OpmLog::error(str.str());
}
}

View File

@ -31,6 +31,11 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.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 <cassert>
@ -73,6 +78,9 @@ namespace {
return s.substr(b, e - b + 1);
}
template <typename WellOp>
void wellLoop(const std::vector<Opm::Well>& wells,
WellOp&& wellOp)
@ -407,11 +415,11 @@ namespace {
zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2)
infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3)
one , zero , zero , zero , zero , zero , // 24.. 29 ( 4)
zero , one , zero , zero, zero , zero , // 30.. 35 ( 5)
zero , one , zero , infty, zero , zero , // 30.. 35 ( 5)
zero , zero , zero , zero , zero , zero , // 36.. 41 ( 6)
zero , zero , zero , zero , zero , zero , // 42.. 47 ( 7)
zero , zero , zero , zero , zero , zero , // 48.. 53 ( 8)
zero, zero , zero , zero , zero , zero , // 54.. 59 ( 9)
infty, zero , zero , zero , zero , zero , // 54.. 59 ( 9)
zero , zero , zero , zero , zero , zero , // 60.. 65 (10)
zero , zero , zero , zero , zero , zero , // 66.. 71 (11)
zero , zero , zero , zero , zero , zero , // 72.. 77 (12)
@ -460,28 +468,28 @@ namespace {
const auto& pc = well.productionControls(smry);
const auto& predMode = well.predictionMode();
if ((pc.oil_rate != 0.0) || (!predMode)) {
if (pc.oil_rate != 0.0) {
sWell[Ix::OilRateTarget] =
swprop(M::liquid_surface_rate, pc.oil_rate);
}
if ((pc.water_rate != 0.0) || (!predMode)) {
if (pc.water_rate != 0.0) {
sWell[Ix::WatRateTarget] =
swprop(M::liquid_surface_rate, pc.water_rate);
}
if ((pc.gas_rate != 0.0) || (!predMode)) {
if (pc.gas_rate != 0.0) {
sWell[Ix::GasRateTarget] =
swprop(M::gas_surface_rate, pc.gas_rate);
sWell[Ix::HistGasRateTarget] = sWell[Ix::GasRateTarget];
}
if (pc.liquid_rate != 0.0 || (!predMode)) {
if (pc.liquid_rate != 0.0) { // check if this works - may need to be rewritten
sWell[Ix::LiqRateTarget] =
swprop(M::liquid_surface_rate, pc.liquid_rate);
sWell[Ix::HistLiqRateTarget] = sWell[Ix::LiqRateTarget];
}
else {
else if (!predMode) {
sWell[Ix::LiqRateTarget] =
swprop(M::liquid_surface_rate, pc.oil_rate + pc.water_rate);
}
@ -761,12 +769,31 @@ namespace {
};
}
Opm::RestartIO::Helpers::ActionResStatus
act_res_stat(const Opm::Schedule& sched, const Opm::SummaryState& smry, const std::size_t sim_step) {
std::vector<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>
void staticContrib(const Opm::Well& well, ZWellArray& zWell)
void staticContrib(const Opm::Well& well, const Opm::RestartIO::Helpers::ActionResStatus& actResStat, ZWellArray& zWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
zWell[Ix::WellName] = well.name();
//loop over actions to assign action name for relevant wells
for (std::size_t ind = 0; ind < actResStat.result.size(); ind++) {
if (actResStat.result[ind].has_well(well.name())) {
zWell[Ix::ActionX] = actResStat.name[ind];
}
}
}
} // ZWell
} // Anonymous
@ -828,15 +855,17 @@ captureDeclaredWellData(const Schedule& sched,
XWell::staticContrib(well, smry, units, xw);
});
{
const auto actResStat = ZWell::act_res_stat(sched, smry, sim_step);
// Static contributions to ZWEL array.
wellLoop(wells,
[this](const Well& well, const std::size_t wellID) -> void
[&actResStat, this](const Well& well, const std::size_t wellID) -> void
{
auto zw = this->zWell_[wellID];
ZWell::staticContrib(well, zw);
ZWell::staticContrib(well, actResStat, zw);
});
}
}
// ---------------------------------------------------------------------

View File

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

View File

@ -28,6 +28,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.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/UDQActive.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/Tuning.hpp>
@ -43,6 +44,17 @@
#include <vector>
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,
const std::size_t lookup_step)
{
@ -72,6 +84,65 @@ namespace {
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
getWellTableDims(const int nwgmax,
const int ngmax,
@ -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& udqActive = sched.udqActive(simStep);
const auto r_seed = udq_par.rand_seed();
const auto no_udq = udqcfg.size();
const auto no_wudq = noWellUdqs(sched, simStep);
const auto no_gudq = noGroupUdqs(sched, simStep);
const auto no_fudq = noFieldUdqs(sched, simStep);
const auto no_iuads = udqActive.IUAD_size();
const auto no_iuaps = udqActive.IUAP_size();
return { r_seed, static_cast<int>(no_udq)};
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
@ -208,7 +287,7 @@ namespace {
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)};
}*/
}
Opm::RestartIO::InteHEAD::WellSegDims
getWellSegDims(const ::Opm::Runspec& rspec,
@ -262,6 +341,30 @@ namespace {
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
// #####################################################################
@ -279,8 +382,7 @@ createInteHead(const EclipseState& es,
{
const auto nwgmax = maxGroupSize(sched, lookup_step);
const auto ngmax = numGroupsInField(sched, lookup_step);
//const auto& udqCfg = sched.getUDQConfig(lookup_step);
//const auto& acts = sched.actions(lookup_step);
const auto& acts = sched.actions(lookup_step);
const auto& rspec = es.runspec();
const auto& tdim = es.getTableManager();
const auto& rdim = tdim.getRegdims();
@ -297,7 +399,7 @@ createInteHead(const EclipseState& es,
// across a range of reference cases, but are not guaranteed to be
// universally valid.
.params_NWELZ (155, 122, 130, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL
.params_NCON (25, 40, 58) // n{isx}conz: number of data elements per completion in ICON
.params_NCON (25, 41, 58) // n{isx}conz: number of data elements per completion in ICON
.params_GRPZ (getNGRPZ(nwgmax, ngmax, rspec))
// ncamax: max number of analytical aquifer connections
// n{isx}aaqz: number of data elements per aquifer in {ISX}AAQ
@ -308,9 +410,12 @@ createInteHead(const EclipseState& es,
.wellSegDimensions (getWellSegDims(rspec, sched, lookup_step))
.regionDimensions (getRegDims(tdim, rdim))
.ngroups ({ ngmax })
.variousParam (201702, 100) // Output should be compatible with Eclipse 100, 2017.02 version.
//.udqParam_1 (getUdqParam(rspec, udqCfg))
//.actionParam (getActionParam(rspec, acts))
.params_NGCTRL (GroupControl(sched,lookup_step))
.variousParam (201802, 100) // Output should be compatible with Eclipse 100, 2017.02 version.
.udqParam_1 (getUdqParam(rspec, sched, lookup_step ))
.actionParam (getActionParam(rspec, acts))
.variousUDQ_ACTIONXParam()
.nominatedPhaseGuideRate(setGuideRateNominatedPhase(sched,lookup_step))
;
return ih.data();

View File

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

View File

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

View File

@ -52,7 +52,7 @@ enum index : std::vector<int>::size_type {
ih_030 = 30 , // 0 0
ih_031 = 31 , // 0 0
NICONZ = VI::intehead::NICONZ, // 25 15 25 NICON = no of data elements per completion in ICON array (default 19)
NSCONZ = VI::intehead::NSCONZ, // 40 0 NSCONZ = number of data elements per completion in SCON array
NSCONZ = VI::intehead::NSCONZ, // 41 0 NSCONZ = number of data elements per completion in SCON array
NXCONZ = VI::intehead::NXCONZ, // 58 0 58 NXCONZ = number of data elements per completion in XCON array
ih_035 = 35 , // 0 0
NIGRPZ = VI::intehead::NIGRPZ, // 97+intehead_array[19] 0 97 + intehead[19] NIGRPZ = no of data elements per group in IGRP array
@ -70,14 +70,14 @@ enum index : std::vector<int>::size_type {
ih_048 = 48 , // 0 0
ih_049 = 49 , // 1 // has been determined by testing
ih_050 = 50 , // 1 // has been determined by testing
ih_051 = 51 , // 0 0
NGCONT = VI::intehead::NGCTRL, // 0 - no group control, 1 if GCONPROD, 2 if GCONINJE
ih_052 = 52 , // 0 0
ih_053 = 53 , // 0 0
ih_054 = 54 , // 0 0
ih_055 = 55 , // 0 0
ih_056 = 56 , // 0 0
ih_057 = 57 , // 0 0
ih_058 = 58 , // 0 0
NGRNPHASE = VI::intehead::NGRNPH, // Parameter to determine the nominated phase for the guiderate
ih_059 = 59 , // 0 0
ih_060 = 60 , // 0 0
ih_061 = 61 , // 0 0
@ -281,11 +281,11 @@ enum index : std::vector<int>::size_type {
ih_259 = 259 , // 0
ih_260 = 260 , // 0
ih_261 = 261 , // 0
ih_262 = 262 , // 0
ih_263 = 263 , // 0
NOFUDQS = VI::intehead::NO_FIELD_UDQS, // 0
NOGUDQS = VI::intehead::NO_GROUP_UDQS, // 0
ih_264 = 264 , // 0
ih_265 = 265 , // 0
NOUDQS = VI::intehead::NO_UDQS, // 0
NOWUDQS = VI::intehead::NO_WELL_UDQS, // 0
UDQPAR_1 = VI::intehead::UDQPAR_1, // 0
ih_268 = 268 , // 0
ih_269 = 269 , // 0
@ -309,8 +309,8 @@ enum index : std::vector<int>::size_type {
ih_287 = 287 , // 0
ih_288 = 288 , // 0
ih_289 = 289 , // 0
ih_290 = 290 , // 0
ih_291 = 291 , // 0
NOIUADS = VI::intehead::NO_IUADS, // 0
NOIUAPS = VI::intehead::NO_IUAPS, // 0
ih_292 = 292 , // 0
ih_293 = 293 , // 0
ih_294 = 294 , // 0
@ -501,7 +501,7 @@ Opm::RestartIO::InteHEAD::wellTableDimensions(const WellTableDim& wtdim)
this->data_[NGMAXZ] = wtdim.maxGroupInField + 1;
//this->data_[NWMAXZ] = wtdim.maxWellsInField;
this->data_[NWMAXZ] = wtdim.maxWellsInField;
return *this;
}
@ -571,6 +571,15 @@ params_GRPZ(const std::array<int, 4>& grpz)
return *this;
}
Opm::RestartIO::InteHEAD&
Opm::RestartIO::InteHEAD::
params_NGCTRL(const int gct)
{
this -> data_[NGCONT] = gct;
return *this;
}
Opm::RestartIO::InteHEAD&
Opm::RestartIO::InteHEAD::
params_NAAQZ(const int ncamax,
@ -684,7 +693,11 @@ udqParam_1(const UdqParam& udq_par)
{
this -> data_[UDQPAR_1] = - udq_par.udqParam_1;
this -> data_[R_SEED] = - udq_par.udqParam_1;
this -> data_[NOUDQS] = udq_par.no_udqs;
this -> data_[NOWUDQS] = udq_par.no_wudqs;
this -> data_[NOGUDQS] = udq_par.no_gudqs;
this -> data_[NOFUDQS] = udq_par.no_fudqs;
this -> data_[NOIUADS] = udq_par.no_iuads;
this -> data_[NOIUAPS] = udq_par.no_iuaps;
return *this;
}
@ -702,6 +715,31 @@ actionParam(const ActionParam& act_par)
return *this;
}
//InteHEAD parameters which meaning are currently not known, but which are needed for Eclipse restart runs with UDQ and ACTIONX data
Opm::RestartIO::InteHEAD&
Opm::RestartIO::InteHEAD::
variousUDQ_ACTIONXParam()
{
this -> data_[159] = 4;
this -> data_[160] = 5;
this -> data_[161] = 9;
this -> data_[246] = 26;
this -> data_[247] = 16;
this -> data_[248] = 13;
return *this;
}
Opm::RestartIO::InteHEAD&
Opm::RestartIO::InteHEAD::
nominatedPhaseGuideRate(GuideRateNominatedPhase nphase)
{
this -> data_[NGRNPHASE] = nphase.nominated_phase;
return *this;
}
// =====================================================================
// Free functions (calendar/time utilities)
// =====================================================================

View File

@ -29,6 +29,8 @@
#include <opm/output/eclipse/AggregateConnectionData.hpp>
#include <opm/output/eclipse/AggregateMSWData.hpp>
#include <opm/output/eclipse/AggregateUDQData.hpp>
#include <opm/output/eclipse/AggregateActionxData.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
@ -232,6 +234,7 @@ namespace {
}
void writeGroup(int sim_step,
const UnitSystem& units,
const Schedule& schedule,
const Opm::SummaryState& sumState,
const std::vector<int>& ih,
@ -242,7 +245,7 @@ namespace {
auto groupData = Helpers::AggregateGroupData(ih);
groupData.captureDeclaredGroupData(schedule, simStep, sumState, ih);
groupData.captureDeclaredGroupData(schedule, units, simStep, sumState, ih);
rstFile.write("IGRP", groupData.getIGroup());
rstFile.write("SGRP", groupData.getSGroup());
@ -278,10 +281,6 @@ namespace {
const std::vector<int>& ih,
EclIO::OutputStream::Restart& rstFile)
{
//return;
//need to add test if UDQ-data exist and UDQ - active exist etc.
// do not write unless data exists and copy E100 logic.
// write UDQ - data to restart file
const std::size_t simStep = static_cast<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,
const bool ecl_compatible_rst,
const Phases& phases,
@ -538,7 +561,7 @@ void save(EclIO::OutputStream::Restart& rstFile,
writeHeader(sim_step, nextStepSize(value), seconds_elapsed,
schedule, grid, es, rstFile);
writeGroup(sim_step, schedule, sumState, inteHD, rstFile);
writeGroup(sim_step, units, schedule, sumState, inteHD, rstFile);
// Write well and MSW data only when applicable (i.e., when present)
{
@ -563,6 +586,8 @@ void save(EclIO::OutputStream::Restart& rstFile,
}
}
writeActionx(sim_step, es, schedule, sumState, rstFile);
writeSolution(value, schedule, sumState, sim_step, ecl_compatible_rst, write_double, inteHD, rstFile);
if (! ecl_compatible_rst) {

View File

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

View File

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

View File

@ -175,6 +175,30 @@ double GuideRateModel::damping_factor() const {
return this->damping_factor_;
}
double GuideRateModel::getA() const {
return this->A;
}
double GuideRateModel::getB() const {
return this->B;
}
double GuideRateModel::getC() const {
return this->C;
}
double GuideRateModel::getD() const {
return this->D;
}
double GuideRateModel::getE() const {
return this->E;
}
double GuideRateModel::getF() const {
return this->F;
}
bool GuideRateModel::allow_increase() const {
return this->allow_increase_;
}

View File

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

View File

@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims);
actionxData.captureDeclaredActionxData(sched, st, actDims, rptStep);
#if 0
/*rstFile.write("INTEHEAD", ih);
rstFile.write("IUDQ", udqData.getIUDQ());
rstFile.write("IUAD", udqData.getIUAD());
rstFile.write("IGPH", udqData.getIGPH());
@ -162,10 +162,8 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
rstFile.write("ZLACT", actionxData.getZLACT());
rstFile.write("ZACN", actionxData.getZACN());
rstFile.write("IACN", actionxData.getIACN());
rstFile.write("SACN", actionxData.getSACN());
#endif
rstFile.write("SACN", actionxData.getSACN()); */
#if 0
{
/*
Check of InteHEAD and DoubHEAD data for UDQ variables
@ -201,8 +199,6 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
}
#endif
{
/*
IACT
@ -526,11 +522,11 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
BOOST_CHECK_EQUAL(sAcn[start + 1] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 2] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 3] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 4] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 4] , 24);
BOOST_CHECK_EQUAL(sAcn[start + 5] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 6] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 6] , 24);
BOOST_CHECK_EQUAL(sAcn[start + 7] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 8] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 8] , 24);
BOOST_CHECK_EQUAL(sAcn[start + 9] , 17);
BOOST_CHECK_EQUAL(sAcn[start + 10] , 0);
BOOST_CHECK_EQUAL(sAcn[start + 11] , 0);
@ -577,11 +573,6 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
}
#if 0
#endif
}
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,9 +498,9 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data)
BOOST_CHECK_EQUAL(ih.nwells, MockIH::Sz{4});
const auto smry = sim_state();
const auto& units = simCase.es.getUnits();
auto agrpd = Opm::RestartIO::Helpers::AggregateGroupData{ih.value};
agrpd.captureDeclaredGroupData(simCase.sched,
rptStep, smry,
agrpd.captureDeclaredGroupData(simCase.sched, units, rptStep, smry,
ih.value);
// 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[213] , 0.0);
BOOST_CHECK_EQUAL(dh[214] , 1.0E-4); */
BOOST_CHECK_EQUAL(dh[214] , 1.0E-4);
}