Merge pull request #2074 from joakim-hove/handlercontext-units

Make section and keyword index optional in Schedule handlerContext
This commit is contained in:
Joakim Hove 2020-11-05 12:40:53 +01:00 committed by GitHub
commit f5631549bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 55 deletions

View File

@ -107,7 +107,6 @@ namespace Opm
class SCHEDULESection;
class SummaryState;
class TimeMap;
class UnitSystem;
class ErrorGuard;
class WListManager;
class UDQConfig;
@ -336,6 +335,7 @@ namespace Opm
reconstructDynMap<Map2>(splitvfpprod.first, splitvfpprod.second, vfpprod_tables);
reconstructDynMap<Map2>(splitvfpinj.first, splitvfpinj.second, vfpinj_tables);
}
unit_system.serializeOp(serializer);
}
private:
@ -366,13 +366,13 @@ namespace Opm
RFTConfig rft_config;
DynamicState<int> m_nupcol;
RestartConfig restart_config;
UnitSystem unit_system;
std::optional<int> exit_status;
std::map<std::string,Events> wellgroup_events;
void load_rst(const RestartIO::RstState& rst,
const EclipseGrid& grid,
const FieldPropsManager& fp,
const UnitSystem& unit_system);
const FieldPropsManager& fp);
void addWell(Well well, std::size_t report_step);
void addWell(const std::string& wellName,
const std::string& group,
@ -386,8 +386,7 @@ namespace Opm
int pvt_table,
Well::GasInflowEquation gas_inflow,
std::size_t timeStep,
Connection::Order wellConnectionOrder,
const UnitSystem& unit_system);
Connection::Order wellConnectionOrder);
DynamicState<std::shared_ptr<RPTConfig>> rpt_config;
void updateNetwork(std::shared_ptr<Network::ExtNetwork> network, std::size_t report_step);
@ -404,9 +403,9 @@ namespace Opm
void addACTIONX(const Action::ActionX& action, std::size_t currentStep);
void addGroupToGroup( const std::string& parent_group, const std::string& child_group, std::size_t timeStep);
void addGroupToGroup( const std::string& parent_group, const Group& child_group, std::size_t timeStep);
void addGroup(const std::string& groupName , std::size_t timeStep, const UnitSystem& unit_system);
void addGroup(const std::string& groupName , std::size_t timeStep);
void addGroup(const Group& group, std::size_t timeStep);
void addWell(const std::string& wellName, const DeckRecord& record, std::size_t timeStep, Connection::Order connection_order, const UnitSystem& unit_system);
void addWell(const std::string& wellName, const DeckRecord& record, std::size_t timeStep, Connection::Order connection_order);
void checkUnhandledKeywords( const SCHEDULESection& ) const;
void checkIfAllConnectionsIsShut(std::size_t currentStep);
void updateUDQ(const DeckKeyword& keyword, std::size_t current_step);
@ -449,7 +448,7 @@ namespace Opm
}
static std::string formatDate(std::time_t t);
std::string simulationDays(const UnitSystem&, std::size_t currentStep) const;
std::string simulationDays(std::size_t currentStep) const;
void applyEXIT(const DeckKeyword&, std::size_t currentStep);
void applyMESSAGES(const DeckKeyword&, std::size_t currentStep);
@ -458,12 +457,24 @@ namespace Opm
void applyWRFTPLT(const DeckKeyword&, std::size_t currentStep);
struct HandlerContext {
const SCHEDULESection& section;
const DeckKeyword& keyword;
const std::size_t keywordIndex;
const std::size_t currentStep;
const EclipseGrid& grid;
const FieldPropsManager& fieldPropsManager;
const SCHEDULESection * section = nullptr;
std::optional<std::size_t> keywordIndex;
HandlerContext(const DeckKeyword& keyword_,
const std::size_t currentStep_,
const EclipseGrid& grid_,
const FieldPropsManager& fieldPropsManager_) :
keyword(keyword_),
currentStep(currentStep_),
grid(grid_),
fieldPropsManager(fieldPropsManager_)
{}
};
/**

View File

@ -383,7 +383,7 @@ namespace {
{
auto group_ptr = std::make_shared<Group>(this->getGroup(group_name, handlerContext.currentStep));
Group::GroupProductionProperties production(handlerContext.section.unitSystem(), group_name);
Group::GroupProductionProperties production(this->unit_system, group_name);
production.gconprod_cmode = controlMode;
production.active_cmode = controlMode;
production.oil_target = oil_target;
@ -439,7 +439,6 @@ namespace {
}
void Schedule::handleGCONSALE(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
const auto& unit_system = handlerContext.section.unitSystem();
const auto& current = *this->gconsale.get(handlerContext.currentStep);
std::shared_ptr<GConSale> new_gconsale(new GConSale(current));
for (const auto& record : handlerContext.keyword) {
@ -450,7 +449,7 @@ namespace {
std::string procedure = record.getItem("MAX_PROC").getTrimmedString(0);
auto udqconfig = this->getUDQConfig(handlerContext.currentStep).params().undefinedValue();
new_gconsale->add(groupName, sales_target, max_rate, min_rate, procedure, udqconfig, unit_system);
new_gconsale->add(groupName, sales_target, max_rate, min_rate, procedure, udqconfig, this->unit_system);
auto group_ptr = std::make_shared<Group>(this->getGroup(groupName, handlerContext.currentStep));
Group::GroupInjectionProperties injection;
@ -463,7 +462,6 @@ namespace {
}
void Schedule::handleGCONSUMP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
const auto& unit_system = handlerContext.section.unitSystem();
const auto& current = *this->gconsump.get(handlerContext.currentStep);
std::shared_ptr<GConSump> new_gconsump(new GConSump(current));
for (const auto& record : handlerContext.keyword) {
@ -478,7 +476,7 @@ namespace {
auto udqconfig = this->getUDQConfig(handlerContext.currentStep).params().undefinedValue();
new_gconsump->add(groupName, consumption_rate, import_rate, network_node_name, udqconfig, unit_system);
new_gconsump->add(groupName, consumption_rate, import_rate, network_node_name, udqconfig, this->unit_system);
}
this->gconsump.update(handlerContext.currentStep, new_gconsump);
}
@ -555,12 +553,11 @@ namespace {
}
void Schedule::handleGRUPNET(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
const auto& unit_system = handlerContext.section.unitSystem();
for (const auto& record : handlerContext.keyword) {
const auto& groupName = record.getItem("NAME").getTrimmedString(0);
if (!hasGroup(groupName))
addGroup(groupName , handlerContext.currentStep, unit_system);
addGroup(groupName , handlerContext.currentStep);
int table = record.getItem("VFP_TABLE").get< int >(0);
@ -571,16 +568,15 @@ namespace {
}
void Schedule::handleGRUPTREE(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
const auto& unit_system = handlerContext.section.unitSystem();
for (const auto& record : handlerContext.keyword) {
const std::string& childName = trim_wgname(handlerContext.keyword, record.getItem("CHILD_GROUP").get<std::string>(0), parseContext, errors);
const std::string& parentName = trim_wgname(handlerContext.keyword, record.getItem("PARENT_GROUP").get<std::string>(0), parseContext, errors);
if (!hasGroup(childName))
addGroup(childName, handlerContext.currentStep, unit_system);
addGroup(childName, handlerContext.currentStep);
if (!hasGroup(parentName))
addGroup(parentName, handlerContext.currentStep, unit_system);
addGroup(parentName, handlerContext.currentStep);
this->addGroupToGroup(parentName, childName, handlerContext.currentStep);
}
@ -803,7 +799,7 @@ namespace {
}
void Schedule::handleVFPINJ(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
std::shared_ptr<VFPInjTable> table = std::make_shared<VFPInjTable>(handlerContext.keyword, handlerContext.section.unitSystem());
std::shared_ptr<VFPInjTable> table = std::make_shared<VFPInjTable>(handlerContext.keyword, this->unit_system);
int table_id = table->getTableNum();
if (vfpinj_tables.find(table_id) == vfpinj_tables.end()) {
@ -817,7 +813,7 @@ namespace {
}
void Schedule::handleVFPPROD(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
std::shared_ptr<VFPProdTable> table = std::make_shared<VFPProdTable>(handlerContext.keyword, handlerContext.section.unitSystem());
std::shared_ptr<VFPProdTable> table = std::make_shared<VFPProdTable>(handlerContext.keyword, this->unit_system);
int table_id = table->getTableNum();
if (vfpprod_tables.find(table_id) == vfpprod_tables.end()) {
@ -831,7 +827,6 @@ namespace {
}
void Schedule::handleWCONHIST(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
const auto& unit_system = handlerContext.section.unitSystem();
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep);
@ -853,7 +848,7 @@ namespace {
if (table_nr != 0)
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
properties->handleWCONHIST(alq_type, unit_system, record);
properties->handleWCONHIST(alq_type, this->unit_system, record);
if (switching_from_injector) {
properties->resetDefaultBHPLimit();
@ -898,7 +893,6 @@ namespace {
}
void Schedule::handleWCONPROD(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
const auto& unit_system = handlerContext.section.unitSystem();
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep);
@ -922,7 +916,7 @@ namespace {
if (table_nr != 0)
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
properties->handleWCONPROD(alq_type, unit_system, well_name, record);
properties->handleWCONPROD(alq_type, this->unit_system, well_name, record);
if (switching_from_injector)
properties->resetDefaultBHPLimit();
@ -1148,20 +1142,19 @@ namespace {
}
void Schedule::handleWELSPECS(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
const auto& section = handlerContext.section;
const auto& unit_system = section.unitSystem();
const auto COMPORD_in_timestep = [&]() -> const DeckKeyword* {
auto itr = section.begin() + handlerContext.keywordIndex;
const auto& section = *handlerContext.section;
auto itr = section.begin() + handlerContext.keywordIndex.value();
for( ; itr != section.end(); ++itr ) {
if (itr->name() == "DATES") return nullptr;
if (itr->name() == "TSTEP") return nullptr;
if (itr->name() == "COMPORD") return std::addressof( *itr );
}
return nullptr;
};
const auto& keyword = section.getKeyword(handlerContext.keywordIndex);
const auto& keyword = handlerContext.keyword;
for (std::size_t recordNr = 0; recordNr < keyword.size(); recordNr++) {
const auto& record = keyword.getRecord(recordNr);
const std::string& wellName = trim_wgname(keyword, record.getItem<ParserKeywords::WELSPECS::WELL>().get<std::string>(0), parseContext, errors);
@ -1182,7 +1175,7 @@ namespace {
}
if (!hasGroup(groupName))
addGroup(groupName, handlerContext.currentStep, unit_system);
addGroup(groupName, handlerContext.currentStep);
if (!hasWell(wellName)) {
auto wellConnectionOrder = Connection::Order::TRACK;
@ -1200,7 +1193,7 @@ namespace {
}
}
}
this->addWell(wellName, record, handlerContext.currentStep, wellConnectionOrder, unit_system);
this->addWell(wellName, record, handlerContext.currentStep, wellConnectionOrder);
this->addWellToGroup(groupName, wellName, handlerContext.currentStep);
} else {
const auto headI = record.getItem<ParserKeywords::WELSPECS::HEAD_I>().get<int>(0) - 1;
@ -1248,7 +1241,7 @@ namespace {
rates will be wrong.
*/
void Schedule::handleWELTARG(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
const double SiFactorP = handlerContext.section.unitSystem().parse("Pressure").getSIScaling();
const double SiFactorP = this->unit_system.parse("Pressure").getSIScaling();
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
const auto well_names = wellNames(wellNamePattern, handlerContext.currentStep);

View File

@ -130,11 +130,12 @@ namespace {
rft_config(this->m_timeMap),
m_nupcol(this->m_timeMap, runspec.nupcol()),
restart_config(m_timeMap, deck, parseContext, errors),
unit_system(deck.getActiveUnitSystem()),
rpt_config(this->m_timeMap, std::make_shared<RPTConfig>())
{
addGroup( "FIELD", 0, deck.getActiveUnitSystem());
addGroup( "FIELD", 0);
if (rst)
this->load_rst(*rst, grid, fp, deck.getActiveUnitSystem());
this->load_rst(*rst, grid, fp);
/*
We can have the MESSAGES keyword anywhere in the deck, we
@ -261,6 +262,7 @@ namespace {
result.m_nupcol = {{1}, 1};
result.restart_config = RestartConfig::serializeObject();
result.wellgroup_events = {{"test", Events::serializeObject()}};
result.unit_system = UnitSystem::newFIELD();
return result;
}
@ -290,7 +292,18 @@ namespace {
const FieldPropsManager& fp,
std::vector<std::pair<const DeckKeyword*, std::size_t > >& rftProperties) {
const HandlerContext handlerContext { section, keyword, keywordIdx, currentStep, grid, fp };
HandlerContext handlerContext { keyword, currentStep, grid, fp };
/*
The WELSPECS handler needs to look in the same report step for a
COMPORD keyword. This keyword-keyword interaction is quite ugly, so in
this case it is made very explicit - hopefully it can be refactored in
the future.
*/
if (keyword.name() == "WELSPECS") {
handlerContext.section = &section;
handlerContext.keywordIndex = keywordIdx;
}
if (handleNormalKeyword(handlerContext, parseContext, errors))
return;
@ -353,9 +366,8 @@ private:
const FieldPropsManager& fp) {
std::vector<std::pair< const DeckKeyword* , std::size_t> > rftProperties;
const auto& unit_system = section.unitSystem();
std::string time_unit = unit_system.name(UnitSystem::measure::time);
auto convert_time = [&unit_system](double seconds) { return unit_system.from_si(UnitSystem::measure::time, seconds); };
std::string time_unit = this->unit_system.name(UnitSystem::measure::time);
auto convert_time = [this](double seconds) { return this->unit_system.from_si(UnitSystem::measure::time, seconds); };
std::size_t keywordIdx = 0;
std::string current_file;
const auto& time_map = this->m_timeMap;
@ -778,8 +790,7 @@ private:
void Schedule::addWell(const std::string& wellName,
const DeckRecord& record,
std::size_t timeStep,
Connection::Order wellConnectionOrder,
const UnitSystem& unit_system)
Connection::Order wellConnectionOrder)
{
// We change from eclipse's 1 - n, to a 0 - n-1 solution
int headI = record.getItem("HEAD_I").get< int >(0) - 1;
@ -832,8 +843,7 @@ private:
pvt_table,
gas_inflow,
timeStep,
wellConnectionOrder,
unit_system);
wellConnectionOrder);
}
void Schedule::addWell(Well well, std::size_t report_step) {
@ -861,8 +871,7 @@ private:
int pvt_table,
Well::GasInflowEquation gas_inflow,
std::size_t timeStep,
Connection::Order wellConnectionOrder,
const UnitSystem& unit_system) {
Connection::Order wellConnectionOrder) {
Well well(wellName,
group,
@ -873,7 +882,7 @@ private:
WellType(preferredPhase),
this->global_whistctl_mode[timeStep],
wellConnectionOrder,
unit_system,
this->unit_system,
this->getUDQConfig(timeStep).params().undefinedValue(),
drainageRadius,
allowCrossFlow,
@ -1197,10 +1206,10 @@ private:
}
void Schedule::addGroup(const std::string& groupName, std::size_t timeStep, const UnitSystem& unit_system) {
void Schedule::addGroup(const std::string& groupName, std::size_t timeStep) {
const std::size_t insert_index = this->groups.size();
auto udq_undefined = this->getUDQConfig(timeStep).params().undefinedValue();
auto group = Group{ groupName, insert_index, timeStep, udq_undefined, unit_system };
auto group = Group{ groupName, insert_index, timeStep, udq_undefined, this->unit_system };
this->addGroup(group, timeStep);
}
@ -1592,6 +1601,7 @@ private:
rft_config == data.rft_config &&
this->m_nupcol == data.m_nupcol &&
this->restart_config == data.restart_config &&
this->unit_system == data.unit_system &&
this->wellgroup_events == data.wellgroup_events;
}
@ -1601,9 +1611,9 @@ private:
return fmt::format("{:04d}-{:02d}-{:02d}" , ts.year(), ts.month(), ts.day());
}
std::string Schedule::simulationDays(const UnitSystem& unit_system, std::size_t currentStep) const {
const double sim_time { unit_system.from_si(UnitSystem::measure::time, simTime(currentStep)) } ;
return fmt::format("{} {}", sim_time, unit_system.name(UnitSystem::measure::time));
std::string Schedule::simulationDays(std::size_t currentStep) const {
const double sim_time { this->unit_system.from_si(UnitSystem::measure::time, simTime(currentStep)) } ;
return fmt::format("{} {}", sim_time, this->unit_system.name(UnitSystem::measure::time));
}
namespace {
@ -1623,13 +1633,13 @@ namespace {
}
}
void Schedule::load_rst(const RestartIO::RstState& rst_state, const EclipseGrid& grid, const FieldPropsManager& fp, const UnitSystem& unit_system)
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;
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, unit_system };
auto group = Group{ rst_group, this->groups.size(), static_cast<std::size_t>(report_step), udq_undefined, this->unit_system };
this->addGroup(group, report_step);
if (group.isProductionGroup()) {
@ -1657,7 +1667,7 @@ namespace {
}
for (const auto& rst_well : rst_state.wells) {
Opm::Well well(rst_well, report_step, unit_system, udq_undefined);
Opm::Well well(rst_well, report_step, this->unit_system, udq_undefined);
std::vector<Opm::Connection> rst_connections;
for (const auto& rst_conn : rst_well.connections)