Merge pull request #2210 from joakim-hove/sched-vfp

Sched vfp
This commit is contained in:
Joakim Hove 2021-01-15 07:39:34 +01:00 committed by GitHub
commit ccb0ecbea3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 131 additions and 219 deletions

View File

@ -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,

View File

@ -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;
};
}

View File

@ -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));
}

View File

@ -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) {

View File

@ -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,43 +403,37 @@ 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);
while (true) {
@ -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);

View File

@ -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) );
}
}

View File

@ -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};