Merge pull request #2074 from joakim-hove/handlercontext-units
Make section and keyword index optional in Schedule handlerContext
This commit is contained in:
commit
f5631549bf
@ -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_)
|
||||
{}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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 = §ion;
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user