Merge pull request #2817 from joakim-hove/schedule-fp

Schedule fp
This commit is contained in:
Joakim Hove 2021-11-12 07:52:58 +01:00 committed by GitHub
commit fb1dcd0203
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 355 additions and 297 deletions

View File

@ -137,7 +137,7 @@ namespace Opm {
private:
void initIOConfigPostSchedule(const Deck& deck);
void initTransMult();
void applyMULTXYZ();
void initFaults(const Deck& deck);
void initPara(const Deck& deck);

View File

@ -29,6 +29,7 @@ namespace Opm {
class EclipseGrid;
class Deck;
class DeckKeyword;
class FieldProps;
class Phases;
class TableManager;
@ -47,6 +48,9 @@ public:
virtual std::vector<int> actnum() const;
virtual std::vector<double> porv(bool global = false) const;
void apply_schedule_keywords(const std::vector<DeckKeyword>& keywords);
/*
The number of cells in the fields managed by this FieldPropsManager.
Initially this will correspond to the number of active cells in the grid

View File

@ -598,84 +598,85 @@ namespace Opm
void handleWELPIRuntime(HandlerContext&);
// Normal keyword handlers -- in KeywordHandlers.cpp
void handleBRANPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPDAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPLUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPORD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleEXIT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSALE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGPMAINT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPNET (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPTREE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGUIDERAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLINCOM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMESSAGES (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMULTFLT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMXUNSUPP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNETBALAN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNEXTSTEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNODEPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNUPCOL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLY (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLYO (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTRST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTSCHED (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleTUNING (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSUMTHIN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleUDQ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVAPPARS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPINJ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONHIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJH (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWECON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELOPEN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELPI (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSPECS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELTARG (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWFOAM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWGRUPCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWHISTCTL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWINJTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWMICP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVEDEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPIMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPMITAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPOLYMER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFTPLT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSALT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGITER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGSICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGAICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGVALV (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSKPTAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSOLVENT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTRACER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleBRANPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPDAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPLUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPORD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleCOMPSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRSDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleDRVDTR (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleEXIT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSALE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGCONSUMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGEOKeyword(HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGPMAINT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPNET (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGRUPTREE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleGUIDERAT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleLINCOM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMESSAGES (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMULTFLT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMXUNSUPP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNETBALAN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNEXTSTEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNODEPROP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNUPCOL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLY (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLYO (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTRST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTSCHED (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleTUNING (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleSUMTHIN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleUDQ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVAPPARS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPINJ (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleVFPPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONHIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONINJH (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWCONPROD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWECON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWEFAC (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELOPEN (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELPI (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSEGS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELSPECS (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWELTARG (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWFOAM (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWGRUPCON (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWHISTCTL (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWINJTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIFTOPT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWLIST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWMICP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPAVEDEP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWWPAVE (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPIMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPMITAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWPOLYMER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWRFTPLT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSALT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGITER (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGSICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGAICD (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSEGVALV (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSKPTAB (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWSOLVENT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEMP (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTEST (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTMULT (HandlerContext&, const ParseContext&, ErrorGuard&);
void handleWTRACER (HandlerContext&, const ParseContext&, ErrorGuard&);
};
}

View File

@ -235,17 +235,6 @@ class KeywordLocation;
*/
const static std::string UNIT_SYSTEM_MISMATCH;
/*
Some property modfiers can be modified in the Schedule
section; this effectively means that Eclipse supports time
dependent geology. This is marked as an exocit special
feature in Eclipse, and not supported at all in the
EclipseState object of opm-parser. If these modifiers are
encountered in the Schedule section the behavior is
regulated by this setting.
*/
const static std::string UNSUPPORTED_SCHEDULE_GEO_MODIFIER;
/*
If the third item in the THPRES keyword is defaulted the

View File

@ -149,7 +149,7 @@ AquiferConfig load_aquifers(const Deck& deck, const TableManager& tables, NNC& i
m_title.pop_back();
}
this->initTransMult();
this->applyMULTXYZ();
this->initFaults(deck);
const auto& init_config = this->getInitConfig();
@ -307,16 +307,18 @@ AquiferConfig load_aquifers(const Deck& deck, const TableManager& tables, NNC& i
this->aquifer_config.loadFromRestart(aquifers, this->m_tables);
}
void EclipseState::initTransMult() {
void EclipseState::applyMULTXYZ() {
const auto& fp = this->field_props;
if (fp.has_double("MULTX")) this->m_transMult.applyMULT(fp.get_global_double("MULTX") , FaceDir::XPlus);
if (fp.has_double("MULTX-")) this->m_transMult.applyMULT(fp.get_global_double("MULTX-"), FaceDir::XMinus);
if (fp.has_double("MULTY")) this->m_transMult.applyMULT(fp.get_global_double("MULTY") , FaceDir::YPlus);
if (fp.has_double("MULTY-")) this->m_transMult.applyMULT(fp.get_global_double("MULTY-"), FaceDir::YMinus);
if (fp.has_double("MULTZ")) this->m_transMult.applyMULT(fp.get_global_double("MULTZ") , FaceDir::ZPlus);
if (fp.has_double("MULTZ-")) this->m_transMult.applyMULT(fp.get_global_double("MULTZ-"), FaceDir::ZMinus);
static const std::vector<std::pair<std::string, FaceDir::DirEnum>> multipliers = {{"MULTX" , FaceDir::XPlus},
{"MULTX-", FaceDir::XMinus},
{"MULTY" , FaceDir::YPlus},
{"MULTY-", FaceDir::YMinus},
{"MULTZ" , FaceDir::ZPlus},
{"MULTZ-", FaceDir::ZMinus}};
for (const auto& [field, face] : multipliers) {
if (fp.has_double(field))
this->m_transMult.applyMULT(fp.get_global_double(field), face);
}
}
void EclipseState::initFaults(const Deck& deck) {
@ -361,44 +363,38 @@ AquiferConfig load_aquifers(const Deck& deck, const TableManager& tables, NNC& i
}
}
/*
The apply_schedule_keywords can apply a small set of keywords from the
Schdule section for transmissibility scaling; the currently supported
keywords are: {MULTFLT, MULTX, MULTX-, MULTY, MULTY-, MULTZ, MULTZ-}.
Observe that the multiplier scalars which are in the schedule section are
applied by multiplying with the transmissibility which has already been
calculated, i.e. to increase the permeability you must use a multiplier
greater than one.
*/
void EclipseState::apply_schedule_keywords(const std::vector<DeckKeyword>& keywords) {
using namespace ParserKeywords;
static const std::unordered_set<std::string> multipliers = {"MULTFLT", "MULTX", "MULTX-", "MULTY", "MULTY-", "MULTZ", "MULTZ-"};
for (const auto& keyword : keywords) {
if (keyword.isKeyword<MULTFLT>()) {
for (const auto& record : keyword) {
const std::string& faultName = record.getItem<MULTFLT::fault>().get< std::string >(0);
auto& fault = m_faults.getFault( faultName );
double tmpMultFlt = record.getItem<MULTFLT::factor>().get< double >(0);
double oldMultFlt = fault.getTransMult( );
double newMultFlt = oldMultFlt * tmpMultFlt;
auto multflt = record.getItem<MULTFLT::factor>().get< double >(0);
/*
This extremely contrived way of doing it is because of difference in
behavior and section awareness between the Fault object and the
Transmult object:
1. MULTFLT keywords found in the SCHEDULE section should apply the
transmissibility modifiers cumulatively - i.e. the current
transmissibility across the fault should be *multiplied* with the
newly entered MULTFLT value, and the resulting transmissibility
multplier for this fault should be the product of the newly
entered value and the current value.
2. The TransMult::applyMULTFLT() implementation will *multiply* the
transmissibility across a face with the value in the fault
object. Hence the current value has already been multiplied in;
we therefor first *set* the MULTFLT value to the new value, then
apply it to the TransMult object and then eventually update the
MULTFLT value in the fault instance.
*/
fault.setTransMult( tmpMultFlt );
fault.setTransMult( multflt );
m_transMult.applyMULTFLT( fault );
fault.setTransMult( newMultFlt );
}
}
if (multipliers.count(keyword.name()) == 1)
OpmLog::info(fmt::format("Apply transmissibility multiplier: {}", keyword.name()));
}
this->field_props.apply_schedule_keywords(keywords);
this->applyMULTXYZ();
}

View File

@ -791,7 +791,7 @@ void FieldProps::handle_double_keyword(Section section, const Fieldprops::keywor
const auto& deck_data = keyword.getSIDoubleData();
const auto& deck_status = keyword.getValueStatus();
if (section == Section::EDIT && kw_info.multiplier)
if ((section == Section::EDIT || section == Section::SCHEDULE) && kw_info.multiplier)
multiply_deck(kw_info, keyword, field_data, deck_data, deck_status, box);
else
assign_deck(kw_info, keyword, field_data, deck_data, deck_status, box);
@ -1272,21 +1272,31 @@ void FieldProps::scanSOLUTIONSection(const SOLUTIONSection& solution_section) {
}
}
void FieldProps::scanSCHEDULESection(const SCHEDULESection& schedule_section) {
void FieldProps::handle_schedule_keywords(const std::vector<DeckKeyword>& keywords) {
Box box(*this->grid_ptr);
for (const auto& keyword : schedule_section) {
// When called in the SCHEDULE section the context is that the scaling factors
// have already been applied.
for (const auto& [kw, _] : Fieldprops::keywords::SCHEDULE::double_keywords) {
(void)_;
if (this->has<double>(kw)) {
auto& field_data = this->init_get<double>(kw);
field_data.default_assign(1.0);
}
}
for (const auto& keyword : keywords) {
const std::string& name = keyword.name();
if (Fieldprops::keywords::SCHEDULE::double_keywords.count(name) == 1) {
this->handle_double_keyword(Section::SCHEDULE, Fieldprops::keywords::SCHEDULE::double_keywords.at(name), keyword, box);
continue;
}
if (Fieldprops::keywords::SCHEDULE::int_keywords.count(name) == 1) {
this->handle_int_keyword(Fieldprops::keywords::SCHEDULE::int_keywords.at(name), keyword, box);
if (Fieldprops::keywords::box_keywords.count(name) == 1) {
handle_box_keyword(keyword, box);
continue;
}
this->handle_keyword(keyword, box);
}
}

View File

@ -267,7 +267,13 @@ static const std::unordered_map<std::string, keyword_info<double>> double_keywor
namespace SCHEDULE {
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {};
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
{"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
{"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
{"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
{"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
{"MULTZ-", keyword_info<double>{}.init(1.0).mult(true)}};
static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ROCKNUM", keyword_info<int>{}}};
}
@ -485,6 +491,7 @@ public:
return this->double_data.size();
}
void handle_schedule_keywords(const std::vector<DeckKeyword>& keywords);
bool tran_active(const std::string& keyword) const;
void apply_tran(const std::string& keyword, std::vector<double>& data);
std::vector<char> serialize_tran() const;
@ -497,7 +504,6 @@ private:
void scanPROPSSection(const PROPSSection& props_section);
void scanREGIONSSection(const REGIONSSection& regions_section);
void scanSOLUTIONSection(const SOLUTIONSection& solution_section);
void scanSCHEDULESection(const SCHEDULESection& schedule_section);
double getSIValue(const std::string& keyword, double raw_value) const;
double getSIValue(ScalarOperation op, const std::string& keyword, double raw_value) const;
template <typename T>

View File

@ -18,6 +18,7 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
@ -46,6 +47,10 @@ void FieldPropsManager::reset_actnum(const std::vector<int>& actnum) {
this->fp->reset_actnum(actnum);
}
void FieldPropsManager::apply_schedule_keywords(const std::vector<DeckKeyword>& keywords) {
this->fp->handle_schedule_keywords(keywords);
}
template <typename T>
const std::vector<T>& FieldPropsManager::get(const std::string& keyword) const {

View File

@ -721,16 +721,22 @@ namespace {
this->snapshots.back().message_limits().update( handlerContext.keyword );
}
void Schedule::handleMULTFLT (HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
void Schedule::handleMULTFLT(HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
this->snapshots.back().geo_keywords().push_back(handlerContext.keyword);
this->snapshots.back().events().addEvent( ScheduleEvents::GEO_MODIFIER );
}
void Schedule::handleMXUNSUPP(HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
void Schedule::handleGEOKeyword(HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
this->snapshots.back().geo_keywords().push_back(handlerContext.keyword);
this->snapshots.back().events().addEvent( ScheduleEvents::GEO_MODIFIER );
}
void Schedule::handleMXUNSUPP(HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
std::string msg_fmt = fmt::format("Problem with keyword {{keyword}} at report step {}\n"
"In {{file}} line {{line}}\n"
"OPM does not support grid property modifier {} in the Schedule section", handlerContext.currentStep, handlerContext.keyword.name());
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg_fmt, handlerContext.keyword.location(), errors );
OpmLog::warning(OpmInputError::format(msg_fmt, handlerContext.keyword.location()));
}
void Schedule::handleNETBALAN(HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
@ -2094,97 +2100,99 @@ namespace {
bool Schedule::handleNormalKeyword(HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
using handler_function = void (Schedule::*)(HandlerContext&, const ParseContext&, ErrorGuard&);
static const std::unordered_map<std::string,handler_function> handler_functions = {
{ "BRANPROP", &Schedule::handleBRANPROP },
{ "COMPDAT" , &Schedule::handleCOMPDAT },
{ "COMPLUMP", &Schedule::handleCOMPLUMP },
{ "COMPORD" , &Schedule::handleCOMPORD },
{ "COMPSEGS", &Schedule::handleCOMPSEGS },
{ "DRSDT" , &Schedule::handleDRSDT },
{ "DRSDTCON", &Schedule::handleDRSDTCON },
{ "DRSDTR" , &Schedule::handleDRSDTR },
{ "DRVDT" , &Schedule::handleDRVDT },
{ "DRVDTR" , &Schedule::handleDRVDTR },
{ "EXIT", &Schedule::handleEXIT },
{ "GCONINJE", &Schedule::handleGCONINJE },
{ "GCONPROD", &Schedule::handleGCONPROD },
{ "GCONSALE", &Schedule::handleGCONSALE },
{ "GCONSUMP", &Schedule::handleGCONSUMP },
{ "GEFAC" , &Schedule::handleGEFAC },
{ "GLIFTOPT", &Schedule::handleGLIFTOPT },
{ "GPMAINT" , &Schedule::handleGPMAINT },
{ "GRUPNET" , &Schedule::handleGRUPNET },
{ "GRUPTREE", &Schedule::handleGRUPTREE },
{ "GUIDERAT", &Schedule::handleGUIDERAT },
{ "LIFTOPT" , &Schedule::handleLIFTOPT },
{ "LINCOM" , &Schedule::handleLINCOM },
{ "MESSAGES", &Schedule::handleMESSAGES },
{ "MULTFLT" , &Schedule::handleMULTFLT },
{ "MULTPV" , &Schedule::handleMXUNSUPP },
{ "MULTR" , &Schedule::handleMXUNSUPP },
{ "MULTR-" , &Schedule::handleMXUNSUPP },
{ "MULTREGT", &Schedule::handleMXUNSUPP },
{ "MULTSIG" , &Schedule::handleMXUNSUPP },
{ "MULTSIGV", &Schedule::handleMXUNSUPP },
{ "MULTTHT" , &Schedule::handleMXUNSUPP },
{ "MULTTHT-", &Schedule::handleMXUNSUPP },
{ "MULTX" , &Schedule::handleMXUNSUPP },
{ "MULTX-" , &Schedule::handleMXUNSUPP },
{ "MULTY" , &Schedule::handleMXUNSUPP },
{ "MULTY-" , &Schedule::handleMXUNSUPP },
{ "MULTZ" , &Schedule::handleMXUNSUPP },
{ "MULTZ-" , &Schedule::handleMXUNSUPP },
{ "NETBALAN", &Schedule::handleNETBALAN },
{ "NEXTSTEP", &Schedule::handleNEXTSTEP },
{ "NODEPROP", &Schedule::handleNODEPROP },
{ "NUPCOL" , &Schedule::handleNUPCOL },
{ "RPTONLY" , &Schedule::handleRPTONLY },
{ "RPTONLYO", &Schedule::handleRPTONLYO },
{ "RPTRST" , &Schedule::handleRPTRST },
{ "RPTSCHED", &Schedule::handleRPTSCHED },
{ "SAVE" , &Schedule::handleSAVE },
{ "SUMTHIN" , &Schedule::handleSUMTHIN },
{ "TUNING" , &Schedule::handleTUNING },
{ "UDQ" , &Schedule::handleUDQ },
{ "VAPPARS" , &Schedule::handleVAPPARS },
{ "VFPINJ" , &Schedule::handleVFPINJ },
{ "VFPPROD" , &Schedule::handleVFPPROD },
{ "WCONHIST", &Schedule::handleWCONHIST },
{ "WCONINJE", &Schedule::handleWCONINJE },
{ "WCONINJH", &Schedule::handleWCONINJH },
{ "WCONPROD", &Schedule::handleWCONPROD },
{ "WECON" , &Schedule::handleWECON },
{ "WEFAC" , &Schedule::handleWEFAC },
{ "WELOPEN" , &Schedule::handleWELOPEN },
{ "WELPI" , &Schedule::handleWELPI },
{ "WELSEGS" , &Schedule::handleWELSEGS },
{ "WELSPECS", &Schedule::handleWELSPECS },
{ "WELTARG" , &Schedule::handleWELTARG },
{ "WFOAM" , &Schedule::handleWFOAM },
{ "WGRUPCON", &Schedule::handleWGRUPCON },
{ "WHISTCTL", &Schedule::handleWHISTCTL },
{ "WINJTEMP", &Schedule::handleWINJTEMP },
{ "WLIFTOPT", &Schedule::handleWLIFTOPT },
{ "WLIST" , &Schedule::handleWLIST },
{ "WMICP" , &Schedule::handleWMICP },
{ "WPAVE" , &Schedule::handleWPAVE },
{ "WPAVEDEP", &Schedule::handleWPAVEDEP },
{ "WWPAVE" , &Schedule::handleWWPAVE },
{ "WPIMULT" , &Schedule::handleWPIMULT },
{ "WPMITAB" , &Schedule::handleWPMITAB },
{ "WPOLYMER", &Schedule::handleWPOLYMER },
{ "WRFT" , &Schedule::handleWRFT },
{ "WRFTPLT" , &Schedule::handleWRFTPLT },
{ "WSALT" , &Schedule::handleWSALT },
{ "WSEGITER", &Schedule::handleWSEGITER },
{ "WSEGSICD", &Schedule::handleWSEGSICD },
{ "WSEGAICD", &Schedule::handleWSEGAICD },
{ "WSEGVALV", &Schedule::handleWSEGVALV },
{ "WSKPTAB" , &Schedule::handleWSKPTAB },
{ "WSOLVENT", &Schedule::handleWSOLVENT },
{ "WTEMP" , &Schedule::handleWTEMP },
{ "WTEST" , &Schedule::handleWTEST },
{ "WTMULT" , &Schedule::handleWTMULT },
{ "WTRACER" , &Schedule::handleWTRACER },
{ "BOX", &Schedule::handleGEOKeyword},
{ "BRANPROP", &Schedule::handleBRANPROP },
{ "COMPDAT" , &Schedule::handleCOMPDAT },
{ "COMPLUMP", &Schedule::handleCOMPLUMP },
{ "COMPORD" , &Schedule::handleCOMPORD },
{ "COMPSEGS", &Schedule::handleCOMPSEGS },
{ "DRSDT" , &Schedule::handleDRSDT },
{ "DRSDTCON", &Schedule::handleDRSDTCON },
{ "DRSDTR" , &Schedule::handleDRSDTR },
{ "DRVDT" , &Schedule::handleDRVDT },
{ "DRVDTR" , &Schedule::handleDRVDTR },
{ "ENDBOX" , &Schedule::handleGEOKeyword},
{ "EXIT", &Schedule::handleEXIT },
{ "GCONINJE", &Schedule::handleGCONINJE },
{ "GCONPROD", &Schedule::handleGCONPROD },
{ "GCONSALE", &Schedule::handleGCONSALE },
{ "GCONSUMP", &Schedule::handleGCONSUMP },
{ "GEFAC" , &Schedule::handleGEFAC },
{ "GLIFTOPT", &Schedule::handleGLIFTOPT },
{ "GPMAINT" , &Schedule::handleGPMAINT },
{ "GRUPNET" , &Schedule::handleGRUPNET },
{ "GRUPTREE", &Schedule::handleGRUPTREE },
{ "GUIDERAT", &Schedule::handleGUIDERAT },
{ "LIFTOPT" , &Schedule::handleLIFTOPT },
{ "LINCOM" , &Schedule::handleLINCOM },
{ "MESSAGES", &Schedule::handleMESSAGES },
{ "MULTFLT" , &Schedule::handleMULTFLT },
{ "MULTPV" , &Schedule::handleMXUNSUPP },
{ "MULTR" , &Schedule::handleMXUNSUPP },
{ "MULTR-" , &Schedule::handleMXUNSUPP },
{ "MULTREGT", &Schedule::handleMXUNSUPP },
{ "MULTSIG" , &Schedule::handleMXUNSUPP },
{ "MULTSIGV", &Schedule::handleMXUNSUPP },
{ "MULTTHT" , &Schedule::handleMXUNSUPP },
{ "MULTTHT-", &Schedule::handleMXUNSUPP },
{ "MULTX" , &Schedule::handleGEOKeyword},
{ "MULTX-" , &Schedule::handleGEOKeyword},
{ "MULTY" , &Schedule::handleGEOKeyword},
{ "MULTY-" , &Schedule::handleGEOKeyword},
{ "MULTZ" , &Schedule::handleGEOKeyword},
{ "MULTZ-" , &Schedule::handleGEOKeyword},
{ "NETBALAN", &Schedule::handleNETBALAN },
{ "NEXTSTEP", &Schedule::handleNEXTSTEP },
{ "NODEPROP", &Schedule::handleNODEPROP },
{ "NUPCOL" , &Schedule::handleNUPCOL },
{ "RPTONLY" , &Schedule::handleRPTONLY },
{ "RPTONLYO", &Schedule::handleRPTONLYO },
{ "RPTRST" , &Schedule::handleRPTRST },
{ "RPTSCHED", &Schedule::handleRPTSCHED },
{ "SAVE" , &Schedule::handleSAVE },
{ "SUMTHIN" , &Schedule::handleSUMTHIN },
{ "TUNING" , &Schedule::handleTUNING },
{ "UDQ" , &Schedule::handleUDQ },
{ "VAPPARS" , &Schedule::handleVAPPARS },
{ "VFPINJ" , &Schedule::handleVFPINJ },
{ "VFPPROD" , &Schedule::handleVFPPROD },
{ "WCONHIST", &Schedule::handleWCONHIST },
{ "WCONINJE", &Schedule::handleWCONINJE },
{ "WCONINJH", &Schedule::handleWCONINJH },
{ "WCONPROD", &Schedule::handleWCONPROD },
{ "WECON" , &Schedule::handleWECON },
{ "WEFAC" , &Schedule::handleWEFAC },
{ "WELOPEN" , &Schedule::handleWELOPEN },
{ "WELPI" , &Schedule::handleWELPI },
{ "WELSEGS" , &Schedule::handleWELSEGS },
{ "WELSPECS", &Schedule::handleWELSPECS },
{ "WELTARG" , &Schedule::handleWELTARG },
{ "WFOAM" , &Schedule::handleWFOAM },
{ "WGRUPCON", &Schedule::handleWGRUPCON },
{ "WHISTCTL", &Schedule::handleWHISTCTL },
{ "WINJTEMP", &Schedule::handleWINJTEMP },
{ "WLIFTOPT", &Schedule::handleWLIFTOPT },
{ "WLIST" , &Schedule::handleWLIST },
{ "WMICP" , &Schedule::handleWMICP },
{ "WPAVE" , &Schedule::handleWPAVE },
{ "WPAVEDEP", &Schedule::handleWPAVEDEP },
{ "WWPAVE" , &Schedule::handleWWPAVE },
{ "WPIMULT" , &Schedule::handleWPIMULT },
{ "WPMITAB" , &Schedule::handleWPMITAB },
{ "WPOLYMER", &Schedule::handleWPOLYMER },
{ "WRFT" , &Schedule::handleWRFT },
{ "WRFTPLT" , &Schedule::handleWRFTPLT },
{ "WSALT" , &Schedule::handleWSALT },
{ "WSEGITER", &Schedule::handleWSEGITER },
{ "WSEGSICD", &Schedule::handleWSEGSICD },
{ "WSEGAICD", &Schedule::handleWSEGAICD },
{ "WSEGVALV", &Schedule::handleWSEGVALV },
{ "WSKPTAB" , &Schedule::handleWSKPTAB },
{ "WSOLVENT", &Schedule::handleWSOLVENT },
{ "WTEMP" , &Schedule::handleWTEMP },
{ "WTEST" , &Schedule::handleWTEST },
{ "WTMULT" , &Schedule::handleWTMULT },
{ "WTRACER" , &Schedule::handleWTRACER },
};
auto function_iterator = handler_functions.find(handlerContext.keyword.name());

View File

@ -90,7 +90,6 @@ namespace Opm {
this->addKey(RUNSPEC_NUMGROUPS_TOO_LARGE, InputError::THROW_EXCEPTION);
this->addKey(RUNSPEC_GROUPSIZE_TOO_LARGE, InputError::THROW_EXCEPTION);
addKey(UNSUPPORTED_SCHEDULE_GEO_MODIFIER, InputError::THROW_EXCEPTION);
addKey(UNSUPPORTED_INITIAL_THPRES, InputError::THROW_EXCEPTION);
addKey(UNSUPPORTED_TERMINATE_IF_BHP, InputError::THROW_EXCEPTION);
@ -338,7 +337,6 @@ namespace Opm {
const std::string ParseContext::RUNSPEC_NUMGROUPS_TOO_LARGE = "RUNSPEC_NUMGROUPS_TOO_LARGE";
const std::string ParseContext::RUNSPEC_GROUPSIZE_TOO_LARGE = "RUNSPEC_GROUPSIZE_TOO_LARGE";
const std::string ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER = "UNSUPPORTED_SCHEDULE_GEO_MODIFIER";
const std::string ParseContext::UNSUPPORTED_INITIAL_THPRES = "UNSUPPORTED_INITIAL_THPRES";
const std::string ParseContext::UNSUPPORTED_TERMINATE_IF_BHP = "UNSUPPORTED_TERMINATE_IF_BHP";

View File

@ -2,7 +2,8 @@
"name": "MULT_XYZ",
"sections": [
"GRID",
"EDIT"
"EDIT",
"SCHEDULE"
],
"deck_names": [
"MULTTHT",

View File

@ -33,6 +33,7 @@
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Python/Python.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
@ -43,6 +44,7 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include "src/opm/parser/eclipse/EclipseState/Grid/FieldProps.hpp"
@ -2596,3 +2598,106 @@ COPYREG
BOOST_CHECK( FieldPropsManager::rst_cmp(fp, fp2) );
(void) satnum;
}
BOOST_AUTO_TEST_CASE(SCHEDULE_MULTZ) {
std::string deck_string1 = R"(
GRID
PORO
200*0.15 /
PERMX
200*1 /
REGIONS
FIPNUM
200*1 /
MULTNUM
50*1 50*2 100*3 /
EDIT
MULTZ
200*3 /
SCHEDULE
TSTEP
1 /
BOX
1 10 1 10 1 1 /
MULTZ
100*2 /
ENDBOX
TSTEP
1 /
BOX
1 10 1 10 2 2 /
MULTZ
100*4 /
ENDBOX
TSTEP
10 /
MULTZ
100*2 100*4/
MULTZ
200*10 /
)";
UnitSystem unit_system(UnitSystem::UnitType::UNIT_TYPE_METRIC);
EclipseGrid grid(10,10, 2);
Deck deck = Parser{}.parseString(deck_string1);
TableManager tables;
FieldPropsManager fp(deck, Phases{true, true, true}, grid, tables);
Runspec runspec (deck);
auto python = std::make_shared<Python>();
Schedule sched(deck, grid, fp, runspec, python);
const auto& multz0 = fp.get_double("MULTZ");
for (std::size_t k=0; k < 2; k++) {
for (std::size_t ij=0; ij < 100; ij++)
BOOST_CHECK_EQUAL(multz0[ij + k*100], 3.0);
}
// Observe that the MULTZ multiplier is reset to 1.0 for every timestep
const auto& sched1 = sched[1];
fp.apply_schedule_keywords(sched1.geo_keywords());
const auto& multz1 = fp.get_double("MULTZ");
for (std::size_t ij=0; ij < 100; ij++) {
BOOST_CHECK_EQUAL(multz1[ij] , 2.0);
BOOST_CHECK_EQUAL(multz1[ij + 100], 1.0);
}
const auto& sched2 = sched[2];
fp.apply_schedule_keywords(sched2.geo_keywords());
const auto& multz2 = fp.get_double("MULTZ");
for (std::size_t ij=0; ij < 100; ij++) {
BOOST_CHECK_EQUAL(multz2[ij] , 1.0);
BOOST_CHECK_EQUAL(multz2[ij + 100], 4.0);
}
const auto& sched3 = sched[3];
fp.apply_schedule_keywords(sched3.geo_keywords());
for (std::size_t ij=0; ij < 100; ij++) {
BOOST_CHECK_EQUAL(multz2[ij] , 20.0);
BOOST_CHECK_EQUAL(multz2[ij + 100], 40.0);
}
}

View File

@ -88,7 +88,6 @@ TSTEP -- 3,4
TableManager table ( deck );
FieldPropsManager fp( deck, Phases{true, true, true}, grid, table);
parseContext.update( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::IGNORE );
{
Runspec runspec ( deck );
Schedule schedule( deck, grid , fp, runspec , parseContext, errors, python);

View File

@ -286,70 +286,6 @@ BOOST_AUTO_TEST_CASE( CheckMissingSizeKeyword) {
}
BOOST_AUTO_TEST_CASE( CheckUnsupportedInSCHEDULE ) {
const char * deckStringUnSupported =
"START\n"
" 10 'JAN' 2000 /\n"
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 / \n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DY\n"
"1000*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"SCHEDULE\n"
"MULTZ\n"
" 1000*0.10 /\n"
"\n";
const char * deckStringSupported =
"START\n"
" 10 'JAN' 2000 /\n"
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 / \n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DY\n"
"1000*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"SCHEDULE\n"
"MULTFLT\n"
" 'F1' 0.10 /\n"
"/\n"
"\n";
ErrorGuard errors;
ParseContext parseContext;
Parser parser(true);
auto deckSupported = parser.parseString( deckStringSupported , parseContext, errors );
auto deckUnSupported = parser.parseString( deckStringUnSupported , parseContext, errors );
EclipseGrid grid( deckSupported );
TableManager table ( deckSupported );
FieldPropsManager fp(deckSupported, Phases{true, true, true}, grid, table);
Runspec runspec(deckSupported);
auto python = std::make_shared<Python>();
parseContext.update( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::IGNORE );
BOOST_CHECK_NO_THROW( Schedule( deckSupported , grid , fp, runspec, parseContext, errors, python ));
BOOST_CHECK_NO_THROW( Schedule( deckUnSupported, grid , fp, runspec, parseContext, errors, python ));
parseContext.update( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( Schedule( deckUnSupported , grid , fp, runspec , parseContext , errors, python), OpmInputError );
BOOST_CHECK_NO_THROW( Schedule( deckSupported , grid , fp, runspec , parseContext, errors, python));
}
BOOST_AUTO_TEST_CASE(TestRandomSlash) {
const char * deck1 =