commit
ccb0ecbea3
@ -37,8 +37,6 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp>
|
||||
@ -169,8 +167,6 @@ namespace Opm
|
||||
public:
|
||||
using WellMap = OrderedMap<std::string, DynamicState<std::shared_ptr<Well>>>;
|
||||
using GroupMap = OrderedMap<std::string, DynamicState<std::shared_ptr<Group>>>;
|
||||
using VFPProdMap = std::map<int, DynamicState<std::shared_ptr<VFPProdTable>>>;
|
||||
using VFPInjMap = std::map<int, DynamicState<std::shared_ptr<VFPInjTable>>>;
|
||||
|
||||
Schedule() = default;
|
||||
explicit Schedule(std::shared_ptr<const Python> python_handle);
|
||||
@ -300,10 +296,6 @@ namespace Opm
|
||||
const GuideRateConfig& guideRateConfig(std::size_t timeStep) const;
|
||||
|
||||
const RFTConfig& rftConfig() const;
|
||||
const VFPProdTable& getVFPProdTable(int table_id, std::size_t timeStep) const;
|
||||
const VFPInjTable& getVFPInjTable(int table_id, std::size_t timeStep) const;
|
||||
std::map<int, std::shared_ptr<const VFPProdTable> > getVFPProdTables(std::size_t timeStep) const;
|
||||
std::map<int, std::shared_ptr<const VFPInjTable> > getVFPInjTables(std::size_t timeStep) const;
|
||||
/*
|
||||
Will remove all completions which are connected to cell which is not
|
||||
active. Will scan through all wells and all timesteps.
|
||||
@ -350,12 +342,6 @@ namespace Opm
|
||||
auto splitGroups = splitDynMap(groups);
|
||||
serializer.vector(splitGroups.first);
|
||||
serializer(splitGroups.second);
|
||||
auto splitvfpprod = splitDynMap<Map2>(vfpprod_tables);
|
||||
serializer.vector(splitvfpprod.first);
|
||||
serializer(splitvfpprod.second);
|
||||
auto splitvfpinj = splitDynMap<Map2>(vfpinj_tables);
|
||||
serializer.vector(splitvfpinj.first);
|
||||
serializer(splitvfpinj.second);
|
||||
udq_config.serializeOp(serializer);
|
||||
udq_active.serializeOp(serializer);
|
||||
guide_rate_config.serializeOp(serializer);
|
||||
@ -366,8 +352,6 @@ namespace Opm
|
||||
if (!serializer.isSerializing()) {
|
||||
reconstructDynMap(splitWells.first, splitWells.second, wells_static);
|
||||
reconstructDynMap(splitGroups.first, splitGroups.second, groups);
|
||||
reconstructDynMap<Map2>(splitvfpprod.first, splitvfpprod.second, vfpprod_tables);
|
||||
reconstructDynMap<Map2>(splitvfpinj.first, splitvfpinj.second, vfpinj_tables);
|
||||
}
|
||||
serializer.vector(snapshots);
|
||||
m_static.serializeOp(serializer);
|
||||
@ -380,8 +364,6 @@ namespace Opm
|
||||
TimeMap m_timeMap;
|
||||
WellMap wells_static;
|
||||
GroupMap groups;
|
||||
VFPProdMap vfpprod_tables;
|
||||
VFPInjMap vfpinj_tables;
|
||||
DynamicState<std::shared_ptr<UDQConfig>> udq_config;
|
||||
DynamicState<std::shared_ptr<UDQActive>> udq_active;
|
||||
DynamicState<std::shared_ptr<GuideRateConfig>> guide_rate_config;
|
||||
@ -420,7 +402,8 @@ namespace Opm
|
||||
void updateUDQActive( std::size_t timeStep, std::shared_ptr<UDQActive> udq );
|
||||
bool updateWellStatus( const std::string& well, std::size_t reportStep, bool runtime, Well::Status status, std::optional<KeywordLocation> = {});
|
||||
void addWellToGroup( const std::string& group_name, const std::string& well_name , std::size_t timeStep);
|
||||
void iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
void iterateScheduleSection(std::size_t load_start,
|
||||
std::size_t load_end,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
const EclipseGrid& grid,
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSump.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -116,6 +118,14 @@ namespace Opm {
|
||||
const RPTConfig& rpt_config() const;
|
||||
void rpt_config(RPTConfig rpt_config);
|
||||
|
||||
std::vector<const VFPProdTable*> vfpprod() const;
|
||||
const VFPProdTable& vfpprod(int table_id) const;
|
||||
void vfpprod(VFPProdTable vfpprod);
|
||||
|
||||
std::vector<const VFPInjTable*> vfpinj() const;
|
||||
const VFPInjTable& vfpinj(int table_id) const;
|
||||
void vfpinj(VFPInjTable vfpinj);
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer) {
|
||||
serializer(m_start_time);
|
||||
@ -135,8 +145,11 @@ namespace Opm {
|
||||
serializer(m_wlist_manager);
|
||||
serializer(m_network);
|
||||
serializer(m_rptconfig);
|
||||
serializer.map(m_vfpprod);
|
||||
serializer.map(m_vfpinj);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::chrono::system_clock::time_point m_start_time;
|
||||
std::optional<std::chrono::system_clock::time_point> m_end_time;
|
||||
@ -156,6 +169,8 @@ namespace Opm {
|
||||
std::shared_ptr<WListManager> m_wlist_manager;
|
||||
std::shared_ptr<Network::ExtNetwork> m_network;
|
||||
std::shared_ptr<RPTConfig> m_rptconfig;
|
||||
std::map<int, std::shared_ptr<VFPProdTable>> m_vfpprod;
|
||||
std::map<int, std::shared_ptr<VFPInjTable>> m_vfpinj;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -588,7 +588,7 @@ namespace {
|
||||
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
|
||||
|
||||
if (pc.alq_value != 0.0) {
|
||||
auto vfpTable = sched.getVFPProdTable(pc.vfp_table_number,sim_step);
|
||||
auto vfpTable = sched[sim_step].vfpprod(pc.vfp_table_number);
|
||||
if (vfpTable.getALQType() == Opm::VFPProdTable::ALQ_GRAT) {
|
||||
sWell[Ix::Alq_value] = static_cast<float>(units.from_si(M::gas_surface_rate, pc.alq_value));
|
||||
}
|
||||
|
@ -470,7 +470,6 @@ namespace {
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("GCONPROD complete\n");
|
||||
}
|
||||
|
||||
void Schedule::handleGCONSALE(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
@ -742,6 +741,7 @@ namespace {
|
||||
}
|
||||
|
||||
void Schedule::handleRPTSCHED(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
printf("snapshost.size(): %ld \n", this->snapshots.size());
|
||||
this->snapshots.back().rpt_config( RPTConfig(handlerContext.keyword ));
|
||||
}
|
||||
|
||||
@ -838,31 +838,15 @@ namespace {
|
||||
}
|
||||
|
||||
void Schedule::handleVFPINJ(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
std::shared_ptr<VFPInjTable> table = std::make_shared<VFPInjTable>(handlerContext.keyword, this->m_static.m_unit_system);
|
||||
int table_id = table->getTableNum();
|
||||
|
||||
if (vfpinj_tables.find(table_id) == vfpinj_tables.end()) {
|
||||
std::pair<int, DynamicState<std::shared_ptr<VFPInjTable> > > pair = std::make_pair(table_id, DynamicState<std::shared_ptr<VFPInjTable> >(this->m_timeMap, nullptr));
|
||||
vfpinj_tables.insert( pair );
|
||||
}
|
||||
|
||||
auto& table_state = vfpinj_tables.at(table_id);
|
||||
table_state.update(handlerContext.currentStep, table);
|
||||
auto table = VFPInjTable(handlerContext.keyword, this->m_static.m_unit_system);
|
||||
this->snapshots.back().vfpinj( std::move(table) );
|
||||
this->snapshots.back().events().addEvent( ScheduleEvents::VFPINJ_UPDATE );
|
||||
}
|
||||
|
||||
void Schedule::handleVFPPROD(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
|
||||
std::shared_ptr<VFPProdTable> table = std::make_shared<VFPProdTable>(handlerContext.keyword, this->m_static.m_unit_system);
|
||||
int table_id = table->getTableNum();
|
||||
|
||||
if (vfpprod_tables.find(table_id) == vfpprod_tables.end()) {
|
||||
std::pair<int, DynamicState<std::shared_ptr<VFPProdTable> > > pair = std::make_pair(table_id, DynamicState<std::shared_ptr<VFPProdTable> >(this->m_timeMap, nullptr));
|
||||
vfpprod_tables.insert( pair );
|
||||
}
|
||||
|
||||
auto& table_state = vfpprod_tables.at(table_id);
|
||||
table_state.update(handlerContext.currentStep, table);
|
||||
auto table = VFPProdTable(handlerContext.keyword, this->m_static.m_unit_system);
|
||||
this->snapshots.back().events().addEvent( ScheduleEvents::VFPPROD_UPDATE );
|
||||
this->snapshots.back().vfpprod( std::move(table) );
|
||||
}
|
||||
|
||||
void Schedule::handleWCONHIST(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
@ -889,7 +873,7 @@ namespace {
|
||||
table_nr = properties->VFPTableNumber;
|
||||
|
||||
if (table_nr != 0)
|
||||
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
|
||||
alq_type = this->snapshots.back().vfpprod(table_nr).getALQType();
|
||||
properties->handleWCONHIST(alq_type, this->m_static.m_unit_system, record);
|
||||
|
||||
if (switching_from_injector) {
|
||||
@ -959,7 +943,7 @@ namespace {
|
||||
table_nr = properties->VFPTableNumber;
|
||||
|
||||
if (table_nr != 0)
|
||||
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
|
||||
alq_type = this->snapshots.back().vfpprod(table_nr).getALQType();
|
||||
properties->handleWCONPROD(alq_type, this->m_static.m_unit_system, well_name, record);
|
||||
|
||||
if (switching_from_injector) {
|
||||
|
@ -121,10 +121,13 @@ namespace {
|
||||
rft_config(this->m_timeMap),
|
||||
restart_config(m_timeMap, deck, parseContext, errors)
|
||||
{
|
||||
if (rst)
|
||||
if (rst) {
|
||||
auto restart_step = rst->header.restart_info().second;
|
||||
this->iterateScheduleSection( 0, restart_step, parseContext, errors, grid, fp);
|
||||
this->load_rst(*rst, grid, fp);
|
||||
|
||||
this->iterateScheduleSection( {}, parseContext, errors, grid, fp);
|
||||
this->iterateScheduleSection( restart_step, this->m_sched_deck.size(), parseContext, errors, grid, fp);
|
||||
} else
|
||||
this->iterateScheduleSection( 0, this->m_sched_deck.size(), parseContext, errors, grid, fp);
|
||||
|
||||
/*
|
||||
The code in the #ifdef SCHEDULE_DEBUG is an enforced integration test
|
||||
@ -135,14 +138,6 @@ namespace {
|
||||
if (this->size() == 0)
|
||||
return;
|
||||
|
||||
//Verify that we can safely re-iterate over the Schedule section
|
||||
//if (!rst)
|
||||
// this->iterateScheduleSection(0, parseContext, errors, grid, fp);
|
||||
//else {
|
||||
// auto restart_offset = this->m_sched_deck.restart_offset();
|
||||
// this->iterateScheduleSection(restart_offset, parseContext, errors, grid, fp);
|
||||
//}
|
||||
|
||||
// Verify that the time schedule is correct.
|
||||
for (std::size_t report_step = 0; report_step < this->size() - 1; report_step++) {
|
||||
const auto& this_block = this->m_sched_deck[report_step];
|
||||
@ -257,8 +252,6 @@ namespace {
|
||||
result.m_timeMap = TimeMap::serializeObject();
|
||||
result.wells_static.insert({"test1", {{std::make_shared<Opm::Well>(Opm::Well::serializeObject())},1}});
|
||||
result.groups.insert({"test2", {{std::make_shared<Opm::Group>(Opm::Group::serializeObject())},1}});
|
||||
result.vfpprod_tables = {{1, {{std::make_shared<VFPProdTable>(VFPProdTable::serializeObject())}, 1}}};
|
||||
result.vfpinj_tables = {{2, {{std::make_shared<VFPInjTable>(VFPInjTable::serializeObject())}, 1}}};
|
||||
result.udq_config = {{std::make_shared<UDQConfig>(UDQConfig::serializeObject())}, 1};
|
||||
result.m_glo = {{std::make_shared<GasLiftOpt>(GasLiftOpt::serializeObject())}, 1};
|
||||
result.udq_active = {{std::make_shared<UDQActive>(UDQActive::serializeObject())}, 1};
|
||||
@ -366,7 +359,7 @@ private:
|
||||
|
||||
}
|
||||
|
||||
void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_end,
|
||||
const ParseContext& parseContext ,
|
||||
ErrorGuard& errors,
|
||||
const EclipseGrid& grid,
|
||||
@ -377,74 +370,6 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
auto deck_time = [this](double seconds) { return this->m_static.m_unit_system.from_si(UnitSystem::measure::time, seconds); };
|
||||
std::string current_file;
|
||||
const auto& time_map = this->m_timeMap;
|
||||
/*
|
||||
The process of transitioning to Schedule model based on ScheduleState
|
||||
instances is a gradual one. For the keywords which have been converted
|
||||
to the ScheduleState implementation the iterateScheduleSection()
|
||||
function can be called repeatedly, whereas for the keywords which have
|
||||
not yet been converted that is not safe. The old_style_keywords is a
|
||||
list of keywords which should be ignored when iterateScheduleSection()
|
||||
is called repeatedly.
|
||||
*/
|
||||
std::unordered_set<std::string> old_style_keywords = {
|
||||
"PYACTION",
|
||||
"GCONPROD",
|
||||
"GCONINJE",
|
||||
"GLIFTOPT",
|
||||
"WELPI",
|
||||
"BRANPROP",
|
||||
"COMPDAT",
|
||||
"COMPLUMP",
|
||||
"COMPORD",
|
||||
"COMPSEGS",
|
||||
"GCONINJE",
|
||||
"GCONPROD",
|
||||
"GCONSALE",
|
||||
"GCONSUMP",
|
||||
"GEFAC",
|
||||
"GLIFTOPT",
|
||||
"GPMAINT",
|
||||
"GRUPNET",
|
||||
"GRUPTREE",
|
||||
"GUIDERAT",
|
||||
"LIFTOPT",
|
||||
"LINCOM",
|
||||
"MESSAGES",
|
||||
"MXUNSUPP",
|
||||
"NODEPROP",
|
||||
"RPTSCHED",
|
||||
"UDQ",
|
||||
"VFPINJ",
|
||||
"VFPPROD",
|
||||
"WCONHIST",
|
||||
"WCONINJE",
|
||||
"WCONINJH",
|
||||
"WCONPROD",
|
||||
"WECON",
|
||||
"WEFAC",
|
||||
"WELOPEN",
|
||||
"WELPI",
|
||||
"WELSEGS",
|
||||
"WELSPECS",
|
||||
"WELTARG",
|
||||
"WFOAM",
|
||||
"WGRUPCON",
|
||||
"WINJTEMP",
|
||||
"WLIFTOPT",
|
||||
"WPAVEDEP",
|
||||
"WPIMULT",
|
||||
"WPMITAB",
|
||||
"WPOLYMER",
|
||||
"WSALT",
|
||||
"WSEGSICD",
|
||||
"WSEGAICD",
|
||||
"WSEGVALV",
|
||||
"WSKPTAB",
|
||||
"WSOLVENT",
|
||||
"WTEMP",
|
||||
"WTRACER"
|
||||
};
|
||||
|
||||
/*
|
||||
The keywords in the skiprest_whitelist set are loaded from the
|
||||
SCHEDULE section even though the SKIPREST keyword is in action. The
|
||||
@ -452,7 +377,6 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
all.
|
||||
*/
|
||||
std::unordered_set<std::string> skiprest_whitelist = {"VFPPROD", "VFPINJ", "RPTSCHED", "RPTRST", "TUNING", "MESSAGES"};
|
||||
std::size_t currentStep = 0;
|
||||
/*
|
||||
The behavior of variable restart_skip is more lenient than the
|
||||
SKIPREST keyword. If this is a restarted[1] run the loop iterating
|
||||
@ -469,7 +393,7 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
these keywords will be assigned to report step 0.
|
||||
*/
|
||||
|
||||
auto restart_skip = currentStep < this->m_timeMap.restart_offset();
|
||||
auto restart_skip = load_start < this->m_timeMap.restart_offset();
|
||||
ScheduleLogger logger(restart_skip);
|
||||
{
|
||||
const auto& location = this->m_sched_deck.location();
|
||||
@ -479,44 +403,38 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
logger.info(fmt::format("This is a restarted run - skipping until report step {} at {}", time_map.restart_offset(), Schedule::formatDate(time_map.restart_time())));
|
||||
|
||||
logger(fmt::format("Initializing report step {}/{} at {} {} {} line {}",
|
||||
currentStep + 1,
|
||||
load_start + 1,
|
||||
this->size(),
|
||||
Schedule::formatDate(this->getStartTime()),
|
||||
deck_time(time_map.getTimePassedUntil(currentStep)),
|
||||
deck_time(time_map.getTimePassedUntil(load_start)),
|
||||
time_unit,
|
||||
location.lineno));
|
||||
}
|
||||
|
||||
if (load_offset.has_value()) {
|
||||
if (load_offset.value() < this->m_sched_deck.restart_offset())
|
||||
throw std::logic_error("BUG: Tried to replay schedule keywords from historical section in restarted run");
|
||||
this->snapshots.resize( load_offset.value() );
|
||||
}
|
||||
|
||||
for (const auto& block : this->m_sched_deck) {
|
||||
for (auto report_step = load_start; report_step < load_end; report_step++) {
|
||||
std::size_t keyword_index = 0;
|
||||
auto& block = this->m_sched_deck[report_step];
|
||||
auto time_type = block.time_type();
|
||||
if (time_type == ScheduleTimeType::DATES || time_type == ScheduleTimeType::TSTEP) {
|
||||
const auto& start_date = Schedule::formatDate(std::chrono::system_clock::to_time_t(block.start_time()));
|
||||
const auto& days = deck_time(this->stepLength(currentStep - 1));
|
||||
const auto& days_total = deck_time(time_map.getTimePassedUntil(currentStep));
|
||||
const auto& days = deck_time(this->stepLength(report_step - 1));
|
||||
const auto& days_total = deck_time(time_map.getTimePassedUntil(report_step));
|
||||
logger.complete_step(fmt::format("Complete report step {0} ({1} {2}) at {3} ({4} {2})",
|
||||
currentStep,
|
||||
report_step,
|
||||
days,
|
||||
time_unit,
|
||||
start_date,
|
||||
days_total));
|
||||
|
||||
logger(fmt::format("Initializing report step {}/{} at {} ({} {}) - line {}",
|
||||
currentStep + 1,
|
||||
report_step + 1,
|
||||
this->size(),
|
||||
start_date,
|
||||
days_total,
|
||||
time_unit,
|
||||
block.location().lineno));
|
||||
}
|
||||
if (time_type != ScheduleTimeType::RESTART)
|
||||
this->create_next(block);
|
||||
this->create_next(block);
|
||||
|
||||
while (true) {
|
||||
if (keyword_index == block.size())
|
||||
@ -529,13 +447,8 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
current_file = location.filename;
|
||||
}
|
||||
|
||||
if (load_offset.has_value() && old_style_keywords.count(keyword.name()) == 1) {
|
||||
keyword_index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyword.name() == "ACTIONX") {
|
||||
Action::ActionX action(keyword, this->m_timeMap.getStartTime(currentStep));
|
||||
Action::ActionX action(keyword, this->m_timeMap.getStartTime(report_step));
|
||||
while (true) {
|
||||
keyword_index++;
|
||||
if (keyword_index == block.size())
|
||||
@ -553,13 +466,13 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
parseContext.handleError( ParseContext::ACTIONX_ILLEGAL_KEYWORD, msg_fmt, action_keyword.location(), errors);
|
||||
}
|
||||
}
|
||||
this->addACTIONX(action, currentStep);
|
||||
this->addACTIONX(action, report_step);
|
||||
keyword_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
logger(fmt::format("Processing keyword {} at line {}", location.keyword, location.lineno));
|
||||
this->handleKeyword(currentStep,
|
||||
this->handleKeyword(report_step,
|
||||
block,
|
||||
keyword,
|
||||
parseContext,
|
||||
@ -570,8 +483,7 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
keyword_index++;
|
||||
}
|
||||
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
currentStep += 1;
|
||||
checkIfAllConnectionsIsShut(report_step);
|
||||
}
|
||||
|
||||
|
||||
@ -1396,49 +1308,6 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
}
|
||||
}
|
||||
|
||||
const VFPProdTable& Schedule::getVFPProdTable(int table_id, std::size_t timeStep) const {
|
||||
const auto pair = vfpprod_tables.find(table_id);
|
||||
if (pair == vfpprod_tables.end())
|
||||
throw std::invalid_argument("No such table id: " + std::to_string(table_id));
|
||||
|
||||
auto table_ptr = pair->second.get(timeStep);
|
||||
if (!table_ptr)
|
||||
throw std::invalid_argument("Table not yet defined at timeStep:" + std::to_string(timeStep));
|
||||
|
||||
return *table_ptr;
|
||||
}
|
||||
|
||||
const VFPInjTable& Schedule::getVFPInjTable(int table_id, std::size_t timeStep) const {
|
||||
const auto pair = vfpinj_tables.find(table_id);
|
||||
if (pair == vfpinj_tables.end())
|
||||
throw std::invalid_argument("No such table id: " + std::to_string(table_id));
|
||||
|
||||
auto table_ptr = pair->second.get(timeStep);
|
||||
if (!table_ptr)
|
||||
throw std::invalid_argument("Table not yet defined at timeStep:" + std::to_string(timeStep));
|
||||
|
||||
return *table_ptr;
|
||||
}
|
||||
|
||||
std::map<int, std::shared_ptr<const VFPInjTable> > Schedule::getVFPInjTables(std::size_t timeStep) const {
|
||||
std::map<int, std::shared_ptr<const VFPInjTable> > tables;
|
||||
for (const auto& pair : this->vfpinj_tables) {
|
||||
if (pair.second.get(timeStep)) {
|
||||
tables.insert(std::make_pair(pair.first, pair.second.get(timeStep)) );
|
||||
}
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
std::map<int, std::shared_ptr<const VFPProdTable> > Schedule::getVFPProdTables(std::size_t timeStep) const {
|
||||
std::map<int, std::shared_ptr<const VFPProdTable> > tables;
|
||||
for (const auto& pair : this->vfpprod_tables) {
|
||||
if (pair.second.get(timeStep)) {
|
||||
tables.insert(std::make_pair(pair.first, pair.second.get(timeStep)) );
|
||||
}
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
const UDQActive& Schedule::udqActive(std::size_t timeStep) const {
|
||||
return *this->udq_active[timeStep];
|
||||
@ -1624,8 +1493,6 @@ void Schedule::iterateScheduleSection(std::optional<std::size_t> load_offset,
|
||||
this->m_static == data.m_static &&
|
||||
compareMap(this->wells_static, data.wells_static) &&
|
||||
compareMap(this->groups, data.groups) &&
|
||||
compareMap(this->vfpprod_tables, data.vfpprod_tables) &&
|
||||
compareMap(this->vfpinj_tables, data.vfpinj_tables) &&
|
||||
compareDynState(this->m_glo, data.m_glo) &&
|
||||
compareDynState(this->udq_config, data.udq_config) &&
|
||||
compareDynState(this->udq_active, data.udq_active) &&
|
||||
@ -1666,16 +1533,8 @@ namespace {
|
||||
|
||||
void Schedule::load_rst(const RestartIO::RstState& rst_state, const EclipseGrid& grid, const FieldPropsManager& fp)
|
||||
{
|
||||
double udq_undefined = 0;
|
||||
const auto report_step = rst_state.header.report_step - 1;
|
||||
auto start_time = std::chrono::system_clock::from_time_t( this->getStartTime() );
|
||||
for (int step = 0; step < report_step; step++)
|
||||
this->create_next(start_time, start_time);
|
||||
{
|
||||
auto restart_time = std::chrono::system_clock::from_time_t( rst_state.header.restart_info().first );
|
||||
this->create_next(start_time, restart_time);
|
||||
}
|
||||
|
||||
double udq_undefined = 0;
|
||||
for (const auto& rst_group : rst_state.groups) {
|
||||
auto group = Group{ rst_group, this->groups.size(), static_cast<std::size_t>(report_step), udq_undefined, this->m_static.m_unit_system };
|
||||
this->addGroup(group, report_step);
|
||||
|
@ -16,11 +16,15 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSump.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -141,6 +145,30 @@ void ScheduleState::whistctl(Well::ProducerCMode whistctl) {
|
||||
}
|
||||
|
||||
bool ScheduleState::operator==(const ScheduleState& other) const {
|
||||
auto&& map_equal = [](const auto& map1, const auto& map2) {
|
||||
if (map1.size() != map2.size())
|
||||
return false;
|
||||
|
||||
auto it2 = map2.begin();
|
||||
for (const auto& it1 : map1) {
|
||||
if (it1.first != it2->first)
|
||||
return false;
|
||||
|
||||
if (!(*it1.second == *it2->second))
|
||||
return false;
|
||||
|
||||
++it2;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!map_equal(this->m_vfpprod, other.m_vfpprod))
|
||||
return false;
|
||||
|
||||
if (!map_equal(this->m_vfpinj, other.m_vfpinj))
|
||||
return false;
|
||||
|
||||
return this->m_start_time == other.m_start_time &&
|
||||
this->m_oilvap == other.m_oilvap &&
|
||||
this->m_tuning == other.m_tuning &&
|
||||
@ -172,6 +200,11 @@ ScheduleState ScheduleState::serializeObject() {
|
||||
ts.m_gconsale = std::make_shared<GConSale>( GConSale::serializeObject() );
|
||||
ts.m_wlist_manager = std::make_shared<WListManager>( WListManager::serializeObject() );
|
||||
ts.m_rptconfig = std::make_shared<RPTConfig>( RPTConfig::serializeObject() );
|
||||
ts.m_vfpprod.emplace( std::make_pair(77, std::make_shared<VFPProdTable>(VFPProdTable::serializeObject() )));
|
||||
ts.m_vfpprod.emplace( std::make_pair(78, std::make_shared<VFPProdTable>(VFPProdTable::serializeObject() )));
|
||||
ts.m_vfpinj.emplace( std::make_pair(177, std::make_shared<VFPInjTable>(VFPInjTable::serializeObject() )));
|
||||
ts.m_vfpinj.emplace( std::make_pair(178, std::make_shared<VFPInjTable>(VFPInjTable::serializeObject() )));
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
@ -260,4 +293,48 @@ const RPTConfig& ScheduleState::rpt_config() const {
|
||||
void ScheduleState::rpt_config(RPTConfig rpt_config) {
|
||||
this->m_rptconfig = std::make_shared<RPTConfig>(std::move(rpt_config));
|
||||
}
|
||||
|
||||
std::vector<const VFPProdTable*> ScheduleState::vfpprod() const {
|
||||
std::vector<const VFPProdTable*> tables;
|
||||
for (const auto& [_, table] : this->m_vfpprod) {
|
||||
(void)_;
|
||||
tables.push_back( table.get() );
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
const VFPProdTable& ScheduleState::vfpprod(int table_id) const {
|
||||
auto vfp_iter = this->m_vfpprod.find(table_id);
|
||||
if (vfp_iter == this->m_vfpprod.end())
|
||||
throw std::logic_error(fmt::format("No VFPPROD table with id: {} has been registered", table_id));
|
||||
|
||||
return *vfp_iter->second;
|
||||
}
|
||||
|
||||
void ScheduleState::vfpprod(VFPProdTable vfpprod) {
|
||||
int table_id = vfpprod.getTableNum();
|
||||
this->m_vfpprod[table_id] = std::make_shared<VFPProdTable>( std::move(vfpprod) );
|
||||
}
|
||||
|
||||
std::vector<const VFPInjTable*> ScheduleState::vfpinj() const {
|
||||
std::vector<const VFPInjTable*> tables;
|
||||
for (const auto& [_, table] : this->m_vfpinj) {
|
||||
(void)_;
|
||||
tables.push_back( table.get() );
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
const VFPInjTable& ScheduleState::vfpinj(int table_id) const {
|
||||
auto vfp_iter = this->m_vfpinj.find(table_id);
|
||||
if (vfp_iter == this->m_vfpinj.end())
|
||||
throw std::logic_error(fmt::format("No VFPINJ table with id: {} has been registered", table_id));
|
||||
|
||||
return *vfp_iter->second;
|
||||
}
|
||||
|
||||
void ScheduleState::vfpinj(VFPInjTable vfpinj) {
|
||||
int table_id = vfpinj.getTableNum();
|
||||
this->m_vfpinj[table_id] = std::make_shared<VFPInjTable>( std::move(vfpinj) );
|
||||
}
|
||||
}
|
||||
|
@ -3006,31 +3006,26 @@ VFPINJ
|
||||
BOOST_CHECK( schedule[2].events().hasEvent(ScheduleEvents::VFPINJ_UPDATE));
|
||||
|
||||
// No such table id
|
||||
BOOST_CHECK_THROW(schedule.getVFPInjTable(77,0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(schedule[0].vfpinj(77), std::exception);
|
||||
|
||||
// Table not defined at step 0
|
||||
BOOST_CHECK_THROW(schedule.getVFPInjTable(10,0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(schedule[0].vfpinj(10), std::exception);
|
||||
|
||||
const Opm::VFPInjTable& vfpinjTable2 = schedule.getVFPInjTable(5, 2);
|
||||
const Opm::VFPInjTable& vfpinjTable2 = schedule[2].vfpinj(5);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable2.getTableNum(), 5);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable2.getDatumDepth(), 100);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable2.getFloType(), Opm::VFPInjTable::FLO_GAS);
|
||||
|
||||
const Opm::VFPInjTable& vfpinjTable3 = schedule.getVFPInjTable(10, 2);
|
||||
const Opm::VFPInjTable& vfpinjTable3 = schedule[2].vfpinj(10);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable3.getTableNum(), 10);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable3.getDatumDepth(), 200);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable3.getFloType(), Opm::VFPInjTable::FLO_WAT);
|
||||
|
||||
const Opm::VFPInjTable& vfpinjTable = schedule.getVFPInjTable(5, 0);
|
||||
const Opm::VFPInjTable& vfpinjTable = schedule[0].vfpinj(5);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable.getTableNum(), 5);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable.getDatumDepth(), 32.9);
|
||||
BOOST_CHECK_EQUAL(vfpinjTable.getFloType(), Opm::VFPInjTable::FLO_WAT);
|
||||
|
||||
const auto vfp_tables0 = schedule.getVFPInjTables(0);
|
||||
BOOST_CHECK_EQUAL( vfp_tables0.size(), 1U);
|
||||
|
||||
const auto vfp_tables2 = schedule.getVFPInjTables(2);
|
||||
BOOST_CHECK_EQUAL( vfp_tables2.size(), 2U);
|
||||
//Flo axis
|
||||
{
|
||||
const std::vector<double>& flo = vfpinjTable.getFloAxis();
|
||||
@ -3698,8 +3693,7 @@ BOOST_AUTO_TEST_CASE(SKIPREST_VFP) {
|
||||
Opm::EclIO::ERst rst_file(rst_filename);
|
||||
const auto& rst = Opm::RestartIO::RstState::load(rst_file, report_step);
|
||||
const auto sched = Schedule{ deck, es, python , &rst};
|
||||
const auto& tables = sched.getVFPProdTables(3);
|
||||
BOOST_CHECK( !tables.empty() );
|
||||
BOOST_CHECK_NO_THROW( sched[3].vfpprod(5) );
|
||||
}
|
||||
|
||||
|
||||
@ -4229,7 +4223,7 @@ BOOST_AUTO_TEST_CASE(VFPPROD_SCALING) {
|
||||
const auto deck = Parser{}.parseFile("VFP_CASE.DATA");
|
||||
const auto es = EclipseState{ deck };
|
||||
const auto sched = Schedule{ deck, es };
|
||||
const auto& vfp_table = sched.getVFPProdTable(1, 0);
|
||||
const auto& vfp_table = sched[0].vfpprod(1);
|
||||
const std::vector<double> flo = { 0.000578704, 0.001157407, 0.002893519, 0.005787037, 0.008680556, 0.011574074, 0.017361111, 0.023148148, 0.034722222, 0.046296296};
|
||||
const std::vector<double> thp = {1300000.000000000, 2500000.000000000, 5000000.000000000, 7500000.000000000, 10000000.000000000};
|
||||
const std::vector<double> wfr = { 0.000000000, 0.100000000, 0.200000000, 0.300000000, 0.400000000, 0.500000000, 0.600000000, 0.700000000, 0.800000000, 0.990000000};
|
||||
|
Loading…
Reference in New Issue
Block a user