#804 Updated opm-parser based on

a3496df501a4369fd827fbf0ff893d03deff425f
This commit is contained in:
Magne Sjaastad 2016-10-13 13:37:07 +02:00
parent 0306168bb4
commit 83e000c91f
269 changed files with 9563 additions and 4741 deletions

View File

@ -1,11 +1,9 @@
cmake_minimum_required (VERSION 2.8)
# -DBOOST_FILESYSTEM_VERSION=3 -DBOOST_TEST_DYN_LINK -DHAVE_CASE_SENSITIVE_FILESYSTEM=1 -DHAVE_REGEX=1 -DOPM_PARSER_DECK_API=1 -Wall -std=c++11 -fopenmp -Wall -g -O0 -DDEBUG -ggdb3
if(MSVC)
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996" )
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4244 /wd4267" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
else()
#always set these flags to make opm-parser compile on Linux
@ -19,319 +17,20 @@ project (custom-opm-parser)
include_directories(
${Boost_INCLUDE_DIRS}
${ResInsight_SOURCE_DIR}/ThirdParty/custom-opm-common/opm-common/
${ERT_INCLUDE_DIRS}
)
# TODO: opm-parser should hold a cmake file with source code files only
#include(opm-parser/CMakeLists_files.cmake)
set( rawdeck_source
RawDeck/StarToken.cpp
RawDeck/RawKeyword.cpp
RawDeck/RawRecord.cpp )
set( unit_source
Units/UnitSystem.cpp
Units/Dimension.cpp)
set( deck_source
Deck/Deck.cpp
Deck/DeckKeyword.cpp
Deck/DeckRecord.cpp
Deck/DeckItem.cpp
Deck/Section.cpp
Deck/SCHEDULESection.cpp
Deck/DeckTimeStep.cpp
)
set( parser_source
Parser/ParseContext.cpp
Parser/MessageContainer.cpp
Parser/ParserEnums.cpp
Parser/ParserKeyword.cpp
Parser/Parser.cpp
Parser/ParserRecord.cpp
Parser/ParserItem.cpp
Parser/ParserIntItem.cpp
Parser/ParserDoubleItem.cpp
Parser/ParserStringItem.cpp
)
set( generator_source
Generator/KeywordGenerator.cpp
Generator/KeywordLoader.cpp )
set( build_parser_source
Parser/ParseContext.cpp
Parser/MessageContainer.cpp
Parser/ParserEnums.cpp
Parser/ParserKeyword.cpp
Parser/ParserRecord.cpp
Parser/ParserItem.cpp
Parser/ParserIntItem.cpp
Parser/ParserDoubleItem.cpp
Parser/ParserStringItem.cpp
${generator_source}
)
set (state_source
EclipseState/EclipseState.cpp
EclipseState/EclipseConfig.cpp
EclipseState/Eclipse3DProperties.cpp
EclipseState/Messages.cpp
#
EclipseState/checkDeck.cpp
#
EclipseState/Schedule/OilVaporizationProperties.cpp
EclipseState/Schedule/TimeMap.cpp
EclipseState/Schedule/Schedule.cpp
EclipseState/Schedule/Well.cpp
EclipseState/Schedule/WellProductionProperties.cpp
EclipseState/Schedule/WellInjectionProperties.cpp
EclipseState/Schedule/WellPolymerProperties.cpp
EclipseState/Schedule/MSW/Segment.cpp
EclipseState/Schedule/MSW/SegmentSet.cpp
EclipseState/Schedule/MSW/Compsegs.cpp
EclipseState/Schedule/WellSet.cpp
EclipseState/Schedule/Group.cpp
EclipseState/Schedule/Completion.cpp
EclipseState/Schedule/CompletionSet.cpp
EclipseState/Schedule/ScheduleEnums.cpp
EclipseState/Schedule/GroupTreeNode.cpp
EclipseState/Schedule/GroupTree.cpp
EclipseState/Schedule/Tuning.cpp
EclipseState/Schedule/Events.cpp
#
EclipseState/Tables/SimpleTable.cpp
EclipseState/Tables/VFPProdTable.cpp
EclipseState/Tables/VFPInjTable.cpp
EclipseState/Tables/TableManager.cpp
EclipseState/Tables/TableContainer.cpp
EclipseState/Tables/TableColumn.cpp
EclipseState/Tables/ColumnSchema.cpp
EclipseState/Tables/TableSchema.cpp
EclipseState/Tables/TableIndex.cpp
EclipseState/Tables/PvtxTable.cpp
EclipseState/Tables/Tables.cpp
#
EclipseState/Grid/SatfuncPropertyInitializers.cpp
EclipseState/Grid/GridProperty.cpp
EclipseState/Grid/GridProperties.cpp
EclipseState/Grid/Box.cpp
EclipseState/Grid/BoxManager.cpp
EclipseState/Grid/FaceDir.cpp
EclipseState/Grid/TransMult.cpp
EclipseState/Grid/MULTREGTScanner.cpp
EclipseState/Grid/EclipseGrid.cpp
EclipseState/Grid/FaultFace.cpp
EclipseState/Grid/Fault.cpp
EclipseState/Grid/FaultCollection.cpp
EclipseState/Grid/NNC.cpp
EclipseState/Grid/PinchMode.cpp
#
EclipseState/InitConfig/InitConfig.cpp
EclipseState/InitConfig/Equil.cpp
EclipseState/SimulationConfig/SimulationConfig.cpp
EclipseState/SimulationConfig/ThresholdPressure.cpp
EclipseState/SummaryConfig/SummaryConfig.cpp
EclipseState/IOConfig/IOConfig.cpp)
#
set( utility_source
Utility/Functional.cpp
Utility/Stringview.cpp
)
set( HEADER_FILES
RawDeck/RawConsts.hpp
RawDeck/RawKeyword.hpp
RawDeck/RawRecord.hpp
RawDeck/StarToken.hpp
RawDeck/RawEnums.hpp
#
Deck/Deck.hpp
Deck/DeckKeyword.hpp
Deck/DeckRecord.hpp
Deck/DeckItem.hpp
Deck/Section.hpp
Deck/SCHEDULESection.hpp
Deck/DeckTimeStep.hpp
#
Parser/ParserEnums.hpp
Parser/ParserKeyword.hpp
Parser/Parser.hpp
Parser/ParserRecord.hpp
Parser/ParserItem.hpp
Parser/ParserIntItem.hpp
Parser/ParserDoubleItem.hpp
Parser/ParserStringItem.hpp
Parser/InputErrorAction.hpp
Parser/ParseContext.hpp
Parser/MessageContainer.hpp
#
Generator/KeywordLoader.hpp
Generator/KeywordGenerator.hpp
#
Units/UnitSystem.hpp
Units/Dimension.hpp
Units/ConversionFactors.hpp
#
EclipseState/EclipseState.hpp
EclipseState/EclipseConfig.hpp
EclipseState/Eclipse3DProperties.hpp
EclipseState/Messages.hpp
#
EclipseState/checkDeck.hpp
#
EclipseState/Schedule/OilVaporizationProperties.hpp
EclipseState/Schedule/TimeMap.hpp
EclipseState/Schedule/Schedule.hpp
EclipseState/Schedule/Well.hpp
EclipseState/Schedule/WellProductionProperties.hpp
EclipseState/Schedule/WellInjectionProperties.hpp
EclipseState/Schedule/WellPolymerProperties.hpp
EclipseState/Schedule/MSW/Segment.hpp
EclipseState/Schedule/MSW/SegmentSet.hpp
EclipseState/Schedule/MSW/Compsegs.hpp
EclipseState/Schedule/WellSet.hpp
EclipseState/Schedule/Group.hpp
EclipseState/Schedule/DynamicState.hpp
EclipseState/Schedule/DynamicVector.hpp
EclipseState/Schedule/Completion.hpp
EclipseState/Schedule/CompletionSet.hpp
EclipseState/Schedule/ScheduleEnums.hpp
EclipseState/Schedule/GroupTreeNode.hpp
EclipseState/Schedule/GroupTree.hpp
EclipseState/Schedule/Tuning.hpp
EclipseState/Schedule/Events.hpp
#
EclipseState/Util/RecordVector.hpp
EclipseState/Util/OrderedMap.hpp
EclipseState/Util/Value.hpp
#
EclipseState/Grid/EclipseGrid.hpp
EclipseState/Grid/GridProperty.hpp
EclipseState/Grid/GridProperties.hpp
EclipseState/Grid/SatfuncPropertyInitializers.hpp
EclipseState/Grid/Box.hpp
EclipseState/Grid/BoxManager.hpp
EclipseState/Grid/FaceDir.hpp
EclipseState/Grid/MinpvMode.hpp
EclipseState/Grid/PinchMode.hpp
EclipseState/Grid/MULTREGTScanner.hpp
EclipseState/Grid/TransMult.hpp
EclipseState/Grid/FaultFace.hpp
EclipseState/Grid/Fault.hpp
EclipseState/Grid/FaultCollection.hpp
EclipseState/Grid/NNC.hpp
#
EclipseState/InitConfig/InitConfig.hpp
EclipseState/InitConfig/Equil.hpp
EclipseState/SimulationConfig/SimulationConfig.hpp
EclipseState/SimulationConfig/ThresholdPressure.hpp
EclipseState/SummaryConfig/SummaryConfig.hpp
EclipseState/IOConfig/IOConfig.hpp
#
EclipseState/Tables/Tabdims.hpp
EclipseState/Tables/Eqldims.hpp
EclipseState/Tables/Regdims.hpp
EclipseState/Tables/PlyadsTable.hpp
EclipseState/Tables/PvtoTable.hpp
EclipseState/Tables/RocktabTable.hpp
EclipseState/Tables/PvdoTable.hpp
EclipseState/Tables/PvdgTable.hpp
EclipseState/Tables/PvdsTable.hpp
EclipseState/Tables/SimpleTable.hpp
EclipseState/Tables/PlymaxTable.hpp
EclipseState/Tables/PlyrockTable.hpp
EclipseState/Tables/SwofTable.hpp
EclipseState/Tables/SgwfnTable.hpp
EclipseState/Tables/SwfnTable.hpp
EclipseState/Tables/SgfnTable.hpp
EclipseState/Tables/SsfnTable.hpp
EclipseState/Tables/Sof2Table.hpp
EclipseState/Tables/Sof3Table.hpp
EclipseState/Tables/EnptvdTable.hpp
EclipseState/Tables/PlyviscTable.hpp
EclipseState/Tables/PlydhflfTable.hpp
EclipseState/Tables/PlyshlogTable.hpp
EclipseState/Tables/EnkrvdTable.hpp
EclipseState/Tables/ImkrvdTable.hpp
EclipseState/Tables/SgofTable.hpp
EclipseState/Tables/SlgofTable.hpp
EclipseState/Tables/PvtxTable.hpp
EclipseState/Tables/ImptvdTable.hpp
EclipseState/Tables/RsvdTable.hpp
EclipseState/Tables/RvvdTable.hpp
EclipseState/Tables/RtempvdTable.hpp
EclipseState/Tables/OilvisctTable.hpp
EclipseState/Tables/GasvisctTable.hpp
EclipseState/Tables/WatvisctTable.hpp
EclipseState/Tables/PvtgTable.hpp
EclipseState/Tables/VFPProdTable.hpp
EclipseState/Tables/VFPInjTable.hpp
EclipseState/Tables/TableManager.hpp
EclipseState/Tables/TableContainer.hpp
EclipseState/Tables/SorwmisTable.hpp
EclipseState/Tables/SgcwmisTable.hpp
EclipseState/Tables/MiscTable.hpp
EclipseState/Tables/PmiscTable.hpp
EclipseState/Tables/TlpmixpaTable.hpp
EclipseState/Tables/MsfnTable.hpp
EclipseState/Tables/TableColumn.hpp
EclipseState/Tables/ColumnSchema.hpp
EclipseState/Tables/TableEnums.hpp
EclipseState/Tables/TableSchema.hpp
EclipseState/Tables/TableIndex.hpp
#
Utility/Functional.hpp
Utility/Stringview.hpp)
include_directories(
opm-parser
generated-source/include
)
set(opm_parser_source_files
${generated_source}
${state_source}
${rawdeck_source}
${parser_source}
${deck_source}
${unit_source}
${generator_source}
${utility_source}
)
foreach (file ${opm_parser_source_files} )
list(APPEND incl_path "opm-parser/opm/parser/eclipse/${file}" )
endforeach()
set(opm_parser_generated_source_files
generated-source/ParserKeywords.cpp
generated-source/ParserKeywords0.cpp
generated-source/ParserKeywords1.cpp
generated-source/ParserKeywords2.cpp
generated-source/ParserKeywords3.cpp
)
# JSON files included directly, not as a separate lib as in original build configuration
set (json_source
opm-parser/opm/json/JsonObject.cpp
opm-parser/opm/json/cjson/cJSON.c
)
# TODO: opm-parser should hold a cmake file with source code files only
#include(opm-parser/CMakeLists_files.cmake)
include ( CMakeLists_files.cmake )
add_library(${PROJECT_NAME}
STATIC
${incl_path}
${json_source}
${opm_parser_generated_source_files}
${opm_parser_source_files}
)

View File

@ -0,0 +1,304 @@
#
# All the source files in the opm-parser project
#
set( rawdeck_source
RawDeck/StarToken.cpp
RawDeck/RawKeyword.cpp
RawDeck/RawRecord.cpp )
set( unit_source
Units/UnitSystem.cpp
Units/Dimension.cpp)
set( deck_source
Deck/Deck.cpp
Deck/DeckKeyword.cpp
Deck/DeckRecord.cpp
Deck/DeckItem.cpp
Deck/Section.cpp
)
set( parser_source
Parser/ParseContext.cpp
Parser/MessageContainer.cpp
Parser/ParserEnums.cpp
Parser/ParserKeyword.cpp
Parser/Parser.cpp
Parser/ParserRecord.cpp
Parser/ParserItem.cpp
Parser/ParserIntItem.cpp
Parser/ParserDoubleItem.cpp
Parser/ParserStringItem.cpp
)
set( generator_source
Generator/KeywordGenerator.cpp
Generator/KeywordLoader.cpp )
set( build_parser_source
Parser/ParseContext.cpp
Parser/MessageContainer.cpp
Parser/ParserEnums.cpp
Parser/ParserKeyword.cpp
Parser/ParserRecord.cpp
Parser/ParserItem.cpp
Parser/ParserIntItem.cpp
Parser/ParserDoubleItem.cpp
Parser/ParserStringItem.cpp
${generator_source}
)
set (state_source
EclipseState/EclipseState.cpp
EclipseState/EclipseConfig.cpp
EclipseState/Eclipse3DProperties.cpp
EclipseState/Messages.cpp
#
EclipseState/checkDeck.cpp
#
EclipseState/Schedule/OilVaporizationProperties.cpp
EclipseState/Schedule/TimeMap.cpp
EclipseState/Schedule/Schedule.cpp
EclipseState/Schedule/Well.cpp
EclipseState/Schedule/WellProductionProperties.cpp
EclipseState/Schedule/WellInjectionProperties.cpp
EclipseState/Schedule/WellPolymerProperties.cpp
EclipseState/Schedule/WellEconProductionLimits.cpp
EclipseState/Schedule/MSW/Segment.cpp
EclipseState/Schedule/MSW/SegmentSet.cpp
EclipseState/Schedule/MSW/Compsegs.cpp
EclipseState/Schedule/WellSet.cpp
EclipseState/Schedule/Group.cpp
EclipseState/Schedule/Completion.cpp
EclipseState/Schedule/CompletionSet.cpp
EclipseState/Schedule/ScheduleEnums.cpp
EclipseState/Schedule/GroupTreeNode.cpp
EclipseState/Schedule/GroupTree.cpp
EclipseState/Schedule/Tuning.cpp
EclipseState/Schedule/Events.cpp
#
EclipseState/Tables/SimpleTable.cpp
EclipseState/Tables/VFPProdTable.cpp
EclipseState/Tables/VFPInjTable.cpp
EclipseState/Tables/TableManager.cpp
EclipseState/Tables/TableContainer.cpp
EclipseState/Tables/TableColumn.cpp
EclipseState/Tables/ColumnSchema.cpp
EclipseState/Tables/TableSchema.cpp
EclipseState/Tables/TableIndex.cpp
EclipseState/Tables/PvtxTable.cpp
EclipseState/Tables/Tables.cpp
#
EclipseState/Grid/SatfuncPropertyInitializers.cpp
EclipseState/Grid/GridDims.cpp
EclipseState/Grid/GridProperty.cpp
EclipseState/Grid/GridProperties.cpp
EclipseState/Grid/Box.cpp
EclipseState/Grid/BoxManager.cpp
EclipseState/Grid/FaceDir.cpp
EclipseState/Grid/TransMult.cpp
EclipseState/Grid/MULTREGTScanner.cpp
EclipseState/Grid/EclipseGrid.cpp
EclipseState/Grid/FaultFace.cpp
EclipseState/Grid/Fault.cpp
EclipseState/Grid/FaultCollection.cpp
EclipseState/Grid/NNC.cpp
EclipseState/Grid/PinchMode.cpp
#
EclipseState/InitConfig/InitConfig.cpp
EclipseState/InitConfig/Equil.cpp
EclipseState/SimulationConfig/SimulationConfig.cpp
EclipseState/SimulationConfig/ThresholdPressure.cpp
EclipseState/SummaryConfig/SummaryConfig.cpp
EclipseState/IOConfig/RestartConfig.cpp
EclipseState/IOConfig/IOConfig.cpp)
#
set( utility_source
Utility/Functional.cpp
Utility/Stringview.cpp
)
set( HEADER_FILES
RawDeck/RawConsts.hpp
RawDeck/RawKeyword.hpp
RawDeck/RawRecord.hpp
RawDeck/StarToken.hpp
RawDeck/RawEnums.hpp
#
Deck/Deck.hpp
Deck/DeckKeyword.hpp
Deck/DeckRecord.hpp
Deck/DeckItem.hpp
Deck/Section.hpp
#
Parser/ParserEnums.hpp
Parser/ParserKeyword.hpp
Parser/Parser.hpp
Parser/ParserRecord.hpp
Parser/ParserItem.hpp
Parser/ParserIntItem.hpp
Parser/ParserDoubleItem.hpp
Parser/ParserStringItem.hpp
Parser/InputErrorAction.hpp
Parser/ParseContext.hpp
Parser/MessageContainer.hpp
#
Generator/KeywordLoader.hpp
Generator/KeywordGenerator.hpp
#
Units/UnitSystem.hpp
Units/Dimension.hpp
Units/ConversionFactors.hpp
#
EclipseState/EclipseState.hpp
EclipseState/EclipseConfig.hpp
EclipseState/Eclipse3DProperties.hpp
EclipseState/Messages.hpp
#
EclipseState/checkDeck.hpp
#
EclipseState/Schedule/OilVaporizationProperties.hpp
EclipseState/Schedule/TimeMap.hpp
EclipseState/Schedule/Schedule.hpp
EclipseState/Schedule/Well.hpp
EclipseState/Schedule/WellProductionProperties.hpp
EclipseState/Schedule/WellInjectionProperties.hpp
EclipseState/Schedule/WellPolymerProperties.hpp
EclipseState/Schedule/WellEconProductionLimits.hpp
EclipseState/Schedule/MSW/Segment.hpp
EclipseState/Schedule/MSW/SegmentSet.hpp
EclipseState/Schedule/MSW/Compsegs.hpp
EclipseState/Schedule/WellSet.hpp
EclipseState/Schedule/Group.hpp
EclipseState/Schedule/DynamicState.hpp
EclipseState/Schedule/DynamicVector.hpp
EclipseState/Schedule/Completion.hpp
EclipseState/Schedule/CompletionSet.hpp
EclipseState/Schedule/ScheduleEnums.hpp
EclipseState/Schedule/GroupTreeNode.hpp
EclipseState/Schedule/GroupTree.hpp
EclipseState/Schedule/Tuning.hpp
EclipseState/Schedule/Events.hpp
#
EclipseState/Util/RecordVector.hpp
EclipseState/Util/OrderedMap.hpp
EclipseState/Util/Value.hpp
#
EclipseState/Grid/Box.hpp
EclipseState/Grid/BoxManager.hpp
EclipseState/Grid/EclipseGrid.hpp
EclipseState/Grid/FaceDir.hpp
EclipseState/Grid/FaultCollection.hpp
EclipseState/Grid/FaultFace.hpp
EclipseState/Grid/Fault.hpp
EclipseState/Grid/GridDims.hpp
EclipseState/Grid/GridProperties.hpp
EclipseState/Grid/GridProperty.hpp
EclipseState/Grid/MinpvMode.hpp
EclipseState/Grid/MULTREGTScanner.hpp
EclipseState/Grid/NNC.hpp
EclipseState/Grid/PinchMode.hpp
EclipseState/Grid/SatfuncPropertyInitializers.hpp
EclipseState/Grid/TransMult.hpp
#
EclipseState/InitConfig/InitConfig.hpp
EclipseState/InitConfig/Equil.hpp
EclipseState/SimulationConfig/SimulationConfig.hpp
EclipseState/SimulationConfig/ThresholdPressure.hpp
EclipseState/SummaryConfig/SummaryConfig.hpp
EclipseState/IOConfig/RestartConfig.hpp
EclipseState/IOConfig/IOConfig.hpp
#
EclipseState/Tables/Tabdims.hpp
EclipseState/Tables/Eqldims.hpp
EclipseState/Tables/Regdims.hpp
EclipseState/Tables/PlyadsTable.hpp
EclipseState/Tables/PvtoTable.hpp
EclipseState/Tables/RocktabTable.hpp
EclipseState/Tables/PvdoTable.hpp
EclipseState/Tables/PvdgTable.hpp
EclipseState/Tables/PvdsTable.hpp
EclipseState/Tables/SimpleTable.hpp
EclipseState/Tables/PlymaxTable.hpp
EclipseState/Tables/PlyrockTable.hpp
EclipseState/Tables/SwofTable.hpp
EclipseState/Tables/SgwfnTable.hpp
EclipseState/Tables/SwfnTable.hpp
EclipseState/Tables/SgfnTable.hpp
EclipseState/Tables/SsfnTable.hpp
EclipseState/Tables/Sof2Table.hpp
EclipseState/Tables/Sof3Table.hpp
EclipseState/Tables/EnptvdTable.hpp
EclipseState/Tables/PlyviscTable.hpp
EclipseState/Tables/PlydhflfTable.hpp
EclipseState/Tables/PlyshlogTable.hpp
EclipseState/Tables/EnkrvdTable.hpp
EclipseState/Tables/ImkrvdTable.hpp
EclipseState/Tables/SgofTable.hpp
EclipseState/Tables/SlgofTable.hpp
EclipseState/Tables/PvtxTable.hpp
EclipseState/Tables/ImptvdTable.hpp
EclipseState/Tables/RsvdTable.hpp
EclipseState/Tables/RvvdTable.hpp
EclipseState/Tables/RtempvdTable.hpp
EclipseState/Tables/OilvisctTable.hpp
EclipseState/Tables/GasvisctTable.hpp
EclipseState/Tables/WatvisctTable.hpp
EclipseState/Tables/PvtgTable.hpp
EclipseState/Tables/VFPProdTable.hpp
EclipseState/Tables/VFPInjTable.hpp
EclipseState/Tables/TableManager.hpp
EclipseState/Tables/TableContainer.hpp
EclipseState/Tables/SorwmisTable.hpp
EclipseState/Tables/SgcwmisTable.hpp
EclipseState/Tables/MiscTable.hpp
EclipseState/Tables/PmiscTable.hpp
EclipseState/Tables/TlpmixpaTable.hpp
EclipseState/Tables/MsfnTable.hpp
EclipseState/Tables/TableColumn.hpp
EclipseState/Tables/ColumnSchema.hpp
EclipseState/Tables/TableEnums.hpp
EclipseState/Tables/TableSchema.hpp
EclipseState/Tables/TableIndex.hpp
#
Utility/Functional.hpp
Utility/Stringview.hpp)
set(opm_parser_generated_source_files
generated-source/ParserKeywords.cpp
generated-source/ParserKeywords0.cpp
generated-source/ParserKeywords1.cpp
generated-source/ParserKeywords2.cpp
generated-source/ParserKeywords3.cpp
)
# JSON files included directly, not as a separate lib as in original build configuration
set (json_source
opm-parser/opm/json/JsonObject.cpp
opm-parser/opm/json/cjson/cJSON.c
)
# Assemble all the files and add path as needed
set(opm_parser_source_files_short_path
${generated_source}
${state_source}
${rawdeck_source}
${parser_source}
${deck_source}
${unit_source}
${generator_source}
${utility_source}
)
foreach (file ${opm_parser_source_files_short_path} )
list(APPEND opm_parser_source_files_long_path "opm-parser/opm/parser/eclipse/${file}" )
endforeach()
set(opm_parser_source_files
${opm_parser_source_files_long_path}
${json_source}
${opm_parser_generated_source_files}
)

View File

@ -232,6 +232,89 @@ API::API( ) : ParserKeyword("API") {
const std::string API::keywordName = "API";
AQUANCON::AQUANCON( ) : ParserKeyword("AQUANCON") {
setSizeType(SLASH_TERMINATED);
setDescription("");
clearValidSectionNames();
addValidSectionName("GRID");
addValidSectionName("SOLUTION");
clearDeckNames();
addDeckName("AQUANCON");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserIntItem("AQUIFER_ID",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("I1",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("I2",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("J1",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("J2",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("K1",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("K2",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("FACE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("INFLUX_COEFF",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Length*Length");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("INFLUX_MULT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("CONNECT_ADJOINING_ACTIVE_CELL",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string AQUANCON::keywordName = "AQUANCON";
const std::string AQUANCON::AQUIFER_ID::itemName = "AQUIFER_ID";
const std::string AQUANCON::I1::itemName = "I1";
const std::string AQUANCON::I2::itemName = "I2";
const std::string AQUANCON::J1::itemName = "J1";
const std::string AQUANCON::J2::itemName = "J2";
const std::string AQUANCON::K1::itemName = "K1";
const std::string AQUANCON::K2::itemName = "K2";
const std::string AQUANCON::FACE::itemName = "FACE";
const std::string AQUANCON::INFLUX_COEFF::itemName = "INFLUX_COEFF";
const std::string AQUANCON::INFLUX_MULT::itemName = "INFLUX_MULT";
const std::string AQUANCON::CONNECT_ADJOINING_ACTIVE_CELL::itemName = "CONNECT_ADJOINING_ACTIVE_CELL";
AQUCON::AQUCON( ) : ParserKeyword("AQUCON") {
setSizeType(SLASH_TERMINATED);
setDescription("");
@ -396,6 +479,104 @@ const std::string AQUDIMS::MXAAQL::itemName = "MXAAQL";
const int AQUDIMS::MXAAQL::defaultValue = 0;
AQUFETP::AQUFETP( ) : ParserKeyword("AQUFETP") {
setSizeType(OTHER_KEYWORD_IN_DECK);
initSizeKeyword("AQUDIMS","NANAQU");
setDescription("");
clearValidSectionNames();
addValidSectionName("SCHEDULE");
addValidSectionName("SOLUTION");
clearDeckNames();
addDeckName("AQUFETP");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserIntItem("ID",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("DATUM_DEPTH",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Length");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("P0",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Pressure");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("V0",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Length*Length*Length");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("COMPRESSIBILITY",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("1/Pressure");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("PI",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("ReservoirVolume/Pressure*Time");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("WATER_TABLE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("SALINITY",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Salinity");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("TEMP",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string AQUFETP::keywordName = "AQUFETP";
const std::string AQUFETP::ID::itemName = "ID";
const std::string AQUFETP::DATUM_DEPTH::itemName = "DATUM_DEPTH";
const std::string AQUFETP::P0::itemName = "P0";
const std::string AQUFETP::V0::itemName = "V0";
const std::string AQUFETP::COMPRESSIBILITY::itemName = "COMPRESSIBILITY";
const std::string AQUFETP::PI::itemName = "PI";
const std::string AQUFETP::WATER_TABLE::itemName = "WATER_TABLE";
const std::string AQUFETP::SALINITY::itemName = "SALINITY";
const std::string AQUFETP::TEMP::itemName = "TEMP";
AQUIFER_PROBE_ANALYTIC::AQUIFER_PROBE_ANALYTIC( ) : ParserKeyword("AQUIFER_PROBE_ANALYTIC") {
setFixedSize( (size_t) 1);
setDescription("");
clearValidSectionNames();
addValidSectionName("SUMMARY");
clearDeckNames();
setMatchRegex("AA.+");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserIntItem("data",Opm::ALL));
item->setDescription("");
record->addDataItem(item);
}
addDataRecord( record );
}
}
const std::string AQUIFER_PROBE_ANALYTIC::keywordName = "AQUIFER_PROBE_ANALYTIC";
const std::string AQUIFER_PROBE_ANALYTIC::data::itemName = "data";
AQUNUM::AQUNUM( ) : ParserKeyword("AQUNUM") {
setSizeType(SLASH_TERMINATED);
setDescription("");
@ -1462,6 +1643,28 @@ const std::string DATES::TIME::itemName = "TIME";
const std::string DATES::TIME::defaultValue = "00:00:00.000";
DATUM::DATUM( ) : ParserKeyword("DATUM") {
setFixedSize( (size_t) 1);
setDescription("");
clearValidSectionNames();
addValidSectionName("SOLUTION");
clearDeckNames();
addDeckName("DATUM");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserDoubleItem("DEPTH",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Length");
record->addItem(item);
}
addRecord( record );
}
}
const std::string DATUM::keywordName = "DATUM";
const std::string DATUM::DEPTH::itemName = "DEPTH";
DENSITY::DENSITY( ) : ParserKeyword("DENSITY") {
setSizeType(OTHER_KEYWORD_IN_DECK);
initSizeKeyword("TABDIMS","NTPVT");
@ -1686,6 +1889,17 @@ const std::string DRVDT::keywordName = "DRVDT";
const std::string DRVDT::DRVDT_MAX::itemName = "DRVDT_MAX";
DUMPFLUX::DUMPFLUX( ) : ParserKeyword("DUMPFLUX") {
setFixedSize( (size_t) 0);
setDescription("");
clearValidSectionNames();
addValidSectionName("GRID");
clearDeckNames();
addDeckName("DUMPFLUX");
}
const std::string DUMPFLUX::keywordName = "DUMPFLUX";
DX::DX( ) : ParserKeyword("DX") {
setFixedSize( (size_t) 1);
setDescription("");
@ -3701,6 +3915,43 @@ const std::string GEFAC::TRANSFER_EXT_NET::itemName = "TRANSFER_EXT_NET";
const std::string GEFAC::TRANSFER_EXT_NET::defaultValue = "YES";
GRAVITY::GRAVITY( ) : ParserKeyword("GRAVITY") {
setSizeType(OTHER_KEYWORD_IN_DECK);
initSizeKeyword("TABDIMS","NTPVT");
setDescription("");
clearValidSectionNames();
addValidSectionName("PROPS");
clearDeckNames();
addDeckName("GRAVITY");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserDoubleItem("API_GRAVITY",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("1");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("WATER_SP_GRAVITY",Opm::SINGLE,1));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("GAS_SP_GRAVITY",Opm::SINGLE,0.77729999999999999));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string GRAVITY::keywordName = "GRAVITY";
const std::string GRAVITY::API_GRAVITY::itemName = "API_GRAVITY";
const std::string GRAVITY::WATER_SP_GRAVITY::itemName = "WATER_SP_GRAVITY";
const double GRAVITY::WATER_SP_GRAVITY::defaultValue = 1;
const std::string GRAVITY::GAS_SP_GRAVITY::itemName = "GAS_SP_GRAVITY";
const double GRAVITY::GAS_SP_GRAVITY::defaultValue = 0.7773;
GRID::GRID( ) : ParserKeyword("GRID") {
setFixedSize( (size_t) 0);
setDescription("");
@ -4494,6 +4745,65 @@ const std::string ISWU::keywordName = "ISWU";
const std::string ISWU::data::itemName = "data";
JFUNC::JFUNC( ) : ParserKeyword("JFUNC") {
setFixedSize( (size_t) 1);
setDescription("");
clearValidSectionNames();
addValidSectionName("GRID");
clearDeckNames();
addDeckName("JFUNC");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserStringItem("FLAG",Opm::SINGLE,"BOTH"));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("OW_SURFACE_TENSION",Opm::SINGLE,-1));
item->setDescription("");
item->push_backDimension("SurfaceTension");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("GO_SURFACE_TENSION",Opm::SINGLE,-1));
item->setDescription("");
item->push_backDimension("SurfaceTension");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("ALPHA_FACTOR",Opm::SINGLE,0.5));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("BETA_FACTOR",Opm::SINGLE,0.5));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("DIRECTION",Opm::SINGLE,"XY"));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string JFUNC::keywordName = "JFUNC";
const std::string JFUNC::FLAG::itemName = "FLAG";
const std::string JFUNC::FLAG::defaultValue = "BOTH";
const std::string JFUNC::OW_SURFACE_TENSION::itemName = "OW_SURFACE_TENSION";
const double JFUNC::OW_SURFACE_TENSION::defaultValue = -1;
const std::string JFUNC::GO_SURFACE_TENSION::itemName = "GO_SURFACE_TENSION";
const double JFUNC::GO_SURFACE_TENSION::defaultValue = -1;
const std::string JFUNC::ALPHA_FACTOR::itemName = "ALPHA_FACTOR";
const double JFUNC::ALPHA_FACTOR::defaultValue = 0.5;
const std::string JFUNC::BETA_FACTOR::itemName = "BETA_FACTOR";
const double JFUNC::BETA_FACTOR::defaultValue = 0.5;
const std::string JFUNC::DIRECTION::itemName = "DIRECTION";
const std::string JFUNC::DIRECTION::defaultValue = "XY";
MAPAXES::MAPAXES( ) : ParserKeyword("MAPAXES") {
setFixedSize( (size_t) 1);
setDescription("");
@ -5217,6 +5527,41 @@ const std::string MULTPV::keywordName = "MULTPV";
const std::string MULTPV::data::itemName = "data";
MULTREGP::MULTREGP( ) : ParserKeyword("MULTREGP") {
setSizeType(SLASH_TERMINATED);
setDescription("");
clearValidSectionNames();
addValidSectionName("EDIT");
addValidSectionName("GRID");
clearDeckNames();
addDeckName("MULTREGP");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserIntItem("REGION",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MULTIPLIER",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("REGION_TYPE",Opm::SINGLE,"M"));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string MULTREGP::keywordName = "MULTREGP";
const std::string MULTREGP::REGION::itemName = "REGION";
const std::string MULTREGP::MULTIPLIER::itemName = "MULTIPLIER";
const std::string MULTREGP::REGION_TYPE::itemName = "REGION_TYPE";
const std::string MULTREGP::REGION_TYPE::defaultValue = "M";
MULTREGT::MULTREGT( ) : ParserKeyword("MULTREGT") {
setSizeType(SLASH_TERMINATED);
setDescription("");
@ -9079,6 +9424,27 @@ const std::string RPTPROPS::keywordName = "RPTPROPS";
const std::string RPTPROPS::mnemonics::itemName = "mnemonics";
RPTREGS::RPTREGS( ) : ParserKeyword("RPTREGS") {
setFixedSize( (size_t) 1);
setDescription("");
clearValidSectionNames();
addValidSectionName("REGIONS");
clearDeckNames();
addDeckName("RPTREGS");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserStringItem("MNEMONIC_LIST",Opm::ALL));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string RPTREGS::keywordName = "RPTREGS";
const std::string RPTREGS::MNEMONIC_LIST::itemName = "MNEMONIC_LIST";
RPTRST::RPTRST( ) : ParserKeyword("RPTRST") {
setFixedSize( (size_t) 1);
setDescription("");
@ -10767,6 +11133,27 @@ const std::string TLPMIXPA::keywordName = "TLPMIXPA";
const std::string TLPMIXPA::DATA::itemName = "DATA";
TNUM::TNUM( ) : ParserKeyword("TNUM") {
setFixedSize( (size_t) 1);
setDescription("");
clearValidSectionNames();
addValidSectionName("REGIONS");
clearDeckNames();
setMatchRegex("TNUM(F|S).{1,3}");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserIntItem("data",Opm::ALL));
item->setDescription("");
record->addDataItem(item);
}
addDataRecord( record );
}
}
const std::string TNUM::keywordName = "TNUM";
const std::string TNUM::data::itemName = "data";
TOPS::TOPS( ) : ParserKeyword("TOPS") {
setFixedSize( (size_t) 1);
setDescription("");
@ -12421,6 +12808,175 @@ const std::string WCONPROD::E300_ITEM19::itemName = "E300_ITEM19";
const std::string WCONPROD::E300_ITEM20::itemName = "E300_ITEM20";
WDRILTIM::WDRILTIM( ) : ParserKeyword("WDRILTIM") {
setSizeType(SLASH_TERMINATED);
setDescription("");
clearValidSectionNames();
addValidSectionName("SCHEDULE");
clearDeckNames();
addDeckName("WDRILTIM");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserStringItem("WELL",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("DRILL_TIME",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Time");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("WORKOVER_CLOSE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("COMPARTMENT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
addRecord( record );
}
}
const std::string WDRILTIM::keywordName = "WDRILTIM";
const std::string WDRILTIM::WELL::itemName = "WELL";
const std::string WDRILTIM::DRILL_TIME::itemName = "DRILL_TIME";
const std::string WDRILTIM::WORKOVER_CLOSE::itemName = "WORKOVER_CLOSE";
const std::string WDRILTIM::COMPARTMENT::itemName = "COMPARTMENT";
WECON::WECON( ) : ParserKeyword("WECON") {
setSizeType(SLASH_TERMINATED);
setDescription("");
clearValidSectionNames();
addValidSectionName("SCHEDULE");
clearDeckNames();
addDeckName("WECON");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserStringItem("WELL",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MIN_OIL_PRODUCTION",Opm::SINGLE,0));
item->setDescription("");
item->push_backDimension("LiquidSurfaceVolume/Time");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MIN_GAS_PRODUCTION",Opm::SINGLE,0));
item->setDescription("");
item->push_backDimension("GasSurfaceVolume/Time");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MAX_WATER_CUT",Opm::SINGLE,0));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MAX_GAS_OIL_RATIO",Opm::SINGLE,0));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MAX_WATER_GAS_RATIO",Opm::SINGLE,0));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("WORKOVER_RATIO_LIMIT",Opm::SINGLE,"NONE"));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("END_RUN_FLAG",Opm::SINGLE,"NO"));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("FOLLOW_ON_WELL",Opm::SINGLE,"'"));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("LIMITED_QUANTITY",Opm::SINGLE,"RATE"));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("SECOND_MAX_WATER_CUT",Opm::SINGLE,0));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("WORKOVER_SECOND_WATER_CUT_LIMIT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MAX_GAS_LIQUID_RATIO",Opm::SINGLE,0));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MIN_LIQUID_PRODCUTION_RATE",Opm::SINGLE,0));
item->setDescription("");
item->push_backDimension("LiquidSurfaceVolume/Time");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MAX_TEMP",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Temperature");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("MIN_RES_FLUID_RATE",Opm::SINGLE,0));
item->setDescription("");
item->push_backDimension("ReservoirVolume/Time");
record->addItem(item);
}
addRecord( record );
}
}
const std::string WECON::keywordName = "WECON";
const std::string WECON::WELL::itemName = "WELL";
const std::string WECON::MIN_OIL_PRODUCTION::itemName = "MIN_OIL_PRODUCTION";
const double WECON::MIN_OIL_PRODUCTION::defaultValue = 0;
const std::string WECON::MIN_GAS_PRODUCTION::itemName = "MIN_GAS_PRODUCTION";
const double WECON::MIN_GAS_PRODUCTION::defaultValue = 0;
const std::string WECON::MAX_WATER_CUT::itemName = "MAX_WATER_CUT";
const double WECON::MAX_WATER_CUT::defaultValue = 0;
const std::string WECON::MAX_GAS_OIL_RATIO::itemName = "MAX_GAS_OIL_RATIO";
const double WECON::MAX_GAS_OIL_RATIO::defaultValue = 0;
const std::string WECON::MAX_WATER_GAS_RATIO::itemName = "MAX_WATER_GAS_RATIO";
const double WECON::MAX_WATER_GAS_RATIO::defaultValue = 0;
const std::string WECON::WORKOVER_RATIO_LIMIT::itemName = "WORKOVER_RATIO_LIMIT";
const std::string WECON::WORKOVER_RATIO_LIMIT::defaultValue = "NONE";
const std::string WECON::END_RUN_FLAG::itemName = "END_RUN_FLAG";
const std::string WECON::END_RUN_FLAG::defaultValue = "NO";
const std::string WECON::FOLLOW_ON_WELL::itemName = "FOLLOW_ON_WELL";
const std::string WECON::FOLLOW_ON_WELL::defaultValue = "'";
const std::string WECON::LIMITED_QUANTITY::itemName = "LIMITED_QUANTITY";
const std::string WECON::LIMITED_QUANTITY::defaultValue = "RATE";
const std::string WECON::SECOND_MAX_WATER_CUT::itemName = "SECOND_MAX_WATER_CUT";
const double WECON::SECOND_MAX_WATER_CUT::defaultValue = 0;
const std::string WECON::WORKOVER_SECOND_WATER_CUT_LIMIT::itemName = "WORKOVER_SECOND_WATER_CUT_LIMIT";
const std::string WECON::MAX_GAS_LIQUID_RATIO::itemName = "MAX_GAS_LIQUID_RATIO";
const double WECON::MAX_GAS_LIQUID_RATIO::defaultValue = 0;
const std::string WECON::MIN_LIQUID_PRODCUTION_RATE::itemName = "MIN_LIQUID_PRODCUTION_RATE";
const double WECON::MIN_LIQUID_PRODCUTION_RATE::defaultValue = 0;
const std::string WECON::MAX_TEMP::itemName = "MAX_TEMP";
const std::string WECON::MIN_RES_FLUID_RATE::itemName = "MIN_RES_FLUID_RATE";
const double WECON::MIN_RES_FLUID_RATE::defaultValue = 0;
WELLDIMS::WELLDIMS( ) : ParserKeyword("WELLDIMS") {
setFixedSize( (size_t) 1);
setDescription("");
@ -13239,6 +13795,89 @@ const std::string WHISTCTL::BPH_TERMINATE::itemName = "BPH_TERMINATE";
const std::string WHISTCTL::BPH_TERMINATE::defaultValue = "NO";
WLIFT::WLIFT( ) : ParserKeyword("WLIFT") {
setSizeType(SLASH_TERMINATED);
setDescription("");
clearValidSectionNames();
addValidSectionName("SCHEDULE");
clearDeckNames();
addDeckName("WLIFT");
{
std::shared_ptr<ParserRecord> record = std::make_shared<ParserRecord>();
{
ParserItemPtr item(new ParserStringItem("WELL",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("TRIGGER_LIMIT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserStringItem("TRIGGRE_PHASE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserIntItem("NEW_VFP_TABLE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("NEW_ALQ_VALUE",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("NEW_WEFAC",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("WWCT_LIMIT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("NEW_THP_LIMIT",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Pressure");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("WGOR_LIMIT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("ALQ_SHIFT",Opm::SINGLE));
item->setDescription("");
record->addItem(item);
}
{
ParserItemPtr item(new ParserDoubleItem("THP_SHIFT",Opm::SINGLE));
item->setDescription("");
item->push_backDimension("Pressure");
record->addItem(item);
}
addRecord( record );
}
}
const std::string WLIFT::keywordName = "WLIFT";
const std::string WLIFT::WELL::itemName = "WELL";
const std::string WLIFT::TRIGGER_LIMIT::itemName = "TRIGGER_LIMIT";
const std::string WLIFT::TRIGGRE_PHASE::itemName = "TRIGGRE_PHASE";
const std::string WLIFT::NEW_VFP_TABLE::itemName = "NEW_VFP_TABLE";
const std::string WLIFT::NEW_ALQ_VALUE::itemName = "NEW_ALQ_VALUE";
const std::string WLIFT::NEW_WEFAC::itemName = "NEW_WEFAC";
const std::string WLIFT::WWCT_LIMIT::itemName = "WWCT_LIMIT";
const std::string WLIFT::NEW_THP_LIMIT::itemName = "NEW_THP_LIMIT";
const std::string WLIFT::WGOR_LIMIT::itemName = "WGOR_LIMIT";
const std::string WLIFT::ALQ_SHIFT::itemName = "ALQ_SHIFT";
const std::string WLIFT::THP_SHIFT::itemName = "THP_SHIFT";
WPAVE::WPAVE( ) : ParserKeyword("WPAVE") {
setFixedSize( (size_t) 1);
setDescription("");

View File

@ -12,6 +12,7 @@ namespace Opm {
namespace ParserKeywords {
void addDefaultKeywords0(Parser& p);
void addDefaultKeywords0(Parser& p) {
p.addKeyword< ParserKeywords::ACTDIMS >();
p.addKeyword< ParserKeywords::ACTNUM >();
@ -20,8 +21,11 @@ p.addKeyword< ParserKeywords::ADDREG >();
p.addKeyword< ParserKeywords::ADSALNOD >();
p.addKeyword< ParserKeywords::ALL >();
p.addKeyword< ParserKeywords::API >();
p.addKeyword< ParserKeywords::AQUANCON >();
p.addKeyword< ParserKeywords::AQUCON >();
p.addKeyword< ParserKeywords::AQUDIMS >();
p.addKeyword< ParserKeywords::AQUFETP >();
p.addKeyword< ParserKeywords::AQUIFER_PROBE_ANALYTIC >();
p.addKeyword< ParserKeywords::AQUNUM >();
p.addKeyword< ParserKeywords::BLOCK_PROBE >();
p.addKeyword< ParserKeywords::BLOCK_PROBE300 >();
@ -40,6 +44,7 @@ p.addKeyword< ParserKeywords::CREF >();
p.addKeyword< ParserKeywords::CREFS >();
p.addKeyword< ParserKeywords::DATE >();
p.addKeyword< ParserKeywords::DATES >();
p.addKeyword< ParserKeywords::DATUM >();
p.addKeyword< ParserKeywords::DENSITY >();
p.addKeyword< ParserKeywords::DEPTH >();
p.addKeyword< ParserKeywords::DEPTHZ >();
@ -49,6 +54,7 @@ p.addKeyword< ParserKeywords::DREF >();
p.addKeyword< ParserKeywords::DREFS >();
p.addKeyword< ParserKeywords::DRSDT >();
p.addKeyword< ParserKeywords::DRVDT >();
p.addKeyword< ParserKeywords::DUMPFLUX >();
p.addKeyword< ParserKeywords::DX >();
p.addKeyword< ParserKeywords::DXV >();
p.addKeyword< ParserKeywords::DY >();
@ -94,7 +100,5 @@ p.addKeyword< ParserKeywords::GCONPROD >();
p.addKeyword< ParserKeywords::GDORIENT >();
p.addKeyword< ParserKeywords::GECON >();
p.addKeyword< ParserKeywords::GEFAC >();
p.addKeyword< ParserKeywords::GRID >();
p.addKeyword< ParserKeywords::GRIDFILE >();
p.addKeyword< ParserKeywords::GRIDOPTS >();
p.addKeyword< ParserKeywords::GRAVITY >();
}}}

View File

@ -12,7 +12,11 @@ namespace Opm {
namespace ParserKeywords {
void addDefaultKeywords1(Parser& p);
void addDefaultKeywords1(Parser& p) {
p.addKeyword< ParserKeywords::GRID >();
p.addKeyword< ParserKeywords::GRIDFILE >();
p.addKeyword< ParserKeywords::GRIDOPTS >();
p.addKeyword< ParserKeywords::GRIDUNIT >();
p.addKeyword< ParserKeywords::GROUP_PROBE >();
p.addKeyword< ParserKeywords::GRUPNET >();
@ -33,6 +37,7 @@ p.addKeyword< ParserKeywords::ISOWCR >();
p.addKeyword< ParserKeywords::ISWCR >();
p.addKeyword< ParserKeywords::ISWL >();
p.addKeyword< ParserKeywords::ISWU >();
p.addKeyword< ParserKeywords::JFUNC >();
p.addKeyword< ParserKeywords::MAPAXES >();
p.addKeyword< ParserKeywords::MAPUNITS >();
p.addKeyword< ParserKeywords::MAXVALUE >();
@ -53,6 +58,7 @@ p.addKeyword< ParserKeywords::MULTIPLY >();
p.addKeyword< ParserKeywords::MULTIREG >();
p.addKeyword< ParserKeywords::MULTNUM >();
p.addKeyword< ParserKeywords::MULTPV >();
p.addKeyword< ParserKeywords::MULTREGP >();
p.addKeyword< ParserKeywords::MULTREGT >();
p.addKeyword< ParserKeywords::MULT_XYZ >();
p.addKeyword< ParserKeywords::MW >();
@ -95,6 +101,4 @@ p.addKeyword< ParserKeywords::PERMYZ >();
p.addKeyword< ParserKeywords::PERMZ >();
p.addKeyword< ParserKeywords::PERMZX >();
p.addKeyword< ParserKeywords::PIMTDIMS >();
p.addKeyword< ParserKeywords::PIMULTAB >();
p.addKeyword< ParserKeywords::PINCH >();
}}}

View File

@ -12,7 +12,10 @@ namespace Opm {
namespace ParserKeywords {
void addDefaultKeywords2(Parser& p);
void addDefaultKeywords2(Parser& p) {
p.addKeyword< ParserKeywords::PIMULTAB >();
p.addKeyword< ParserKeywords::PINCH >();
p.addKeyword< ParserKeywords::PLMIXPAR >();
p.addKeyword< ParserKeywords::PLYADS >();
p.addKeyword< ParserKeywords::PLYADSS >();
@ -52,6 +55,7 @@ p.addKeyword< ParserKeywords::RPTGRID >();
p.addKeyword< ParserKeywords::RPTONLY >();
p.addKeyword< ParserKeywords::RPTONLYO >();
p.addKeyword< ParserKeywords::RPTPROPS >();
p.addKeyword< ParserKeywords::RPTREGS >();
p.addKeyword< ParserKeywords::RPTRST >();
p.addKeyword< ParserKeywords::RPTRUNSP >();
p.addKeyword< ParserKeywords::RPTSCHED >();

View File

@ -12,6 +12,7 @@ namespace Opm {
namespace ParserKeywords {
void addDefaultKeywords3(Parser& p);
void addDefaultKeywords3(Parser& p) {
p.addKeyword< ParserKeywords::SSOL >();
p.addKeyword< ParserKeywords::START >();
@ -38,6 +39,7 @@ p.addKeyword< ParserKeywords::THPRES >();
p.addKeyword< ParserKeywords::TITLE >();
p.addKeyword< ParserKeywords::TLMIXPAR >();
p.addKeyword< ParserKeywords::TLPMIXPA >();
p.addKeyword< ParserKeywords::TNUM >();
p.addKeyword< ParserKeywords::TOPS >();
p.addKeyword< ParserKeywords::TRACER >();
p.addKeyword< ParserKeywords::TRACERS >();
@ -68,6 +70,8 @@ p.addKeyword< ParserKeywords::WCONINJ >();
p.addKeyword< ParserKeywords::WCONINJE >();
p.addKeyword< ParserKeywords::WCONINJH >();
p.addKeyword< ParserKeywords::WCONPROD >();
p.addKeyword< ParserKeywords::WDRILTIM >();
p.addKeyword< ParserKeywords::WECON >();
p.addKeyword< ParserKeywords::WELLDIMS >();
p.addKeyword< ParserKeywords::WELL_PROBE >();
p.addKeyword< ParserKeywords::WELOPEN >();
@ -76,6 +80,7 @@ p.addKeyword< ParserKeywords::WELSPECS >();
p.addKeyword< ParserKeywords::WELTARG >();
p.addKeyword< ParserKeywords::WGRUPCON >();
p.addKeyword< ParserKeywords::WHISTCTL >();
p.addKeyword< ParserKeywords::WLIFT >();
p.addKeyword< ParserKeywords::WPAVE >();
p.addKeyword< ParserKeywords::WPIMULT >();
p.addKeyword< ParserKeywords::WPITAB >();

View File

@ -13,6 +13,7 @@ namespace ParserKeywords {
#include <opm/parser/eclipse/Parser/ParserKeywords/F.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/G.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/I.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/J.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/M.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/N.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/O.hpp>

View File

@ -156,6 +156,69 @@ namespace ParserKeywords {
class AQUANCON : public ParserKeyword {
public:
AQUANCON();
static const std::string keywordName;
class AQUIFER_ID {
public:
static const std::string itemName;
};
class I1 {
public:
static const std::string itemName;
};
class I2 {
public:
static const std::string itemName;
};
class J1 {
public:
static const std::string itemName;
};
class J2 {
public:
static const std::string itemName;
};
class K1 {
public:
static const std::string itemName;
};
class K2 {
public:
static const std::string itemName;
};
class FACE {
public:
static const std::string itemName;
};
class INFLUX_COEFF {
public:
static const std::string itemName;
};
class INFLUX_MULT {
public:
static const std::string itemName;
};
class CONNECT_ADJOINING_ACTIVE_CELL {
public:
static const std::string itemName;
};
};
class AQUCON : public ParserKeyword {
public:
AQUCON();
@ -285,6 +348,72 @@ namespace ParserKeywords {
class AQUFETP : public ParserKeyword {
public:
AQUFETP();
static const std::string keywordName;
class ID {
public:
static const std::string itemName;
};
class DATUM_DEPTH {
public:
static const std::string itemName;
};
class P0 {
public:
static const std::string itemName;
};
class V0 {
public:
static const std::string itemName;
};
class COMPRESSIBILITY {
public:
static const std::string itemName;
};
class PI {
public:
static const std::string itemName;
};
class WATER_TABLE {
public:
static const std::string itemName;
};
class SALINITY {
public:
static const std::string itemName;
};
class TEMP {
public:
static const std::string itemName;
};
};
class AQUIFER_PROBE_ANALYTIC : public ParserKeyword {
public:
AQUIFER_PROBE_ANALYTIC();
static const std::string keywordName;
class data {
public:
static const std::string itemName;
};
};
class AQUNUM : public ParserKeyword {
public:
AQUNUM();

View File

@ -41,6 +41,19 @@ namespace ParserKeywords {
class DATUM : public ParserKeyword {
public:
DATUM();
static const std::string keywordName;
class DEPTH {
public:
static const std::string itemName;
};
};
class DENSITY : public ParserKeyword {
public:
DENSITY();
@ -182,6 +195,14 @@ namespace ParserKeywords {
class DUMPFLUX : public ParserKeyword {
public:
DUMPFLUX();
static const std::string keywordName;
};
class DX : public ParserKeyword {
public:
DX();

View File

@ -333,6 +333,31 @@ namespace ParserKeywords {
class GRAVITY : public ParserKeyword {
public:
GRAVITY();
static const std::string keywordName;
class API_GRAVITY {
public:
static const std::string itemName;
};
class WATER_SP_GRAVITY {
public:
static const std::string itemName;
static const double defaultValue;
};
class GAS_SP_GRAVITY {
public:
static const std::string itemName;
static const double defaultValue;
};
};
class GRID : public ParserKeyword {
public:
GRID();

View File

@ -0,0 +1,53 @@
#ifndef PARSER_KEYWORDS_J_HPP
#define PARSER_KEYWORDS_J_HPP
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
namespace Opm {
namespace ParserKeywords {
class JFUNC : public ParserKeyword {
public:
JFUNC();
static const std::string keywordName;
class FLAG {
public:
static const std::string itemName;
static const std::string defaultValue;
};
class OW_SURFACE_TENSION {
public:
static const std::string itemName;
static const double defaultValue;
};
class GO_SURFACE_TENSION {
public:
static const std::string itemName;
static const double defaultValue;
};
class ALPHA_FACTOR {
public:
static const std::string itemName;
static const double defaultValue;
};
class BETA_FACTOR {
public:
static const std::string itemName;
static const double defaultValue;
};
class DIRECTION {
public:
static const std::string itemName;
static const std::string defaultValue;
};
};
}
}
#endif

View File

@ -494,6 +494,30 @@ namespace ParserKeywords {
class MULTREGP : public ParserKeyword {
public:
MULTREGP();
static const std::string keywordName;
class REGION {
public:
static const std::string itemName;
};
class MULTIPLIER {
public:
static const std::string itemName;
};
class REGION_TYPE {
public:
static const std::string itemName;
static const std::string defaultValue;
};
};
class MULTREGT : public ParserKeyword {
public:
MULTREGT();

View File

@ -328,6 +328,19 @@ namespace ParserKeywords {
class RPTREGS : public ParserKeyword {
public:
RPTREGS();
static const std::string keywordName;
class MNEMONIC_LIST {
public:
static const std::string itemName;
};
};
class RPTRST : public ParserKeyword {
public:
RPTRST();

View File

@ -298,6 +298,19 @@ namespace ParserKeywords {
class TNUM : public ParserKeyword {
public:
TNUM();
static const std::string keywordName;
class data {
public:
static const std::string itemName;
};
};
class TOPS : public ParserKeyword {
public:
TOPS();

View File

@ -410,6 +410,135 @@ namespace ParserKeywords {
class WDRILTIM : public ParserKeyword {
public:
WDRILTIM();
static const std::string keywordName;
class WELL {
public:
static const std::string itemName;
};
class DRILL_TIME {
public:
static const std::string itemName;
};
class WORKOVER_CLOSE {
public:
static const std::string itemName;
};
class COMPARTMENT {
public:
static const std::string itemName;
};
};
class WECON : public ParserKeyword {
public:
WECON();
static const std::string keywordName;
class WELL {
public:
static const std::string itemName;
};
class MIN_OIL_PRODUCTION {
public:
static const std::string itemName;
static const double defaultValue;
};
class MIN_GAS_PRODUCTION {
public:
static const std::string itemName;
static const double defaultValue;
};
class MAX_WATER_CUT {
public:
static const std::string itemName;
static const double defaultValue;
};
class MAX_GAS_OIL_RATIO {
public:
static const std::string itemName;
static const double defaultValue;
};
class MAX_WATER_GAS_RATIO {
public:
static const std::string itemName;
static const double defaultValue;
};
class WORKOVER_RATIO_LIMIT {
public:
static const std::string itemName;
static const std::string defaultValue;
};
class END_RUN_FLAG {
public:
static const std::string itemName;
static const std::string defaultValue;
};
class FOLLOW_ON_WELL {
public:
static const std::string itemName;
static const std::string defaultValue;
};
class LIMITED_QUANTITY {
public:
static const std::string itemName;
static const std::string defaultValue;
};
class SECOND_MAX_WATER_CUT {
public:
static const std::string itemName;
static const double defaultValue;
};
class WORKOVER_SECOND_WATER_CUT_LIMIT {
public:
static const std::string itemName;
};
class MAX_GAS_LIQUID_RATIO {
public:
static const std::string itemName;
static const double defaultValue;
};
class MIN_LIQUID_PRODCUTION_RATE {
public:
static const std::string itemName;
static const double defaultValue;
};
class MAX_TEMP {
public:
static const std::string itemName;
};
class MIN_RES_FLUID_RATE {
public:
static const std::string itemName;
static const double defaultValue;
};
};
class WELLDIMS : public ParserKeyword {
public:
WELLDIMS();
@ -855,6 +984,69 @@ namespace ParserKeywords {
class WLIFT : public ParserKeyword {
public:
WLIFT();
static const std::string keywordName;
class WELL {
public:
static const std::string itemName;
};
class TRIGGER_LIMIT {
public:
static const std::string itemName;
};
class TRIGGRE_PHASE {
public:
static const std::string itemName;
};
class NEW_VFP_TABLE {
public:
static const std::string itemName;
};
class NEW_ALQ_VALUE {
public:
static const std::string itemName;
};
class NEW_WEFAC {
public:
static const std::string itemName;
};
class WWCT_LIMIT {
public:
static const std::string itemName;
};
class NEW_THP_LIMIT {
public:
static const std::string itemName;
};
class WGOR_LIMIT {
public:
static const std::string itemName;
};
class ALQ_SHIFT {
public:
static const std::string itemName;
};
class THP_SHIFT {
public:
static const std::string itemName;
};
};
class WPAVE : public ParserKeyword {
public:
WPAVE();

View File

@ -146,6 +146,25 @@ BOOST_AUTO_TEST_CASE(TESTAPIKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTAQUANCONKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/A/AQUANCON";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::AQUANCON inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTAQUCONKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/A/AQUCON";
boost::filesystem::path jsonPath( jsonFile );
@ -184,6 +203,44 @@ BOOST_AUTO_TEST_CASE(TESTAQUDIMSKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTAQUFETPKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/A/AQUFETP";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::AQUFETP inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTAQUIFER_PROBE_ANALYTICKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/A/AQUIFER_PROBE_ANALYTIC";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::AQUIFER_PROBE_ANALYTIC inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTAQUNUMKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/A/AQUNUM";
boost::filesystem::path jsonPath( jsonFile );
@ -526,6 +583,25 @@ BOOST_AUTO_TEST_CASE(TESTDATESKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTDATUMKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/D/DATUM";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::DATUM inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTDENSITYKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/D/DENSITY";
boost::filesystem::path jsonPath( jsonFile );
@ -697,6 +773,25 @@ BOOST_AUTO_TEST_CASE(TESTDRVDTKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTDUMPFLUXKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/D/DUMPFLUX";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::DUMPFLUX inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTDXKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/D/DX";
boost::filesystem::path jsonPath( jsonFile );
@ -1552,6 +1647,25 @@ BOOST_AUTO_TEST_CASE(TESTGEFACKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTGRAVITYKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/G/GRAVITY";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::GRAVITY inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTGRIDKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/G/GRID";
boost::filesystem::path jsonPath( jsonFile );
@ -1989,6 +2103,25 @@ BOOST_AUTO_TEST_CASE(TESTISWUKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTJFUNCKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/J/JFUNC";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::JFUNC inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTMAPAXESKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/M/MAPAXES";
boost::filesystem::path jsonPath( jsonFile );
@ -2369,6 +2502,25 @@ BOOST_AUTO_TEST_CASE(TESTMULTPVKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTMULTREGPKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/M/MULTREGP";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::MULTREGP inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTMULTREGTKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/M/MULTREGT";
boost::filesystem::path jsonPath( jsonFile );
@ -3946,6 +4098,25 @@ BOOST_AUTO_TEST_CASE(TESTRPTPROPSKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTRPTREGSKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/R/RPTREGS";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::RPTREGS inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTRPTRSTKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/R/RPTRST";
boost::filesystem::path jsonPath( jsonFile );
@ -5276,6 +5447,25 @@ BOOST_AUTO_TEST_CASE(TESTTLPMIXPAKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTTNUMKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/T/TNUM";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::TNUM inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTTOPSKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/T/TOPS";
boost::filesystem::path jsonPath( jsonFile );
@ -5846,6 +6036,44 @@ BOOST_AUTO_TEST_CASE(TESTWCONPRODKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTWDRILTIMKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/W/WDRILTIM";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::WDRILTIM inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTWECONKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/W/WECON";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::WECON inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTWELLDIMSKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/W/WELLDIMS";
boost::filesystem::path jsonPath( jsonFile );
@ -5998,6 +6226,25 @@ BOOST_AUTO_TEST_CASE(TESTWHISTCTLKeyword) {
}
}
BOOST_AUTO_TEST_CASE(TESTWLIFTKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/W/WLIFT";
boost::filesystem::path jsonPath( jsonFile );
Json::JsonObject jsonConfig( jsonPath );
ParserKeyword jsonKeyword(jsonConfig);
ParserKeywords::WLIFT inlineKeyword;
BOOST_CHECK( jsonKeyword.equal( inlineKeyword ));
if (jsonKeyword.hasDimension()) {
ParserRecordConstPtr parserRecord = jsonKeyword.getRecord(0);
for (size_t i=0; i < parserRecord->size(); i++){
ParserItemConstPtr item = parserRecord->get( i );
for (size_t j=0; j < item->numDimensions(); j++) {
std::string dimString = item->getDimension(j);
BOOST_CHECK_NO_THROW( unitSystem->getNewDimension( dimString ));
}
}
}
}
BOOST_AUTO_TEST_CASE(TESTWPAVEKeyword) {
std::string jsonFile = "E:/Jenkins/jobs/opm-parser-create-keywords/workspace/opm-parser/opm/parser/share/keywords/000_Eclipse100/W/WPAVE";
boost::filesystem::path jsonPath( jsonFile );

View File

@ -5,6 +5,12 @@ enable_language(C)
include(CTest)
include(TestCXXAcceptsFlag)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type specified - defaulting to 'Debug'.")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose build type." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release" "Debug" "RelWithDebInfo" "MinSizeRel")
endif()
# project information is in dune.module. Read this file and set variables.
# we cannot generate dune.module since it is read by dunecontrol before
# the build starts, so it makes sense to keep the data there then.
@ -77,20 +83,19 @@ endif (USE_RUNPATH)
if (MSVC)
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4244 /wd4267")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
set(CMAKE_CXX_FLAGS "/MP ${CMAKE_CXX_FLAGS}")
else()
if (NOT DEFINED CMAKE_CXX_FLAGS)
SET( CMAKE_CXX_FLAGS "-pipe -std=c++0x -pedantic -Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wmissing-declarations -Wcast-qual -Wshadow -Wwrite-strings -Wchar-subscripts -Wredundant-decls")
endif()
SET( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} -O0 -DDEBUG -ggdb3")
SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG -mtune=native")
# The cmake macros are expanded *after* our flags so that options can be
# overriden via -DCMAKE_FLAGS from the command line or ccmake
SET( CMAKE_CXX_FLAGS "-pipe -std=c++0x ${CMAKE_CXX_FLAGS}")
SET( CMAKE_CXX_FLAGS_DEBUG "-pedantic -Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wmissing-declarations -Wcast-qual -Wshadow -Wwrite-strings -Wchar-subscripts -Wredundant-decls ${CMAKE_CXX_FLAGS_DEBUG}")
SET( CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG -ggdb3 ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ")
SET( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -mtune=native ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}")
endif(MSVC)
if (NOT DEFINED CMAKE_C_FLAGS)
SET( CMAKE_C_FLAGS "-pipe -Wall -Wno-unknown-pragmas -std=c99")
endif()
SET( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG} -O0 -DDEBUG -ggdb3")
SET( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE} -O3 -DNDEBUG -mtune=native")
SET( CMAKE_C_FLAGS "-pipe -Wall -Wno-unknown-pragmas -std=c99 ${CMAKE_C_FLAGS}")
SET( CMAKE_C_FLAGS_DEBUG "-O0 -DDEBUG -ggdb3 ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG} ")
SET( CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -mtune=native ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}")
if (BOOST_ROOT AND NOT DEFINED Boost_NO_SYSTEM_PATHS)
@ -111,7 +116,7 @@ add_definitions(-DOPM_PARSER_DECK_API=1)
# Requires BOOST filesystem version 3, thus 1.44 is necessary.
add_definitions(-DBOOST_FILESYSTEM_VERSION=3)
find_package(Boost 1.44.0 COMPONENTS filesystem date_time system unit_test_framework regex REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR})
@ -137,8 +142,6 @@ endif()
include( cmake/Modules/CheckCaseSensitiveFileSystem.cmake )
add_definitions("-DHAVE_CASE_SENSITIVE_FILESYSTEM=${HAVE_CASE_SENSITIVE_FILESYSTEM}")
find_package(opm-common)
include_directories( ${opm-common_INCLUDE_DIRS} )
include( Findopm-data )
find_package(ERT)

View File

@ -0,0 +1,36 @@
version: 1.0.{build}
clone_depth: 1
configuration:
- Debug
- Release
os: Visual Studio 2015
image: Visual Studio 2015
platform:
- x64
environment:
BOOST_ROOT: C:\Libraries\boost_1_59_0\boost
BOOST_INCLUDEDIR: C:\Libraries\boost_1_59_0
BOOST_LIBRARYDIR: C:\Libraries\boost_1_59_0\lib64-msvc-14.0
BOOST_FLAGS: -DBoost_USE_MULTITHREAD=ON -DBUILD_SHARED_LIBS=OFF -DBoost_USE_STATIC_LIBS=TRUE -DBOOST_ALL_DYN_LINK=OFF
BOOST_OPTIONS: -DBOOST_ROOT=%BOOST_ROOT% -DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% -DBOOST_INCLUDEDIR=%BOOST_INCLUDEDIR% %BOOST_FLAGS%
COMMON_ROOT: "C:/Program Files/Project/share/opm/"
ERT_ROOT: "C:/Program Files/ERT"
GEN: "Visual Studio 14 2015 Win64"
build_script:
- git clone https://github.com/OPM/opm-common.git
- git clone https://github.com/Ensembles/ert.git
- cd ert
- cmake C:\projects\opm-parser\ert -G"%GEN%" -DCMAKE_BUILD_TYPE=%configuration% -DERT_BUILD_CXX=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_PYTHON=OFF
- cmake --build . --target install --config %configuration%
- cd ../opm-common
- cmake C:\projects\opm-parser\opm-common -G"%GEN%" %BOOST_OPTIONS% -DCMAKE_BUILD_TYPE=%configuration% -DBUILD_TESTING=OFF
- cmake --build . --config %configuration% --target install
- cd ..
- cmake C:\projects\opm-parser -G"%GEN%" %BOOST_OPTIONS% -DOPM_COMMON_ROOT="%COMMON_ROOT%" -DCMAKE_PREFIX_PATH="%ERT_ROOT%" -DCMAKE_BUILD_TYPE=%configuration%
- cmake --build . --config %configuration%
- ctest -C %configuration% --output-on-failure

View File

@ -5,7 +5,8 @@ Build-Depends: build-essential, debhelper (>= 9), pkg-config, libopm-common-dev,
cmake, libtinyxml-dev, bc, libboost-filesystem-dev, zlib1g-dev,
libert.ecl-dev, git, libtool, doxygen, libboost-date-time-dev,
texlive-latex-extra, texlive-latex-recommended, ghostscript,
libboost-system-dev, libboost-test-dev, libboost-regex-dev
libboost-system-dev, libboost-test-dev, libboost-regex-dev,
python-ert.ecl, python-cwrap
Standards-Version: 3.9.2
Section: libs
Homepage: http://opm-project.org
@ -30,7 +31,17 @@ Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: libopm-parser
Description: OPM parser library
The OPM parser library is the eclipse parser library within OPM
The OPM parser library is the eclipse parser library within OPM
Package: libopm-parser1-bin
Section: science
Pre-Depends: ${misc:Pre-Depends}, multiarch-support
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: libopm-parser-bin
Description: OPM parser library -- applications
The OPM parser library is the eclipse parser library within OPM
Package: libopm-parser1-dbg
Section: debug
@ -39,3 +50,41 @@ Multi-Arch: foreign
Provides: libopm-parser-dbg
Depends: libopm-parser1 (= ${binary:Version}), ${misc:Depends}
Description: OPM parser library -- debug symbols
Package: libopm-cparser1-dev
Section: libdevel
Architecture: any
Multi-Arch: foreign
Depends: libopm-cparser1 (= ${binary:Version})
Provides: libopm-cparser-dev
Description: OPM parser c wrapping library -- development files
The OPM parser library is the eclipse parser library within OPM.
This package contains the development for the c wrapping library
Package: libopm-cparser1
Section: libs
Pre-Depends: ${misc:Pre-Depends}, multiarch-support
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: libopm-cparser
Description: OPM parser c wrapping library
The OPM parser library is the eclipse parser library within OPM. This
package contains a small C wrapper library for libopm-parser.
Package: libopm-cparser1-dbg
Section: debug
Architecture: any
Multi-Arch: foreign
Provides: libopm-cparser-dbg
Depends: libopm-cparser1 (= ${binary:Version}), ${misc:Depends}
Description: OPM parser c wrapping library -- debug symbols
Package: python-opm-parser
Section: python
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, python-ert.ecl,
python-cwrap, libopm-cparser
Description: OPM parser library -- python bindings
The OPM parser library is the eclipse parser library within OPM
of reservoir models. This package contains the python bindings.

View File

@ -0,0 +1 @@
usr/lib/*/libcopm*.so

View File

@ -0,0 +1 @@
usr/lib/*/libcopm*.so.*

View File

@ -0,0 +1 @@
usr/bin/*

View File

@ -1,5 +1,5 @@
usr/include/*
usr/lib/*/lib*.so
usr/lib/*/libopm*.so
usr/lib/dunecontrol/*
usr/share/cmake/*
usr/lib/*/pkgconfig/*

View File

@ -1 +1 @@
usr/lib/*/lib*.so.*
usr/lib/*/libopm*.so.*

View File

@ -0,0 +1 @@
usr/lib/python2.7/*/opm/*

View File

@ -20,10 +20,11 @@ override_dh_auto_build:
# consider using -DUSE_VERSIONED_DIR=ON if backporting
override_dh_auto_configure:
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DENABLE_PYTHON=1
override_dh_installdocs:
dh_installdocs --link-doc=libopm-parser1
override_dh_strip:
dh_strip -plibopm-parser1 --dbg-package=libopm-parser1-dbg
dh_strip -plibopm-cparser1 --dbg-package=libopm-cparser1-dbg

View File

@ -1,21 +1,14 @@
# opm-parser jenkins build scripts:
**build-opm-parser.sh**:
This is a helper script which contains a function for building,
testing and cloning opm-parser and its dependencies.
**build.sh**:
This script will build dependencies, then build opm-parser and execute its tests.
It is intended for post-merge builds of the master branch.
**build-pr.sh**:
This script will build dependencies, then build opm-parser and execute its tests.
It inspects the $ghbPrBuildComment environmental variable to obtain a pull request
to use for for ert and opm-common (defaults to master)
and then builds $sha1 of opm-parser.
It also inspects the $ghbPrBuildComment environmental variable and builds
downstreams if requested. It inspects the $ghbPrBuildComment
environmental variable to obtain a pull request to use for the modules.
It is intended for pre-merge builds of pull requests.
You specify a given pull request to use for opm-common through the trigger.
The trigger line needs to contain ert=&lt;pull request number&gt; and/or
opm-common=&lt;pull request number&gt;.
To specify a given pull request to use for upstreams and downstreams,
trigger line needs to contain &lt;module-name&gt;=&lt;pull request number&gt;.
To build with downstreams the trigger line needs to contain 'with downstreams'.

View File

@ -1,50 +0,0 @@
#!/bin/bash
function build_opm_parser {
# Build ERT
pushd .
mkdir -p $WORKSPACE/deps/ert
cd $WORKSPACE/deps/ert
git init .
git remote add origin https://github.com/Ensembles/ert
git fetch --depth 1 origin $ERT:branch_to_build
test $? -eq 0 || exit 1
git checkout branch_to_build
popd
pushd .
mkdir -p serial/build-ert
cd serial/build-ert
cmake $WORKSPACE/deps/ert/devel -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$WORKSPACE/serial/install
make install
popd
# Build opm-common
pushd .
mkdir -p $WORKSPACE/deps/opm-common
cd $WORKSPACE/deps/opm-common
git init .
git remote add origin https://github.com/OPM/opm-common
git fetch --depth 1 origin $OPM_COMMON_REVISION:branch_to_build
test $? -eq 0 || exit 1
git checkout branch_to_build
popd
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
pushd .
mkdir serial/build-opm-common
cd serial/build-opm-common
build_module "-DCMAKE_INSTALL_PREFIX=$WORKSPACE/serial/install" 0 $WORKSPACE/deps/opm-common
popd
# Setup opm-data
source $WORKSPACE/deps/opm-common/jenkins/setup-opm-data.sh
# Build opm-parser
pushd .
mkdir serial/build-opm-parser
cd serial/build-opm-parser
build_module "-DCMAKE_PREFIX_PATH=$WORKSPACE/serial/install -DCMAKE_INSTALL_PREFIX=$WORKSPACE/serial/install -DOPM_DATA_ROOT=$OPM_DATA_ROOT" 1 $WORKSPACE
test $? -eq 0 || exit 1
popd
}

View File

@ -1,53 +0,0 @@
#!/bin/bash
source `dirname $0`/build-opm-parser.sh
# Upstream revisions
ERT_REVISION=master
OPM_COMMON_REVISION=master
if grep -q "ert=" <<< $ghprbCommentBody
then
ERT_REVISION=pull/`echo $ghprbCommentBody | sed -r 's/.*ert=([0-9]+).*/\1/g'`/merge
fi
if grep -q "opm-common=" <<< $ghprbCommentBody
then
OPM_COMMON_REVISION=pull/`echo $ghprbCommentBody | sed -r 's/.*opm-common=([0-9]+).*/\1/g'`/merge
fi
echo "Building with ert=$ERT_REVISION opm-common=$OPM_COMMON_REVISION opm-parser=$sha1"
build_opm_parser
test $? -eq 0 || exit 1
# If no downstream builds we are done
if ! grep -q "with downstreams" <<< $ghprbCommentBody
then
cp serial/build-opm-parser/testoutput.xml .
exit 0
fi
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
# Downstream revisions
declare -a downstreams
downstreams=(opm-material
opm-output
opm-core
opm-grid
opm-simulators
opm-upscaling
ewoms)
declare -A downstreamRev
downstreamRev[opm-material]=master
downstreamRev[opm-core]=master
downstreamRev[opm-grid]=master
downstreamRev[opm-output]=master
downstreamRev[opm-simulators]=master
downstreamRev[opm-upscaling]=master
downstreamRev[ewoms]=master
build_downstreams opm-parser
test $? -eq 0 || exit 1

View File

@ -1,11 +1,54 @@
#!/bin/bash
source `dirname $0`/build-opm-parser.sh
declare -a upstreams
upstreams=(opm-common
ert)
ERT_REVISION=master
OPM_COMMON_REVISION=master
declare -A upstreamRev
upstreamRev[opm-common]=master
upstreamRev[ert]=master
build_opm_parser
if grep -q "opm-common=" <<< $ghprbCommentBody
then
upstreamRev[opm-common]=pull/`echo $ghprbCommentBody | sed -r 's/.*opm-common=([0-9]+).*/\1/g'`/merge
fi
# Downstream revisions
declare -a downstreams
downstreams=(opm-material
opm-output
opm-core
opm-grid
opm-simulators
opm-upscaling
ewoms)
declare -A downstreamRev
downstreamRev[opm-material]=master
downstreamRev[opm-core]=master
downstreamRev[opm-grid]=master
downstreamRev[opm-output]=master
downstreamRev[opm-simulators]=master
downstreamRev[opm-upscaling]=master
downstreamRev[ewoms]=master
# Clone opm-common
pushd .
mkdir -p $WORKSPACE/deps/opm-common
cd $WORKSPACE/deps/opm-common
git init .
git remote add origin https://github.com/OPM/opm-common
git fetch --depth 1 origin ${upstreamRev[opm-common]}:branch_to_build
test $? -eq 0 || exit 1
git checkout branch_to_build
popd
cp serial/build-opm-parser/testoutput.xml .
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
parseRevisions
printHeader opm-parser
# Setup opm-data
source $WORKSPACE/deps/opm-common/jenkins/setup-opm-data.sh
build_module_full opm-parser

View File

@ -21,12 +21,28 @@
#include <memory>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
void loadDeck( const char * deck_file) {
inline void dumpMessages( const Opm::MessageContainer& messageContainer) {
auto extractMessage = [](const Opm::Message& msg) {
const auto& location = msg.location;
if (location)
return location.filename + ":" + std::to_string( location.lineno ) + " " + msg.message;
else
return msg.message;
};
for(const auto& msg : messageContainer)
std::cout << extractMessage(msg) << std::endl;
}
inline void loadDeck( const char * deck_file) {
Opm::ParseContext parseContext;
Opm::ParserPtr parser(new Opm::Parser());
std::shared_ptr<const Opm::Deck> deck;
@ -35,8 +51,10 @@ void loadDeck( const char * deck_file) {
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
deck = parser->parseFile(deck_file, parseContext);
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
state = std::make_shared<Opm::EclipseState>( deck , parseContext );
state = std::make_shared<Opm::EclipseState>( *deck , parseContext );
std::cout << "complete." << std::endl;
dumpMessages( deck->getMessageContainer() );
}

View File

@ -1,23 +1,23 @@
include_directories(BEFORE ${PROJECT_BINARY_DIR}/generated-source/include)
add_subdirectory(Parser/tests)
#add_subdirectory(Generator/tests)
#add_subdirectory(RawDeck/tests)
#add_subdirectory(Deck/tests)
#add_subdirectory(Units/tests)
#add_subdirectory(EclipseState/tests)
#add_subdirectory(EclipseState/Schedule/tests)
#add_subdirectory(EclipseState/SimulationConfig/tests)
#add_subdirectory(EclipseState/Tables/tests)
#add_subdirectory(EclipseState/Grid/tests)
#add_subdirectory(EclipseState/Util/tests)
#add_subdirectory(EclipseState/IOConfig/tests)
#add_subdirectory(EclipseState/InitConfig/tests)
#add_subdirectory(EclipseState/SummaryConfig/tests)
#add_subdirectory(Utility/tests)
add_subdirectory(Generator/tests)
add_subdirectory(RawDeck/tests)
add_subdirectory(Deck/tests)
add_subdirectory(Units/tests)
add_subdirectory(EclipseState/tests)
add_subdirectory(EclipseState/Schedule/tests)
add_subdirectory(EclipseState/SimulationConfig/tests)
add_subdirectory(EclipseState/Tables/tests)
add_subdirectory(EclipseState/Grid/tests)
add_subdirectory(EclipseState/Util/tests)
add_subdirectory(EclipseState/IOConfig/tests)
add_subdirectory(EclipseState/InitConfig/tests)
add_subdirectory(EclipseState/SummaryConfig/tests)
add_subdirectory(Utility/tests)
#add_subdirectory(Applications)
#add_subdirectory(IntegrationTests)
add_subdirectory(Applications)
add_subdirectory(IntegrationTests)
set( rawdeck_source
RawDeck/StarToken.cpp
@ -34,8 +34,6 @@ Deck/DeckKeyword.cpp
Deck/DeckRecord.cpp
Deck/DeckItem.cpp
Deck/Section.cpp
Deck/SCHEDULESection.cpp
Deck/DeckTimeStep.cpp
)
set( parser_source
@ -83,6 +81,7 @@ EclipseState/Schedule/Well.cpp
EclipseState/Schedule/WellProductionProperties.cpp
EclipseState/Schedule/WellInjectionProperties.cpp
EclipseState/Schedule/WellPolymerProperties.cpp
EclipseState/Schedule/WellEconProductionLimits.cpp
EclipseState/Schedule/MSW/Segment.cpp
EclipseState/Schedule/MSW/SegmentSet.cpp
EclipseState/Schedule/MSW/Compsegs.cpp
@ -109,6 +108,7 @@ EclipseState/Tables/PvtxTable.cpp
EclipseState/Tables/Tables.cpp
#
EclipseState/Grid/SatfuncPropertyInitializers.cpp
EclipseState/Grid/GridDims.cpp
EclipseState/Grid/GridProperty.cpp
EclipseState/Grid/GridProperties.cpp
EclipseState/Grid/Box.cpp
@ -128,6 +128,7 @@ EclipseState/InitConfig/Equil.cpp
EclipseState/SimulationConfig/SimulationConfig.cpp
EclipseState/SimulationConfig/ThresholdPressure.cpp
EclipseState/SummaryConfig/SummaryConfig.cpp
EclipseState/IOConfig/RestartConfig.cpp
EclipseState/IOConfig/IOConfig.cpp)
#
@ -148,8 +149,6 @@ Deck/DeckKeyword.hpp
Deck/DeckRecord.hpp
Deck/DeckItem.hpp
Deck/Section.hpp
Deck/SCHEDULESection.hpp
Deck/DeckTimeStep.hpp
#
Parser/ParserEnums.hpp
Parser/ParserKeyword.hpp
@ -184,6 +183,7 @@ EclipseState/Schedule/Well.hpp
EclipseState/Schedule/WellProductionProperties.hpp
EclipseState/Schedule/WellInjectionProperties.hpp
EclipseState/Schedule/WellPolymerProperties.hpp
EclipseState/Schedule/WellEconProductionLimits.hpp
EclipseState/Schedule/MSW/Segment.hpp
EclipseState/Schedule/MSW/SegmentSet.hpp
EclipseState/Schedule/MSW/Compsegs.hpp
@ -203,27 +203,29 @@ EclipseState/Util/RecordVector.hpp
EclipseState/Util/OrderedMap.hpp
EclipseState/Util/Value.hpp
#
EclipseState/Grid/EclipseGrid.hpp
EclipseState/Grid/GridProperty.hpp
EclipseState/Grid/GridProperties.hpp
EclipseState/Grid/SatfuncPropertyInitializers.hpp
EclipseState/Grid/Box.hpp
EclipseState/Grid/BoxManager.hpp
EclipseState/Grid/EclipseGrid.hpp
EclipseState/Grid/FaceDir.hpp
EclipseState/Grid/MinpvMode.hpp
EclipseState/Grid/PinchMode.hpp
EclipseState/Grid/MULTREGTScanner.hpp
EclipseState/Grid/TransMult.hpp
EclipseState/Grid/FaultCollection.hpp
EclipseState/Grid/FaultFace.hpp
EclipseState/Grid/Fault.hpp
EclipseState/Grid/FaultCollection.hpp
EclipseState/Grid/GridDims.hpp
EclipseState/Grid/GridProperties.hpp
EclipseState/Grid/GridProperty.hpp
EclipseState/Grid/MinpvMode.hpp
EclipseState/Grid/MULTREGTScanner.hpp
EclipseState/Grid/NNC.hpp
EclipseState/Grid/PinchMode.hpp
EclipseState/Grid/SatfuncPropertyInitializers.hpp
EclipseState/Grid/TransMult.hpp
#
EclipseState/InitConfig/InitConfig.hpp
EclipseState/InitConfig/Equil.hpp
EclipseState/SimulationConfig/SimulationConfig.hpp
EclipseState/SimulationConfig/ThresholdPressure.hpp
EclipseState/SummaryConfig/SummaryConfig.hpp
EclipseState/IOConfig/RestartConfig.hpp
EclipseState/IOConfig/IOConfig.hpp
#
EclipseState/Tables/Tabdims.hpp

View File

@ -120,11 +120,7 @@ namespace Opm {
DeckView( limits.first, limits.second )
{}
Deck::Deck() :
Deck( std::vector< DeckKeyword >() )
{
m_dataFile = "";
}
Deck::Deck() : Deck( std::vector< DeckKeyword >() ) {}
Deck::Deck( std::vector< DeckKeyword >&& x ) :
DeckView( x.begin(), x.end() ),
@ -132,13 +128,21 @@ namespace Opm {
m_dataFile("")
{}
Deck::Deck( std::initializer_list< DeckKeyword > ilist ) :
Deck( std::vector< DeckKeyword >( ilist ) )
{}
Deck::Deck( std::initializer_list< std::string > ilist ) :
Deck( std::vector< DeckKeyword >( ilist.begin(), ilist.end() ) )
{}
void Deck::addKeyword( DeckKeyword&& keyword ) {
this->keywordList.push_back( std::move( keyword ) );
auto first = this->keywordList.begin();
auto last = this->keywordList.end();
auto fst = this->keywordList.begin();
auto lst = this->keywordList.end();
this->add( &this->keywordList.back(), first, last );
this->add( &this->keywordList.back(), fst, lst );
}
void Deck::addKeyword( const DeckKeyword& keyword ) {

View File

@ -120,6 +120,8 @@ namespace Opm {
using iterator = std::vector< DeckKeyword >::iterator;
Deck();
Deck( std::initializer_list< DeckKeyword > );
Deck( std::initializer_list< std::string > );
void addKeyword( DeckKeyword&& keyword );
void addKeyword( const DeckKeyword& keyword );

View File

@ -111,12 +111,12 @@ namespace Opm {
template< typename T >
DeckTypeItem< T >::DeckTypeItem( const std::string& name, size_t size ) :
DeckTypeItem< T >::DeckTypeItem( const std::string& nm, size_t sz ) :
DeckItemBase( type_to_tag< T >() ),
item_name( name )
item_name( nm )
{
this->dataPointDefaulted.reserve( size );
this->data.reserve( size );
this->dataPointDefaulted.reserve( sz );
this->data.reserve( sz );
}
template< typename T >
@ -212,21 +212,21 @@ namespace Opm {
}
const std::vector< double >& DeckItemT< double >::assertSIData() const {
const auto dim_size = dimensions.size();
if( dim_size <= 0 )
throw std::invalid_argument("No dimension has been set for item:" + this->name() + " can not ask for SI data");
// we already converted this item to SI?
if( this->SIdata.size() > 0 ) return this->SIdata;
if( !this->SIdata.empty() ) return this->SIdata;
if( this->dimensions.empty() )
throw std::invalid_argument("No dimension has been set for item:" + this->name() + " can not ask for SI data");
/*
* This is an unobservable state change - SIData is lazily converted to
* SI units, so externally the object still behaves as const
*/
const auto size = this->size();
this->SIdata.resize( size );
const auto dim_size = dimensions.size();
const auto sz = this->size();
this->SIdata.resize( sz );
for( size_t index = 0; index < size; index++ ) {
for( size_t index = 0; index < sz; index++ ) {
const auto dimIndex = index % dim_size;
this->SIdata[ index ] = this->dimensions[ dimIndex ]
->convertRawToSi( this->get( index ) );

View File

@ -18,6 +18,7 @@
*/
#include <unordered_set>
#include <stdexcept>
#include <string>
#include <algorithm>
@ -29,8 +30,26 @@
namespace Opm {
DeckRecord::DeckRecord( size_t size ) {
this->m_items.reserve( size );
DeckRecord::DeckRecord( std::vector< DeckItem >&& items ) :
m_items( std::move( items ) ) {
std::unordered_set< std::string > names;
for( const auto& item : this->m_items )
names.insert( item.name() );
if( names.size() == this->m_items.size() )
return;
names.clear();
std::string msg = "Duplicate item names in DeckRecord:";
for( const auto& item : this->m_items ) {
if( names.count( item.name() ) != 0 )
msg += std::string( " " ) += item.name();
names.insert( item.name() );
}
throw std::invalid_argument( msg );
}
size_t DeckRecord::size() const {

View File

@ -33,7 +33,7 @@ namespace Opm {
typedef std::vector< DeckItem >::const_iterator const_iterator;
DeckRecord() = default;
DeckRecord( size_t );
DeckRecord( std::vector< DeckItem >&& );
size_t size() const;
void addItem( DeckItem&& deckItem );

View File

@ -1,30 +0,0 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/parser/eclipse/Deck/DeckTimeStep.hpp>
namespace Opm {
DeckTimeStep::DeckTimeStep() {
}
}

View File

@ -1,71 +0,0 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckTimeStep.hpp>
#include <opm/parser/eclipse/Deck/SCHEDULESection.hpp>
namespace Opm {
SCHEDULESection::SCHEDULESection( const Deck& deck ) :
Section(deck, "SCHEDULE"), unit_system( deck.getActiveUnitSystem() )
{
populateDeckTimeSteps();
}
DeckTimeStepConstPtr SCHEDULESection::getDeckTimeStep(size_t timestep) const {
if (timestep < m_decktimesteps.size()) {
return m_decktimesteps[timestep];
} else {
throw std::out_of_range("No DeckTimeStep in ScheduleSection for timestep " + std::to_string(timestep));
}
}
void SCHEDULESection::populateDeckTimeSteps() {
DeckTimeStepPtr currentTimeStep = std::make_shared<DeckTimeStep>();
for( const auto& keyword : *this ) {
if (keyword.name() == "TSTEP") {
const auto& items = keyword.getDataRecord().getDataItem();
for (size_t item_iter = 0; item_iter < items.size(); ++item_iter) {
m_decktimesteps.push_back(currentTimeStep);
currentTimeStep = std::make_shared<DeckTimeStep>();
}
} else if (keyword.name() == "DATES") {
for (auto record_iter = keyword.begin(); record_iter != keyword.end(); ++record_iter ) {
m_decktimesteps.push_back(currentTimeStep);
currentTimeStep = std::make_shared<DeckTimeStep>();
}
} else {
currentTimeStep->addKeyword(keyword);
}
}
//push last step
m_decktimesteps.push_back(currentTimeStep);
}
const UnitSystem& SCHEDULESection::getActiveUnitSystem() const {
return this->unit_system;
}
}

View File

@ -1,49 +0,0 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCHEDULESECTION_HPP
#define SCHEDULESECTION_HPP
#include <memory>
#include <opm/parser/eclipse/Deck/Section.hpp>
namespace Opm {
class DeckTimeStep;
class SCHEDULESection : public Section {
public:
SCHEDULESection( const Deck& deck);
std::shared_ptr< const DeckTimeStep > getDeckTimeStep(size_t timestep) const;
const UnitSystem& getActiveUnitSystem() const;
private:
void populateDeckTimeSteps();
std::vector< std::shared_ptr< DeckTimeStep > > m_decktimesteps;
const UnitSystem& unit_system;
};
}
#endif // SCHEDULESECTION_HPP

View File

@ -63,13 +63,18 @@ namespace Opm {
Section::Section( const Deck& deck, const std::string& section )
: DeckView( find_section( deck, section ) ),
section_name( section )
section_name( section ),
units( deck.getActiveUnitSystem() )
{}
const std::string& Section::name() const {
return this->section_name;
}
const UnitSystem& Section::unitSystem() const {
return this->units;
}
bool Section::hasRUNSPEC(const Deck& deck) { return deck.hasKeyword( "RUNSPEC" ); }
bool Section::hasGRID(const Deck& deck) { return deck.hasKeyword( "GRID" ); }
bool Section::hasEDIT(const Deck& deck) { return deck.hasKeyword( "EDIT" ); }

View File

@ -35,6 +35,7 @@ class Section : public DeckView {
Section( const Deck& deck, const std::string& startKeyword );
const std::string& name() const;
const UnitSystem& unitSystem() const;
static bool hasRUNSPEC( const Deck& );
static bool hasGRID( const Deck& );
@ -53,43 +54,57 @@ class Section : public DeckView {
private:
std::string section_name;
const UnitSystem& units;
};
class RUNSPECSection : public Section {
public:
using Section::const_iterator;
RUNSPECSection(const Deck& deck) : Section(deck, "RUNSPEC") {}
};
class GRIDSection : public Section {
public:
using Section::const_iterator;
GRIDSection(const Deck& deck) : Section(deck, "GRID") {}
};
class EDITSection : public Section {
public:
using Section::const_iterator;
EDITSection(const Deck& deck) : Section(deck, "EDIT") {}
};
class PROPSSection : public Section {
public:
using Section::const_iterator;
PROPSSection(const Deck& deck) : Section(deck, "PROPS") {}
};
class REGIONSSection : public Section {
public:
using Section::const_iterator;
REGIONSSection(const Deck& deck) : Section(deck, "REGIONS") {}
};
class SOLUTIONSection : public Section {
public:
using Section::const_iterator;
SOLUTIONSection(const Deck& deck) : Section(deck, "SOLUTION") {}
};
class SUMMARYSection : public Section {
public:
using Section::const_iterator;
SUMMARYSection(const Deck& deck) : Section(deck, "SUMMARY") {}
};
class SCHEDULESection : public Section {
public:
using Section::const_iterator;
SCHEDULESection(const Deck& deck) : Section(deck, "SCHEDULE") {}
};
}
#endif // SECTION_HPP

View File

@ -1,6 +1,5 @@
foreach(tapp DeckRecordTests DeckIntItemTests DeckDoubleItemTests
DeckStringItemTests DeckTests DeckKeywordTests SectionTests
DeckTimeStepTests)
DeckStringItemTests DeckTests DeckKeywordTests SectionTests)
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()

View File

@ -20,9 +20,7 @@
#define BOOST_TEST_MODULE DeckItemTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <stdexcept>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>

View File

@ -19,9 +19,7 @@
#define BOOST_TEST_MODULE DeckItemTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <stdexcept>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>

View File

@ -22,9 +22,7 @@
#define BOOST_TEST_MODULE DeckKeywordTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>

View File

@ -71,6 +71,8 @@ BOOST_AUTO_TEST_CASE(addItem_differentItemsSameName_throws) {
DeckRecord deckRecord;
deckRecord.addItem( mkIntItem( "TEST" ) );
BOOST_CHECK_THROW( deckRecord.addItem( mkIntItem( "TEST" ) ), std::invalid_argument );
std::vector< DeckItem > items = { mkIntItem( "TEST" ), mkIntItem( "TEST" ) };
BOOST_CHECK_THROW( DeckRecord( std::move( items ) ), std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(get_byIndex_returnsItem) {

View File

@ -21,9 +21,7 @@
#define BOOST_TEST_MODULE DeckStringItemTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>

View File

@ -22,9 +22,7 @@
#define BOOST_TEST_MODULE DeckTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -37,6 +35,18 @@ BOOST_AUTO_TEST_CASE(Initialize) {
BOOST_REQUIRE_NO_THROW(DeckConstPtr deckConstPtr(new Deck()));
}
BOOST_AUTO_TEST_CASE(Initializer_lists) {
DeckKeyword foo( "foo" );
DeckKeyword bar( "bar" );
std::string foostr( "foo" );
std::string barstr( "bar" );
BOOST_REQUIRE_NO_THROW( Deck( { foo, bar } ) );
BOOST_REQUIRE_NO_THROW( Deck( { foostr, barstr } ) );
BOOST_REQUIRE_NO_THROW( Deck( { "Kappa", "Phi" } ) );
}
BOOST_AUTO_TEST_CASE(hasKeyword_empty_returnFalse) {
Deck deck;
BOOST_CHECK_EQUAL(false, deck.hasKeyword("Bjarne"));

View File

@ -1,136 +0,0 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE DeckTimeStepTests
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <opm/parser/eclipse/Deck/DeckTimeStep.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Deck/SCHEDULESection.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE(testDeckTimeStepInitialize) {
BOOST_CHECK_NO_THROW(DeckTimeStep deckTimeStep);
}
BOOST_AUTO_TEST_CASE(testDeckTimeStepTSTEP) {
Opm::Parser parser;
std::string input =
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1,2\n"
" 10 OKT 2008 / \n"
" 11 OKT 2008 / \n"
"/\n"
"WELSPECS\n"
" 'OP_1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
"/\n"
"COMPDAT\n"
" 'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
" 'OP_1' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n"
" 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
"/\n"
"DATES -- 3,4\n"
" 20 JAN 2010 / \n"
" 21 JAN 2010 / \n"
"/\n";
ParseContext parseContext;
DeckPtr deck = parser.parseString(input, parseContext);
SCHEDULESection scheduleSection = SCHEDULESection(*deck);
DeckTimeStepConstPtr step1 = scheduleSection.getDeckTimeStep(0);
DeckTimeStepConstPtr step2 = scheduleSection.getDeckTimeStep(1);
DeckTimeStepConstPtr step3 = scheduleSection.getDeckTimeStep(2);
DeckTimeStepConstPtr step4 = scheduleSection.getDeckTimeStep(3);
BOOST_CHECK_EQUAL(step1->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step2->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step3->hasKeyword("WELSPECS"), true);
BOOST_CHECK_EQUAL(step4->hasKeyword("WELSPECS"), false);
}
BOOST_AUTO_TEST_CASE(testDeckTimeStepDATES) {
Opm::Parser parser;
std::string input =
"RUNSPEC\n"
"INIT\n"
"UNIFOUT\n"
"OIL\n"
"GAS\n"
"WATER\n"
"METRIC\n"
"DIMENS\n"
"3 3 3/\n"
"GRID\n"
"DXV\n"
"1.0 2.0 3.0 /\n"
"DYV\n"
"4.0 5.0 6.0 /\n"
"DZV\n"
"7.0 8.0 9.0 /\n"
"TOPS\n"
"9*100 /\n"
"PROPS\n"
"PORO\n"
"27*0.3 /\n"
"PERMX\n"
"27*1 /\n"
"SOLUTION\n"
"RPTRST\n"
"BASIC=2\n"
"/\n"
"SCHEDULE\n"
"TSTEP\n"
"1.0 2.0 3.0 4.0 /\n"
"WELSPECS\n"
"'INJ' 'G' 1 1 2000 'GAS' /\n"
"'PROD' 'G' 3 3 1000 'OIL' /\n"
"/\n";
ParseContext parseContext;
DeckPtr deck = parser.parseString(input, parseContext);
SCHEDULESection scheduleSection = SCHEDULESection(*deck);
DeckTimeStepConstPtr step1 = scheduleSection.getDeckTimeStep(0);
DeckTimeStepConstPtr step2 = scheduleSection.getDeckTimeStep(1);
DeckTimeStepConstPtr step3 = scheduleSection.getDeckTimeStep(2);
DeckTimeStepConstPtr step4 = scheduleSection.getDeckTimeStep(3);
DeckTimeStepConstPtr step5 = scheduleSection.getDeckTimeStep(4);
BOOST_CHECK_EQUAL(step1->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step2->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step3->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step4->hasKeyword("WELSPECS"), false);
BOOST_CHECK_EQUAL(step5->hasKeyword("WELSPECS"), true);
}

View File

@ -28,7 +28,6 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Deck/SCHEDULESection.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>

View File

@ -1,5 +1,5 @@
/*
Copyright 2013 Statoil ASA.
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
@ -19,26 +19,23 @@
#include <algorithm>
#include <functional>
#include <set>
#include <boost/algorithm/string/join.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Utility/String.hpp>
namespace Opm {
namespace GridPropertyPostProcessor {
namespace {
void distTopLayer( std::vector<double>& values,
const EclipseGrid* eclipseGrid )
@ -52,9 +49,26 @@ namespace Opm {
}
}
/// initPORV uses doubleGridProperties: PORV, PORO, NTG, MULTPV
// this funcion applies a single pore volume multiplier (i.e., it deals with a single
// record of the MULTREGP keyword)
void applyPorosityRegionMultiplier_(std::vector<double>& porev,
const std::vector<int>& regionId,
int multRegionId,
double multValue)
{
for (unsigned i = 0; i < porev.size(); ++i) {
if (regionId[i] == multRegionId)
porev[i] *= multValue;
}
}
/// this function initializes the pore volume of all cells. it uses the raw keyword
/// 'MULTREGP', the integer grid properties 'FLUXNUM', 'MULTNUM' and 'OPERNUM' as
/// well as the double grid properties 'PORV', 'PORO', 'NTG' and 'MULTPV'
void initPORV( std::vector<double>& values,
const Deck* deck,
const EclipseGrid* eclipseGrid,
const GridProperties<int>* intGridProperties,
const GridProperties<double>* doubleGridProperties)
{
const auto iter = std::find_if( values.begin(), values.end(), []( double value ) { return std::isnan(value); });
@ -83,6 +97,54 @@ namespace Opm {
for (size_t globalIndex = 0; globalIndex < multpvData.size(); globalIndex++)
values[globalIndex] *= multpvData[globalIndex];
}
// deal with the region multiplier for porosity
if (deck->hasKeyword("MULTREGP")) {
const DeckKeyword& multregpKeyword = deck->getKeyword("MULTREGP");
for (unsigned recordIdx = 0; recordIdx < multregpKeyword.size(); ++recordIdx) {
const DeckRecord& multregpRecord = multregpKeyword.getRecord(recordIdx);
int regionId = multregpRecord.getItem("REGION").template get<int>(0);
std::string regionType = multregpRecord.getItem("REGION_TYPE").template get<std::string>(0);
double multValue = multregpRecord.getItem("MULTIPLIER").template get<double>(0);
uppercase(regionType, regionType);
// deal with the "convenience" feature of ECL: if the region index is
// zero or negative, the record is ignored.
if (regionId <= 0)
continue;
// implement a (documented) ECL bug: the region index must be unique
// (i.e., it is impossible to specify multipliers for different
// region types with the same index). Also, only the last occurence
// of each region counts.
unsigned record2Idx = recordIdx + 1;
for (; record2Idx < multregpKeyword.size(); ++record2Idx) {
const DeckRecord& multregpRecord2 = multregpKeyword.getRecord(record2Idx);
int region2Idx = multregpRecord2.getItem("REGION").template get<int>(0);
if (region2Idx == regionId)
break;
}
if (record2Idx < multregpKeyword.size())
// the region was specified twice
continue;
if (regionType == "M") {
const GridProperty<int>& multnumProp = intGridProperties->getKeyword("MULTNUM");
applyPorosityRegionMultiplier_(values, multnumProp.getData(), regionId, multValue);
}
else if (regionType == "F") {
const GridProperty<int>& fluxnumProp = intGridProperties->getKeyword("FLUXNUM");
applyPorosityRegionMultiplier_(values, fluxnumProp.getData(), regionId, multValue);
}
else if (regionType == "O") {
const GridProperty<int>& opernumProp = intGridProperties->getKeyword("OPERNUM");
applyPorosityRegionMultiplier_(values, opernumProp.getData(), regionId, multValue);
}
else
throw std::logic_error("Unknown or illegal region type for MULTREGP keyword: '"+regionType+"'");
}
}
}
@ -187,7 +249,7 @@ namespace Opm {
const auto tempLookup = std::bind( temperature_lookup, _1, tableManager, eclipseGrid, intGridProperties );
const auto distributeTopLayer = std::bind( &GridPropertyPostProcessor::distTopLayer, _1, eclipseGrid );
const auto distributeTopLayer = std::bind( &distTopLayer, _1, eclipseGrid );
std::vector< GridProperties< double >::SupportedKeywordInfo > supportedDoubleKeywords;
@ -396,19 +458,21 @@ namespace Opm {
{
auto initPORV = std::bind(&GridPropertyPostProcessor::initPORV,
auto initPORVProcessor = std::bind(&initPORV,
std::placeholders::_1,
&deck,
&eclipseGrid,
&m_intGridProperties,
&m_doubleGridProperties);
m_doubleGridProperties.postAddKeyword( "PORV",
std::numeric_limits<double>::quiet_NaN(),
initPORV,
initPORVProcessor,
"Volume" );
}
{
auto actnumPP = std::bind(&GridPropertyPostProcessor::ACTNUMPostProcessor,
auto actnumPP = std::bind(&ACTNUMPostProcessor,
std::placeholders::_1,
&m_doubleGridProperties);
@ -422,34 +486,28 @@ namespace Opm {
}
bool Eclipse3DProperties::supportsGridProperty(const std::string& keyword) const {
auto kw = uppercase(keyword);
return m_doubleGridProperties.supportsKeyword( kw ) || m_intGridProperties.supportsKeyword( kw );
return m_doubleGridProperties.supportsKeyword( keyword ) || m_intGridProperties.supportsKeyword( keyword );
}
bool Eclipse3DProperties::hasDeckIntGridProperty(const std::string& keyword) const {
auto kw = uppercase(keyword);
if (!m_intGridProperties.supportsKeyword(kw))
return false;
//throw std::logic_error("Integer grid property " + kw + " is unsupported!");
if (!m_intGridProperties.supportsKeyword( keyword ))
throw std::logic_error("Integer grid property " + keyword + " is unsupported!");
return m_intGridProperties.hasKeyword( kw );
return m_intGridProperties.hasKeyword( keyword );
}
bool Eclipse3DProperties::hasDeckDoubleGridProperty(const std::string& keyword) const {
auto kw = uppercase(keyword);
if (!m_doubleGridProperties.supportsKeyword(kw))
return false;
//throw std::logic_error("Double grid property " + kw + " is unsupported!");
if (!m_doubleGridProperties.supportsKeyword( keyword ))
throw std::logic_error("Double grid property " + keyword + " is unsupported!");
return m_doubleGridProperties.hasKeyword( kw );
return m_doubleGridProperties.hasKeyword( keyword );
}
const GridProperty<int>& Eclipse3DProperties::getIntGridProperty( const std::string& keyword ) const {
auto kw = uppercase(keyword);
auto& gridProperty = const_cast< Eclipse3DProperties* >( this )->m_intGridProperties.getKeyword( kw );
auto& gridProperty = const_cast< Eclipse3DProperties* >( this )->m_intGridProperties.getKeyword( keyword );
gridProperty.runPostProcessor();
return gridProperty;
}
@ -458,12 +516,20 @@ namespace Opm {
/// gets property from doubleGridProperty --- and calls the runPostProcessor
const GridProperty<double>& Eclipse3DProperties::getDoubleGridProperty( const std::string& keyword ) const {
auto kw = uppercase(keyword);
auto& gridProperty = const_cast< Eclipse3DProperties* >( this )->m_doubleGridProperties.getKeyword( kw );
auto& gridProperty = const_cast< Eclipse3DProperties* >( this )->m_doubleGridProperties.getKeyword( keyword );
gridProperty.runPostProcessor();
return gridProperty;
}
const GridProperties<int>& Eclipse3DProperties::getIntProperties() const {
return m_intGridProperties;
}
const GridProperties<double>& Eclipse3DProperties::getDoubleProperties() const {
return m_doubleGridProperties;
}
std::string Eclipse3DProperties::getDefaultRegionKeyword() const {
return m_defaultRegion;
}
@ -478,10 +544,9 @@ namespace Opm {
}
std::vector< int > Eclipse3DProperties::getRegions( const std::string& keyword ) const {
auto kw = uppercase(keyword);
if( !this->hasDeckIntGridProperty( kw ) ) return {};
if( !this->hasDeckIntGridProperty( keyword ) ) return {};
const auto& property = this->getIntGridProperty( kw );
const auto& property = this->getIntGridProperty( keyword );
std::set< int > regions( property.getData().begin(),
property.getData().end() );
@ -638,34 +703,34 @@ namespace Opm {
if (deckKeyword.name() == "BOX")
handleBOXKeyword(deckKeyword, boxManager);
if (deckKeyword.name() == "ENDBOX")
else if (deckKeyword.name() == "ENDBOX")
handleENDBOXKeyword(boxManager);
if (deckKeyword.name() == "COPY")
else if (deckKeyword.name() == "COPY")
handleCOPYKeyword( deckKeyword , boxManager);
if (deckKeyword.name() == "EQUALS")
else if (deckKeyword.name() == "EQUALS")
handleEQUALSKeyword(deckKeyword, boxManager);
if (deckKeyword.name() == "ADD")
else if (deckKeyword.name() == "ADD")
handleADDKeyword( deckKeyword , boxManager);
if (deckKeyword.name() == "MULTIPLY")
else if (deckKeyword.name() == "MULTIPLY")
handleMULTIPLYKeyword(deckKeyword, boxManager);
if (deckKeyword.name() == "EQUALREG")
else if (deckKeyword.name() == "EQUALREG")
handleEQUALREGKeyword(deckKeyword);
if (deckKeyword.name() == "ADDREG")
else if (deckKeyword.name() == "ADDREG")
handleADDREGKeyword(deckKeyword);
if (deckKeyword.name() == "MULTIREG")
else if (deckKeyword.name() == "MULTIREG")
handleMULTIREGKeyword(deckKeyword);
if (deckKeyword.name() == "COPYREG")
else if (deckKeyword.name() == "COPYREG")
handleCOPYREGKeyword(deckKeyword);
boxManager.endKeyword();
@ -710,7 +775,7 @@ namespace Opm {
void Eclipse3DProperties::handleADDREGKeyword( const DeckKeyword& deckKeyword) {
for( const auto& record : deckKeyword ) {
const std::string targetArray = uppercase(record.getItem("ARRAY").get< std::string >(0));
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
const auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
if (m_intGridProperties.hasKeyword( targetArray ))
@ -726,7 +791,7 @@ namespace Opm {
void Eclipse3DProperties::handleMULTIREGKeyword( const DeckKeyword& deckKeyword) {
for( const auto& record : deckKeyword ) {
const std::string targetArray = uppercase(record.getItem("ARRAY").get< std::string >(0));
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
const auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
if (m_intGridProperties.supportsKeyword( targetArray ))
@ -741,7 +806,7 @@ namespace Opm {
void Eclipse3DProperties::handleCOPYREGKeyword( const DeckKeyword& deckKeyword) {
for( const auto& record : deckKeyword ) {
const std::string srcArray = uppercase(record.getItem("ARRAY").get< std::string >(0));
const std::string& srcArray = record.getItem("ARRAY").get< std::string >(0);
const auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
if (m_intGridProperties.hasKeyword( srcArray ))
@ -758,7 +823,7 @@ namespace Opm {
void Eclipse3DProperties::handleMULTIPLYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
for( const auto& record : deckKeyword ) {
const std::string field = uppercase(record.getItem("field").get< std::string >(0));
const std::string& field = record.getItem("field").get< std::string >(0);
if (m_doubleGridProperties.hasKeyword( field ))
m_doubleGridProperties.handleMULTIPLYRecord( record , boxManager );
@ -778,7 +843,7 @@ namespace Opm {
*/
void Eclipse3DProperties::handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
for( const auto& record : deckKeyword ) {
const std::string field = uppercase(record.getItem("field").get< std::string >(0));
const std::string& field = record.getItem("field").get< std::string >(0);
if (m_doubleGridProperties.hasKeyword( field ))
m_doubleGridProperties.handleADDRecord( record , boxManager );
@ -793,7 +858,7 @@ namespace Opm {
void Eclipse3DProperties::handleCOPYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
for( const auto& record : deckKeyword ) {
const std::string field = uppercase(record.getItem("src").get< std::string >(0));
const std::string& field = record.getItem("src").get< std::string >(0);
if (m_doubleGridProperties.hasKeyword( field ))
m_doubleGridProperties.handleCOPYRecord( record , boxManager );
@ -808,7 +873,7 @@ namespace Opm {
void Eclipse3DProperties::handleEQUALSKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
for( const auto& record : deckKeyword ) {
const std::string field = uppercase(record.getItem("field").get< std::string >(0));
const std::string& field = record.getItem("field").get< std::string >(0);
if (m_doubleGridProperties.supportsKeyword( field ))
m_doubleGridProperties.handleEQUALSRecord( record , boxManager );

View File

@ -1,5 +1,5 @@
/*
Copyright 2013 Statoil ASA.
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
@ -19,13 +19,16 @@
#ifndef OPM_ECLIPSE_PROPERTIES_HPP
#define OPM_ECLIPSE_PROPERTIES_HPP
#include <utility>
#include <memory>
#include <set>
#include <vector>
#include <string>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
namespace Opm {
@ -36,13 +39,8 @@ namespace Opm {
class DeckKeyword;
class DeckRecord;
class EclipseGrid;
class EclipseState;
class InitConfig;
class IOConfig;
class Schedule;
class Section;
class TableManager;
class TransMult;
class UnitSystem;
/// Class representing properties on 3D grid for use in EclipseState.
@ -62,6 +60,9 @@ namespace Opm {
const GridProperty<int>& getIntGridProperty ( const std::string& keyword ) const;
const GridProperty<double>& getDoubleGridProperty ( const std::string& keyword ) const;
const GridProperties<int>& getIntProperties() const;
const GridProperties<double>& getDoubleProperties() const;
bool hasDeckIntGridProperty(const std::string& keyword) const;
bool hasDeckDoubleGridProperty(const std::string& keyword) const;
bool supportsGridProperty(const std::string& keyword) const;

View File

@ -20,12 +20,14 @@
#include <memory>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
@ -34,25 +36,53 @@ namespace Opm {
EclipseConfig::EclipseConfig(const Deck& deck,
const Eclipse3DProperties& eclipse3DProperties,
std::shared_ptr< EclipseGrid > inputGrid,
const Schedule& schedule) :
const GridDims& inputGrid,
const Schedule& schedule,
const ParseContext& parseContext) :
m_ioConfig( std::make_shared<IOConfig>(deck)),
m_initConfig( std::make_shared<const InitConfig>(deck)),
m_simulationConfig(std::make_shared<const SimulationConfig>(deck, eclipse3DProperties)),
m_summaryConfig( deck, schedule, eclipse3DProperties, inputGrid->getNXYZ())
m_initConfig( deck),
m_simulationConfig(deck, eclipse3DProperties),
m_summaryConfig( deck, schedule, eclipse3DProperties, parseContext , inputGrid.getNXYZ()),
m_restartConfig( deck )
{
// Hmmm - would have thought this should iterate through the SCHEDULE section as well?
if (Section::hasSOLUTION(deck)) {
std::shared_ptr<const SOLUTIONSection> solutionSection = std::make_shared<const SOLUTIONSection>(deck);
m_ioConfig->handleSolutionSection(schedule.getTimeMap(), solutionSection);
}
m_ioConfig->initFirstOutput(schedule);
m_ioConfig->initFirstRFTOutput(schedule);
}
const SummaryConfig& EclipseConfig::getSummaryConfig() const {
const InitConfig& EclipseConfig::init() const {
return m_initConfig;
}
const IOConfig& EclipseConfig::io() const {
return *m_ioConfig;
}
IOConfig& EclipseConfig::io() {
return *m_ioConfig;
}
const SimulationConfig& EclipseConfig::simulation() const {
return m_simulationConfig;
}
const SummaryConfig& EclipseConfig::summary() const {
return m_summaryConfig;
}
const RestartConfig& EclipseConfig::restart() const {
return this->m_restartConfig;
}
// [[deprecated]] --- use summary()
const SummaryConfig& EclipseConfig::getSummaryConfig() const {
return summary();
}
// [[deprecated]] --- use restart()
const RestartConfig& EclipseConfig::getRestartConfig() const {
return this->restart();
}
IOConfigConstPtr EclipseConfig::getIOConfigConst() const {
return m_ioConfig;
}
@ -61,11 +91,13 @@ namespace Opm {
return m_ioConfig;
}
InitConfigConstPtr EclipseConfig::getInitConfig() const {
return m_initConfig;
// [[deprecated]] --- use init()
const InitConfig& EclipseConfig::getInitConfig() const {
return init();
}
SimulationConfigConstPtr EclipseConfig::getSimulationConfig() const {
return m_simulationConfig;
// [[deprecated]] --- use simulation()
const SimulationConfig& EclipseConfig::getSimulationConfig() const {
return simulation();
}
}

View File

@ -23,35 +23,47 @@
#include <memory>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
namespace Opm {
class Deck;
class GridDims;
class Eclipse3DProperties;
class IOConfig;
class InitConfig;
class SimulationConfig;
class ParseContext;
class EclipseConfig
{
public:
EclipseConfig(const Deck& deck,
const Eclipse3DProperties& eclipse3DProperties,
std::shared_ptr< EclipseGrid > inputGrid,
const Schedule& schedule);
const GridDims& gridDims,
const Schedule& schedule,
const ParseContext& parseContext);
std::shared_ptr< const IOConfig > getIOConfigConst() const;
std::shared_ptr< IOConfig > getIOConfig() const;
std::shared_ptr< const InitConfig > getInitConfig() const;
std::shared_ptr< const SimulationConfig > getSimulationConfig() const;
const InitConfig& init() const;
const IOConfig& io() const;
IOConfig& io();
const SimulationConfig & simulation() const;
const SummaryConfig& summary() const;
const RestartConfig& restart() const;
std::shared_ptr<const IOConfig> getIOConfigConst() const;
std::shared_ptr<IOConfig> getIOConfig() const;
const InitConfig& getInitConfig() const;
const SimulationConfig & getSimulationConfig() const;
const SummaryConfig& getSummaryConfig() const;
const RestartConfig& getRestartConfig() const;
private:
std::shared_ptr<IOConfig> m_ioConfig;
std::shared_ptr<const InitConfig> m_initConfig;
std::shared_ptr<const SimulationConfig> m_simulationConfig;
const InitConfig m_initConfig;
const SimulationConfig m_simulationConfig;
SummaryConfig m_summaryConfig;
RestartConfig m_restartConfig;
};
}

View File

@ -30,6 +30,7 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
@ -56,16 +57,17 @@ namespace Opm {
EclipseState::EclipseState(const Deck& deck, ParseContext parseContext) :
m_parseContext( parseContext ),
m_tables( deck ),
m_gridDims( deck ),
m_inputGrid( std::make_shared<EclipseGrid>(deck, nullptr) ),
m_schedule( std::make_shared<Schedule>( m_parseContext, m_inputGrid, deck ) ),
m_transMult( m_inputGrid->getNX(), m_inputGrid->getNY(), m_inputGrid->getNZ()),
m_schedule( std::make_shared<Schedule>( m_parseContext, *m_inputGrid, deck ) ),
m_eclipseProperties( deck, m_tables, *m_inputGrid ),
m_eclipseConfig( deck, m_eclipseProperties, m_inputGrid, *m_schedule),
m_inputNnc( deck, m_inputGrid ),
m_eclipseConfig( deck, m_eclipseProperties, m_gridDims, *m_schedule , parseContext),
m_inputNnc( deck, m_gridDims ),
m_deckUnitSystem( deck.getActiveUnitSystem() )
{
if (m_inputGrid->hasCellInfo())
m_inputGrid->resetACTNUM(m_eclipseProperties.getIntGridProperty("ACTNUM").getData().data());
m_inputGrid->resetACTNUM(m_eclipseProperties.getIntGridProperty("ACTNUM").getData().data());
if (deck.hasKeyword( "TITLE" )) {
const auto& titleKeyword = deck.getKeyword( "TITLE" );
@ -76,7 +78,12 @@ namespace Opm {
initTransMult();
initFaults(deck);
initMULTREGT(deck);
std::vector< const DeckKeyword* > multregtKeywords;
if (deck.hasKeyword("MULTREGT"))
multregtKeywords = deck.getKeywordList("MULTREGT");
m_transMult.createMultregtScanner(m_eclipseProperties, multregtKeywords);
m_messageContainer.appendMessages(m_tables.getMessageContainer());
m_messageContainer.appendMessages(m_schedule->getMessageContainer());
@ -104,6 +111,14 @@ namespace Opm {
return m_eclipseConfig.getSummaryConfig();
}
const RestartConfig& EclipseState::getRestartConfig() const {
return m_eclipseConfig.getRestartConfig();
}
RestartConfig& EclipseState::getRestartConfig() {
return const_cast< RestartConfig& >( m_eclipseConfig.getRestartConfig() );
}
const Eclipse3DProperties& EclipseState::get3DProperties() const {
return m_eclipseProperties;
}
@ -130,19 +145,32 @@ namespace Opm {
return m_schedule;
}
/// [[deprecated]] --- use cfg().io()
IOConfigConstPtr EclipseState::getIOConfigConst() const {
return m_eclipseConfig.getIOConfigConst();
}
/// [[deprecated]] --- use cfg().io()
IOConfigPtr EclipseState::getIOConfig() const {
return m_eclipseConfig.getIOConfig();
}
InitConfigConstPtr EclipseState::getInitConfig() const {
/// [[deprecated]] --- use cfg().init()
const InitConfig& EclipseState::getInitConfig() const {
return m_eclipseConfig.getInitConfig();
}
SimulationConfigConstPtr EclipseState::getSimulationConfig() const {
/// [[deprecated]] --- use cfg()
const EclipseConfig& EclipseState::getEclipseConfig() const {
return cfg();
}
const EclipseConfig& EclipseState::cfg() const {
return m_eclipseConfig;
}
/// [[deprecated]] --- use cfg().simulation()
const SimulationConfig& EclipseState::getSimulationConfig() const {
return m_eclipseConfig.getSimulationConfig();
}
@ -150,7 +178,7 @@ namespace Opm {
return m_faults;
}
std::shared_ptr<const TransMult> EclipseState::getTransMult() const {
const TransMult& EclipseState::getTransMult() const {
return m_transMult;
}
@ -167,46 +195,41 @@ namespace Opm {
}
void EclipseState::initTransMult() {
EclipseGridConstPtr grid = getInputGrid();
m_transMult = std::make_shared<TransMult>( grid->getNX() , grid->getNY() , grid->getNZ());
const auto& p = m_eclipseProperties;
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTX"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTX"), FaceDir::XPlus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTX"), FaceDir::XPlus);
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTX-"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTX-"), FaceDir::XMinus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTX-"), FaceDir::XMinus);
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTY"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTY"), FaceDir::YPlus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTY"), FaceDir::YPlus);
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTY-"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTY-"), FaceDir::YMinus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTY-"), FaceDir::YMinus);
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTZ"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTZ"), FaceDir::ZPlus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTZ"), FaceDir::ZPlus);
if (m_eclipseProperties.hasDeckDoubleGridProperty("MULTZ-"))
m_transMult->applyMULT(p.getDoubleGridProperty("MULTZ-"), FaceDir::ZMinus);
m_transMult.applyMULT(p.getDoubleGridProperty("MULTZ-"), FaceDir::ZMinus);
}
void EclipseState::initFaults(const Deck& deck) {
EclipseGridConstPtr grid = getInputGrid();
std::shared_ptr<GRIDSection> gridSection = std::make_shared<GRIDSection>( deck );
const GRIDSection gridSection ( deck );
m_faults = FaultCollection(gridSection, grid);
m_faults = FaultCollection(gridSection, *m_inputGrid);
setMULTFLT(gridSection);
if (Section::hasEDIT(deck)) {
std::shared_ptr<EDITSection> editSection = std::make_shared<EDITSection>( deck );
setMULTFLT(editSection);
setMULTFLT(EDITSection ( deck ));
}
m_transMult->applyMULTFLT( m_faults );
m_transMult.applyMULTFLT( m_faults );
}
void EclipseState::setMULTFLT(std::shared_ptr<const Section> section) {
for (size_t index=0; index < section->count("MULTFLT"); index++) {
const auto& faultsKeyword = section->getKeyword("MULTFLT" , index);
void EclipseState::setMULTFLT(const Section& section) {
for (size_t index=0; index < section.count("MULTFLT"); index++) {
const auto& faultsKeyword = section.getKeyword("MULTFLT" , index);
for (auto iter = faultsKeyword.begin(); iter != faultsKeyword.end(); ++iter) {
const auto& faultRecord = *iter;
@ -218,26 +241,6 @@ namespace Opm {
}
}
void EclipseState::initMULTREGT(const Deck& deck) {
EclipseGridConstPtr grid = getInputGrid();
std::vector< const DeckKeyword* > multregtKeywords;
if (deck.hasKeyword("MULTREGT"))
multregtKeywords = deck.getKeywordList("MULTREGT");
std::shared_ptr<MULTREGTScanner> scanner =
std::make_shared<MULTREGTScanner>(
m_eclipseProperties,
multregtKeywords ,
m_eclipseProperties.getDefaultRegionKeyword());
m_transMult->setMultregtScanner( scanner );
}
void EclipseState::complainAboutAmbiguousKeyword(const Deck& deck, const std::string& keywordName) {
m_messageContainer.error("The " + keywordName + " keyword must be unique in the deck. Ignoring all!");
auto keywords = deck.getKeywordList(keywordName);
@ -247,10 +250,6 @@ namespace Opm {
}
}
void EclipseState::applyModifierDeck(std::shared_ptr<const Deck> deckptr) {
applyModifierDeck(*deckptr);
}
void EclipseState::applyModifierDeck(const Deck& deck) {
using namespace ParserKeywords;
for (const auto& keyword : deck) {
@ -284,7 +283,7 @@ namespace Opm {
*/
fault.setTransMult( tmpMultFlt );
m_transMult->applyMULTFLT( fault );
m_transMult.applyMULTFLT( fault );
fault.setTransMult( newMultFlt );
}
}

View File

@ -21,18 +21,13 @@
#define OPM_ECLIPSE_STATE_HPP
#include <memory>
#include <set>
#include <utility>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@ -52,11 +47,11 @@ namespace Opm {
class InitConfig;
class IOConfig;
class ParseContext;
class RestartConfig;
class Schedule;
class Section;
class SimulationConfig;
class TableManager;
class TransMult;
class UnitSystem;
class EclipseState {
@ -78,15 +73,18 @@ namespace Opm {
std::shared_ptr< const Schedule > getSchedule() const;
std::shared_ptr< const IOConfig > getIOConfigConst() const;
std::shared_ptr< IOConfig > getIOConfig() const;
std::shared_ptr< const InitConfig > getInitConfig() const;
std::shared_ptr< const SimulationConfig > getSimulationConfig() const;
const InitConfig& getInitConfig() const;
const SimulationConfig& getSimulationConfig() const;
const SummaryConfig& getSummaryConfig() const;
const RestartConfig& getRestartConfig() const;
RestartConfig& getRestartConfig();
std::shared_ptr< const EclipseGrid > getInputGrid() const;
std::shared_ptr< EclipseGrid > getInputGridCopy() const;
const FaultCollection& getFaults() const;
std::shared_ptr<const TransMult> getTransMult() const;
const TransMult& getTransMult() const;
/// non-neighboring connections
/// the non-standard adjacencies as specified in input deck
@ -96,6 +94,8 @@ namespace Opm {
const Eclipse3DProperties& get3DProperties() const;
const TableManager& getTableManager() const;
const EclipseConfig& getEclipseConfig() const;
const EclipseConfig& cfg() const;
// the unit system used by the deck. note that it is rarely needed to convert
// units because internally to opm-parser everything is represented by SI
@ -107,8 +107,6 @@ namespace Opm {
MessageContainer& getMessageContainer();
std::string getTitle() const;
/// [deprecated]
void applyModifierDeck(std::shared_ptr<const Deck>);
void applyModifierDeck(const Deck& deck);
private:
@ -116,26 +114,26 @@ namespace Opm {
void initTransMult();
void initFaults(const Deck& deck);
void setMULTFLT(std::shared_ptr<const Opm::Section> section);
void initMULTREGT(const Deck& deck);
void setMULTFLT(const Opm::Section& section);
void complainAboutAmbiguousKeyword(const Deck& deck,
const std::string& keywordName);
ParseContext m_parseContext;
const TableManager m_tables;
const GridDims m_gridDims;
std::shared_ptr<EclipseGrid> m_inputGrid;
TransMult m_transMult;
std::shared_ptr< const Schedule > m_schedule;
Eclipse3DProperties m_eclipseProperties;
EclipseConfig m_eclipseConfig;
NNC m_inputNnc;
UnitSystem m_deckUnitSystem;
MessageContainer m_messageContainer;
std::shared_ptr<TransMult> m_transMult;
FaultCollection m_faults;
std::string m_title;
MessageContainer m_messageContainer;
};
typedef std::shared_ptr<EclipseState> EclipseStatePtr;

View File

@ -29,6 +29,9 @@
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/C.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/D.hpp>
@ -37,88 +40,96 @@
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/T.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/Z.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <ert/ecl/ecl_grid.h>
namespace Opm {
EclipseGrid::EclipseGrid(std::array<int, 3>& dims ,
const std::vector<double>& coord ,
const std::vector<double>& zcorn ,
const int * actnum,
const double * mapaxes)
: m_minpvValue(0),
m_minpvMode(MinpvMode::ModeEnum::Inactive),
m_pinch("PINCH"),
m_pinchoutMode(PinchMode::ModeEnum::TOPBOT),
m_multzMode(PinchMode::ModeEnum::TOP)
{
initCornerPointGrid( dims, coord , zcorn , actnum , mapaxes );
}
/**
Will create an EclipseGrid instance based on an existing
GRID/EGRID file.
*/
EclipseGrid::EclipseGrid(const std::string& filename )
: m_minpvValue(0),
: GridDims(),
m_minpvValue(0),
m_minpvMode(MinpvMode::ModeEnum::Inactive),
m_pinch("PINCH"),
m_pinchoutMode(PinchMode::ModeEnum::TOPBOT),
m_multzMode(PinchMode::ModeEnum::TOP)
{
ecl_grid_type * new_ptr = ecl_grid_load_case( filename.c_str() );
ecl_grid_type * new_ptr = ecl_grid_load_case__( filename.c_str() , false );
if (new_ptr)
m_grid.reset( new_ptr );
else
throw std::invalid_argument("Could not load grid from binary file: " + filename);
m_nx = static_cast<size_t>( ecl_grid_get_nx( c_ptr() ));
m_ny = static_cast<size_t>( ecl_grid_get_ny( c_ptr() ));
m_nz = static_cast<size_t>( ecl_grid_get_nz( c_ptr() ));
m_nx = ecl_grid_get_nx( c_ptr() );
m_ny = ecl_grid_get_ny( c_ptr() );
m_nz = ecl_grid_get_nz( c_ptr() );
}
/* Copy constructor */
EclipseGrid::EclipseGrid(const EclipseGrid& src)
: m_minpvValue( src.m_minpvValue ),
m_minpvMode( src.m_minpvMode ),
m_pinch( src.m_pinch ),
m_pinchoutMode( src.m_pinchoutMode ),
m_multzMode( src.m_multzMode ),
m_nx( src.m_nx ),
m_ny( src.m_ny ),
m_nz( src.m_nz ),
m_messages( src.m_messages )
{
if (src.hasCellInfo())
m_grid.reset( ecl_grid_alloc_copy( src.c_ptr() ) );
}
/*
This creates a grid which only has dimension, and no pointer to
a true grid structure. This grid will answer false to
hasCellInfo() - but can be used in all situations where the grid
dependency is really only on the dimensions.
*/
EclipseGrid::EclipseGrid(size_t nx, size_t ny , size_t nz,
double dx, double dy, double dz)
: m_minpvValue(0),
: GridDims(nx, ny, nz),
m_minpvValue(0),
m_minpvMode(MinpvMode::ModeEnum::Inactive),
m_pinch("PINCH"),
m_pinchoutMode(PinchMode::ModeEnum::TOPBOT),
m_multzMode(PinchMode::ModeEnum::TOP)
m_multzMode(PinchMode::ModeEnum::TOP),
m_grid( ecl_grid_alloc_rectangular(nx, ny, nz, dx, dy, dz, NULL) )
{
m_nx = nx;
m_ny = ny;
m_nz = nz;
m_grid.reset(ecl_grid_alloc_rectangular(nx, ny, nz, dx, dy, dz, NULL));
}
// keyword must be DIMENS or SPECGRID
static std::vector<int> getDims( const DeckKeyword& keyword ) {
const auto& record = keyword.getRecord(0);
std::vector<int> dims = {record.getItem("NX").get< int >(0) ,
record.getItem("NY").get< int >(0) ,
record.getItem("NZ").get< int >(0) };
return dims;
}
EclipseGrid::EclipseGrid(const std::shared_ptr<const Deck>& deckptr, const int * actnum)
:
EclipseGrid(*deckptr, actnum)
: EclipseGrid(*deckptr, actnum)
{}
EclipseGrid::EclipseGrid(const EclipseGrid& src, const double* zcorn , const std::vector<int>& actnum)
: GridDims(src.getNX(), src.getNY(), src.getNZ()),
m_messages( src.m_messages ),
m_minpvValue( src.m_minpvValue ),
m_minpvMode( src.m_minpvMode ),
m_pinch( src.m_pinch ),
m_pinchoutMode( src.m_pinchoutMode ),
m_multzMode( src.m_multzMode )
{
const int * actnum_data = (actnum.empty()) ? nullptr : actnum.data();
m_grid.reset( ecl_grid_alloc_processed_copy( src.c_ptr(), zcorn , actnum_data ));
}
EclipseGrid::EclipseGrid(const EclipseGrid& src, const std::vector<double>& zcorn , const std::vector<int>& actnum)
: EclipseGrid( src , (zcorn.empty()) ? nullptr : zcorn.data(), actnum )
{ }
EclipseGrid::EclipseGrid(const EclipseGrid& src, const std::vector<int>& actnum)
: EclipseGrid( src , nullptr , actnum )
{ }
/*
This is the main EclipseGrid constructor, it will inspect the
input Deck for grid keywords, either the corner point keywords
@ -149,54 +160,17 @@ namespace Opm {
EclipseGrid::EclipseGrid(const Deck& deck, const int * actnum)
: m_minpvValue(0),
: GridDims(deck),
m_minpvValue(0),
m_minpvMode(MinpvMode::ModeEnum::Inactive),
m_pinch("PINCH"),
m_pinchoutMode(PinchMode::ModeEnum::TOPBOT),
m_multzMode(PinchMode::ModeEnum::TOP)
{
const bool hasRUNSPEC = Section::hasRUNSPEC(deck);
const bool hasGRID = Section::hasGRID(deck);
if (hasRUNSPEC && hasGRID) {
// Equivalent to first constructor.
RUNSPECSection runspecSection( deck );
if( runspecSection.hasKeyword<ParserKeywords::DIMENS>() ) {
const auto& dimens = runspecSection.getKeyword<ParserKeywords::DIMENS>();
std::vector<int> dims = getDims(dimens);
initGrid(dims, deck);
} else {
const std::string msg = "The RUNSPEC section must have the DIMENS keyword with logically Cartesian grid dimensions.";
m_messages.error(msg);
throw std::invalid_argument(msg);
}
} else if (hasGRID) {
// Look for SPECGRID instead of DIMENS.
if (deck.hasKeyword<ParserKeywords::SPECGRID>()) {
const auto& specgrid = deck.getKeyword<ParserKeywords::SPECGRID>();
std::vector<int> dims = getDims(specgrid);
initGrid(dims, deck);
} else {
const std::string msg = "With no RUNSPEC section, the GRID section must specify the grid dimensions using the SPECGRID keyword.";
m_messages.error(msg);
throw std::invalid_argument(msg);
}
} else {
// The deck contains no relevant section, so it is probably a sectionless GRDECL file.
// Either SPECGRID or DIMENS is OK.
if (deck.hasKeyword("SPECGRID")) {
const auto& specgrid = deck.getKeyword<ParserKeywords::SPECGRID>();
std::vector<int> dims = getDims(specgrid);
initGrid(dims, deck);
} else if (deck.hasKeyword<ParserKeywords::DIMENS>()) {
const auto& dimens = deck.getKeyword<ParserKeywords::DIMENS>();
std::vector<int> dims = getDims(dimens);
initGrid(dims, deck);
} else {
const std::string msg = "The deck must specify grid dimensions using either DIMENS or SPECGRID.";
m_messages.error(msg);
throw std::invalid_argument(msg);
}
}
const std::array<int, 3> dims = getNXYZ();
initGrid(dims, deck);
if (actnum != nullptr)
resetACTNUM(actnum);
else {
@ -213,15 +187,13 @@ namespace Opm {
}
void EclipseGrid::initGrid( const std::vector<int>& dims, const Deck& deck) {
m_nx = static_cast<size_t>(dims[0]);
m_ny = static_cast<size_t>(dims[1]);
m_nz = static_cast<size_t>(dims[2]);
void EclipseGrid::initGrid( const std::array<int, 3>& dims, const Deck& deck) {
if (hasCornerPointKeywords(deck)) {
initCornerPointGrid(dims , deck);
} else if (hasCartesianKeywords(deck)) {
initCartesianGrid(dims , deck);
} else {
throw std::invalid_argument("EclipseGrid needs cornerpoint or cartesian keywords.");
}
if (deck.hasKeyword<ParserKeywords::PINCH>()) {
@ -261,39 +233,26 @@ namespace Opm {
return activeIndex( getGlobalIndex( i,j,k ));
}
size_t EclipseGrid::activeIndex(size_t globalIndex) const {
assertCellInfo();
{
int active_index = ecl_grid_get_active_index1( m_grid.get() , globalIndex );
if (active_index < 0)
throw std::invalid_argument("Input argument does not correspond to an active cell");
return static_cast<size_t>( active_index );
}
int active_index = ecl_grid_get_active_index1( m_grid.get() , globalIndex );
if (active_index < 0)
throw std::invalid_argument("Input argument does not correspond to an active cell");
return static_cast<size_t>( active_index );
}
size_t EclipseGrid::getNX( ) const {
return m_nx;
/**
Observe: the input argument is assumed to be in the space
[0,num_active).
*/
size_t EclipseGrid::getGlobalIndex(size_t active_index) const {
int global_index = ecl_grid_get_global_index1A( m_grid.get() , active_index );
return static_cast<size_t>(global_index);
}
size_t EclipseGrid::getNY( ) const {
return m_ny;
size_t EclipseGrid::getGlobalIndex(size_t i, size_t j, size_t k) const {
return GridDims::getGlobalIndex(i,j,k);
}
size_t EclipseGrid::getNZ( ) const {
return m_nz;
}
std::array< int, 3 > EclipseGrid::getNXYZ() const {
return {{ int( m_nx ), int( m_ny ), int( m_nz ) }};
}
size_t EclipseGrid::getCartesianSize( ) const {
return m_nx * m_ny * m_nz;
}
bool EclipseGrid::isPinchActive( ) const {
return m_pinch.hasValue();
@ -320,34 +279,7 @@ namespace Opm {
}
size_t EclipseGrid::getGlobalIndex(size_t i, size_t j, size_t k) const {
return (i + j * getNX() + k * getNX() * getNY());
}
std::array<int, 3> EclipseGrid::getIJK(size_t globalIndex) const {
std::array<int, 3> r = {{ 0, 0, 0 }};
int k = globalIndex / (getNX() * getNY()); globalIndex -= k * (getNX() * getNY());
int j = globalIndex / getNX(); globalIndex -= j * getNX();
int i = globalIndex;
r[0] = i;
r[1] = j;
r[2] = k;
return r;
}
void EclipseGrid::assertGlobalIndex(size_t globalIndex) const {
if (globalIndex >= getCartesianSize())
throw std::invalid_argument("input index above valid range");
}
void EclipseGrid::assertIJK(size_t i , size_t j , size_t k) const {
if (i >= getNX() || j >= getNY() || k >= getNZ())
throw std::invalid_argument("input index above valid range");
}
void EclipseGrid::initCartesianGrid(const std::vector<int>& dims , const Deck& deck) {
void EclipseGrid::initCartesianGrid(const std::array<int, 3>& dims , const Deck& deck) {
if (hasDVDEPTHZKeywords( deck ))
initDVDEPTHZGrid( dims , deck );
else if (hasDTOPSKeywords(deck))
@ -357,7 +289,7 @@ namespace Opm {
}
void EclipseGrid::initDVDEPTHZGrid(const std::vector<int>& dims, const Deck& deck) {
void EclipseGrid::initDVDEPTHZGrid(const std::array<int, 3>& dims, const Deck& deck) {
const std::vector<double>& DXV = deck.getKeyword<ParserKeywords::DXV>().getSIDoubleData();
const std::vector<double>& DYV = deck.getKeyword<ParserKeywords::DYV>().getSIDoubleData();
const std::vector<double>& DZV = deck.getKeyword<ParserKeywords::DZV>().getSIDoubleData();
@ -372,7 +304,7 @@ namespace Opm {
}
void EclipseGrid::initDTOPSGrid(const std::vector<int>& dims , const Deck& deck) {
void EclipseGrid::initDTOPSGrid(const std::array<int, 3>& dims , const Deck& deck) {
std::vector<double> DX = createDVector( dims , 0 , "DX" , "DXV" , deck);
std::vector<double> DY = createDVector( dims , 1 , "DY" , "DYV" , deck);
std::vector<double> DZ = createDVector( dims , 2 , "DZ" , "DZV" , deck);
@ -380,14 +312,44 @@ namespace Opm {
m_grid.reset( ecl_grid_alloc_dx_dy_dz_tops( dims[0] , dims[1] , dims[2] , DX.data() , DY.data() , DZ.data() , TOPS.data() , nullptr ) );
}
void EclipseGrid::initCornerPointGrid(const std::vector<int>& dims, const Deck& deck) {
void EclipseGrid::initCornerPointGrid(const std::array<int,3>& dims ,
const std::vector<double>& coord ,
const std::vector<double>& zcorn ,
const int * actnum,
const double * mapaxes)
{
const std::vector<float> zcorn_float( zcorn.begin() , zcorn.end() );
const std::vector<float> coord_float( coord.begin() , coord.end() );
float * mapaxes_float = nullptr;
if (mapaxes) {
mapaxes_float = new float[6];
for (size_t i=0; i < 6; i++)
mapaxes_float[i] = mapaxes[i];
}
m_grid.reset( ecl_grid_alloc_GRDECL_data(dims[0] ,
dims[1] ,
dims[2] ,
zcorn_float.data() ,
coord_float.data() ,
actnum ,
false, // We do not apply the MAPAXES transformations
mapaxes_float) );
if (mapaxes)
delete[] mapaxes_float;
}
void EclipseGrid::initCornerPointGrid(const std::array<int,3>& dims, const Deck& deck) {
assertCornerPointKeywords( dims , deck);
{
const auto& ZCORNKeyWord = deck.getKeyword<ParserKeywords::ZCORN>();
const auto& COORDKeyWord = deck.getKeyword<ParserKeywords::COORD>();
const std::vector<double>& zcorn = ZCORNKeyWord.getSIDoubleData();
const std::vector<double>& coord = COORDKeyWord.getSIDoubleData();
double * mapaxes = NULL;
double * mapaxes = nullptr;
if (deck.hasKeyword<ParserKeywords::MAPAXES>()) {
const auto& mapaxesKeyword = deck.getKeyword<ParserKeywords::MAPAXES>();
@ -397,24 +359,9 @@ namespace Opm {
mapaxes[i] = record.getItem( i ).getSIDouble( 0 );
}
}
{
const std::vector<float> zcorn_float( zcorn.begin() , zcorn.end() );
const std::vector<float> coord_float( coord.begin() , coord.end() );
float * mapaxes_float = NULL;
if (mapaxes) {
mapaxes_float = new float[6];
for (size_t i=0; i < 6; i++)
mapaxes_float[i] = mapaxes[i];
}
m_grid.reset( ecl_grid_alloc_GRDECL_data(dims[0] , dims[1] , dims[2] , zcorn_float.data() , coord_float.data() , nullptr , mapaxes_float) );
if (mapaxes) {
delete[] mapaxes_float;
delete[] mapaxes;
}
}
initCornerPointGrid( dims, coord , zcorn , nullptr , mapaxes );
if (mapaxes)
delete[] mapaxes;
}
}
@ -428,7 +375,7 @@ namespace Opm {
}
void EclipseGrid::assertCornerPointKeywords( const std::vector<int>& dims , const Deck& deck)
void EclipseGrid::assertCornerPointKeywords(const std::array<int, 3>& dims , const Deck& deck)
{
const int nx = dims[0];
const int ny = dims[1];
@ -530,7 +477,7 @@ namespace Opm {
retained.
*/
std::vector<double> EclipseGrid::createTOPSVector(const std::vector<int>& dims,
std::vector<double> EclipseGrid::createTOPSVector(const std::array<int, 3>& dims,
const std::vector<double>& DZ, const Deck& deck)
{
double z_tolerance = 1e-6;
@ -563,7 +510,7 @@ namespace Opm {
return TOPS;
}
std::vector<double> EclipseGrid::createDVector(const std::vector<int>& dims, size_t dim, const std::string& DKey,
std::vector<double> EclipseGrid::createDVector(const std::array<int, 3>& dims, size_t dim, const std::string& DKey,
const std::string& DVKey, const Deck& deck)
{
size_t volume = dims[0] * dims[1] * dims[2];
@ -600,7 +547,7 @@ namespace Opm {
}
void EclipseGrid::scatterDim(const std::vector<int>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D) {
void EclipseGrid::scatterDim(const std::array<int, 3>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D) {
int index[3];
for (index[2] = 0; index[2] < dims[2]; index[2]++) {
for (index[1] = 0; index[1] < dims[1]; index[1]++) {
@ -612,26 +559,7 @@ namespace Opm {
}
}
/*
This function checks if the grid has a pointer to an underlying
ecl_grid_type; which must be used to read cell info as
size/depth/active of individual cells.
*/
bool EclipseGrid::hasCellInfo() const {
return static_cast<bool>( m_grid );
}
void EclipseGrid::assertCellInfo() const {
if (!hasCellInfo())
throw std::invalid_argument("Tried to access cell information in a grid with only dimensions");
}
const ecl_grid_type * EclipseGrid::c_ptr() const {
assertCellInfo();
return m_grid.get();
}
@ -651,7 +579,7 @@ namespace Opm {
if(m_minpvMode!=MinpvMode::ModeEnum::Inactive){
status = status && (m_minpvValue == other.getMinpvValue());
}
return status;
return status;
}
@ -659,6 +587,10 @@ namespace Opm {
return static_cast<size_t>(ecl_grid_get_nactive( c_ptr() ));
}
bool EclipseGrid::allActive( ) const {
return (getNumActive() == getCartesianSize());
}
bool EclipseGrid::cellActive( size_t globalIndex ) const {
assertGlobalIndex( globalIndex );
return ecl_grid_cell_active1( c_ptr() , static_cast<int>(globalIndex));
@ -776,20 +708,69 @@ namespace Opm {
ecl_grid_init_zcorn_data_double( c_ptr() , zcorn.data() );
}
const std::vector<int>& EclipseGrid::getActiveMap() const {
if( !this->activeMap.empty() ) return this->activeMap;
this->activeMap.resize( this->getNumActive() );
const auto size = int(this->getCartesianSize());
for( int global_index = 0; global_index < size; global_index++) {
// Using the low level C function to get the active index, because the C++
// version will throw for inactive cells.
int active_index = ecl_grid_get_active_index1( m_grid.get() , global_index );
if (active_index >= 0)
this->activeMap[ active_index ] = global_index;
}
return this->activeMap;
}
void EclipseGrid::resetACTNUM( const int * actnum) {
assertCellInfo();
ecl_grid_reset_actnum( m_grid.get() , actnum );
/* re-build the active map cache */
this->activeMap.clear();
this->getActiveMap();
}
ZcornMapper EclipseGrid::zcornMapper() const {
return ZcornMapper( getNX() , getNY(), getNZ() );
}
ZcornMapper::ZcornMapper(size_t nx , size_t ny, size_t nz)
: dims( {nx,ny,nz} ),
stride( {2 , 4*nx, 8*nx*ny} ),
cell_shift( {0 , 1 , 2*nx , 2*nx + 1 , 4*nx*ny , 4*nx*ny + 1, 4*nx*ny + 2*nx , 4*nx*ny + 2*nx + 1 })
{
}
void EclipseGrid::fwriteEGRID( const std::string& filename, bool output_metric ) const {
assertCellInfo();
ecl_grid_fwrite_EGRID( m_grid.get() , filename.c_str(), output_metric );
/* lower layer: upper layer (higher value of z - i.e. lower down in resrvoir).
2---3 6---7
| | | |
0---1 4---5
*/
size_t ZcornMapper::index(size_t i, size_t j, size_t k, int c) const {
if ((i >= dims[0]) || (j >= dims[1]) || (k >= dims[2]) || (c < 0) || (c >= 8))
throw std::invalid_argument("Invalid cell argument");
return i*stride[0] + j*stride[1] + k*stride[2] + cell_shift[c];
}
size_t ZcornMapper::index(size_t g, int c) const {
int k = g / (dims[0] * dims[1]);
g -= k * dims[0] * dims[1];
int j = g / dims[0];
g -= j * dims[0];
int i = g;
return index(i,j,k,c);
}
}

View File

@ -18,13 +18,15 @@
*/
#ifndef ECLIPSE_GRID_HPP_
#define ECLIPSE_GRID_HPP_
#ifndef OPM_PARSER_ECLIPSE_GRID_HPP
#define OPM_PARSER_ECLIPSE_GRID_HPP
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/PinchMode.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <ert/ecl/ecl_grid.h>
@ -37,6 +39,7 @@
namespace Opm {
class Deck;
class ZcornMapper;
/**
About cell information and dimension: The actual grid
@ -47,33 +50,29 @@ namespace Opm {
- Size of cells
- Real world position of cells
- Active/inactive status of cells
However in may cases the only required information is the
dimension of the grid. To facilitate simpler use, in particular
in testing, the grid dimensions are internalized separate from
the ecl_grid_type pointer. This means that in many cases a grid
without the underlying ecl_grid_type pointer is sufficient. To
create such a 'naked' grid you can parse a deck with only
DIMENS / SPECGRID and no further grid related keywords, or
alternatively use the:
EclipseGrid::EclipseGrid(nx,ny,nz)
constructor.
To query a grid instance if it has proper underlying grid
support use the method:
bool EclipseGrid::hasCellInfo();
*/
class EclipseGrid {
class EclipseGrid : public GridDims {
public:
explicit EclipseGrid(const std::string& filename);
explicit EclipseGrid(const EclipseGrid& srcGrid);
explicit EclipseGrid(size_t nx, size_t ny, size_t nz,
double dx = 1.0, double dy = 1.0, double dz = 1.0);
/*
These constructors will make a copy of the src grid, with
zcorn and or actnum have been adjustments.
*/
EclipseGrid(const EclipseGrid& src, const double* zcorn , const std::vector<int>& actnum);
EclipseGrid(const EclipseGrid& src, const std::vector<double>& zcorn , const std::vector<int>& actnum);
EclipseGrid(const EclipseGrid& src, const std::vector<int>& actnum);
EclipseGrid(size_t nx, size_t ny, size_t nz,
double dx = 1.0, double dy = 1.0, double dz = 1.0);
EclipseGrid(std::array<int, 3>& dims ,
const std::vector<double>& coord ,
const std::vector<double>& zcorn ,
const int * actnum = nullptr,
const double * mapaxes = nullptr);
/// EclipseGrid ignores ACTNUM in Deck, and therefore needs ACTNUM
/// explicitly. If a null pointer is passed, every cell is active.
@ -84,11 +83,20 @@ namespace Opm {
static bool hasCornerPointKeywords(const Deck&);
static bool hasCartesianKeywords(const Deck&);
size_t getNumActive( ) const;
size_t getNX( ) const;
size_t getNY( ) const;
size_t getNZ( ) const;
std::array< int, 3 > getNXYZ() const;
size_t getCartesianSize( ) const;
bool allActive() const;
size_t activeIndex(size_t i, size_t j, size_t k) const;
size_t activeIndex(size_t globalIndex) const;
/*
Observe that the there is a getGlobalIndex(i,j,k)
implementation in the base class. This method - translating
from an active index to a global index must be implemented
in the current class.
*/
size_t getGlobalIndex(size_t active_index) const;
size_t getGlobalIndex(size_t i, size_t j, size_t k) const;
bool isPinchActive( ) const;
double getPinchThresholdThickness( ) const;
PinchMode::ModeEnum getPinchOption( ) const;
@ -97,22 +105,43 @@ namespace Opm {
MinpvMode::ModeEnum getMinpvMode() const;
double getMinpvValue( ) const;
bool hasCellInfo() const;
/// The activeIndex methods will return from (i,j,k) or g,
/// where g \in [0,nx*n*nz) to the corresponding active index
/// in the range [0,numActive). Observe that if the input
/// argument corresponds to a cell which is not active an
/// exception will be raised - check with cellActive() first
/// if that is a possibillity.
size_t activeIndex(size_t i, size_t j, size_t k) const;
size_t activeIndex(size_t globalIndex) const;
/*
Will return a vector of nactive elements. The method will
behave differently depending on the lenght of the
input_vector:
nx*ny*nz: only the values corresponding to active cells
are copied out.
nactive: The input vector is copied straight out again.
??? : Exception.
*/
template<typename T>
std::vector<T> compressedVector(const std::vector<T>& input_vector) const {
if( input_vector.size() == this->getNumActive() ) {
return input_vector;
}
if (input_vector.size() != getCartesianSize())
throw std::invalid_argument("Input vector must have full size");
{
std::vector<T> compressed_vector( this->getNumActive() );
const auto& active_map = this->getActiveMap( );
for (size_t i = 0; i < this->getNumActive(); ++i)
compressed_vector[i] = input_vector[ active_map[i] ];
return compressed_vector;
}
}
size_t getGlobalIndex(size_t i, size_t j, size_t k) const;
std::array<int, 3> getIJK(size_t globalIndex) const;
void assertGlobalIndex(size_t globalIndex) const;
void assertIJK(size_t i , size_t j , size_t k) const;
/// Will return a vector a length num_active; where the value
/// of each element is the corresponding global index.
const std::vector<int>& getActiveMap() const;
std::array<double, 3> getCellCenter(size_t i,size_t j, size_t k) const;
std::array<double, 3> getCellCenter(size_t globalIndex) const;
double getCellVolume(size_t globalIndex) const;
@ -125,6 +154,7 @@ namespace Opm {
bool cellActive( size_t i , size_t j, size_t k ) const;
double getCellDepth(size_t i,size_t j, size_t k) const;
double getCellDepth(size_t globalIndex) const;
ZcornMapper zcornMapper() const;
void exportMAPAXES( std::vector<double>& mapaxes) const;
@ -133,46 +163,76 @@ namespace Opm {
void exportACTNUM( std::vector<int>& actnum) const;
void resetACTNUM( const int * actnum);
bool equal(const EclipseGrid& other) const;
void fwriteEGRID( const std::string& filename, bool output_metric ) const;
const ecl_grid_type * c_ptr() const;
const MessageContainer& getMessageContainer() const;
MessageContainer& getMessageContainer();
private:
ERT::ert_unique_ptr<ecl_grid_type , ecl_grid_free> m_grid;
MessageContainer m_messages;
double m_minpvValue;
MinpvMode::ModeEnum m_minpvMode;
Value<double> m_pinch;
PinchMode::ModeEnum m_pinchoutMode;
PinchMode::ModeEnum m_multzMode;
size_t m_nx;
size_t m_ny;
size_t m_nz;
MessageContainer m_messages;
mutable std::vector< int > activeMap;
void assertCellInfo() const;
/*
The internal class grid_ptr is a a std::unique_ptr with
special copy semantics. The purpose of implementing this is
that the EclipseGrid class can now use the default
implementation for the copy and move constructors.
*/
using ert_ptr = ERT::ert_unique_ptr<ecl_grid_type , ecl_grid_free>;
class grid_ptr : public ert_ptr {
public:
using ert_ptr::unique_ptr;
grid_ptr() = default;
grid_ptr(grid_ptr&&) = default;
grid_ptr(const grid_ptr& src) :
ert_ptr( ecl_grid_alloc_copy( src.get() ) ) {}
};
grid_ptr m_grid;
void initCartesianGrid(const std::vector<int>& dims, const Deck&);
void initCornerPointGrid(const std::vector<int>& dims, const Deck&);
void initDTOPSGrid(const std::vector<int>& dims, const Deck&);
void initDVDEPTHZGrid(const std::vector<int>& dims, const Deck& deck);
void initGrid(const std::vector<int>& dims, const Deck&);
void initCornerPointGrid(const std::array<int,3>& dims ,
const std::vector<double>& coord ,
const std::vector<double>& zcorn ,
const int * actnum,
const double * mapaxes);
void initCartesianGrid( const std::array<int, 3>&, const Deck&);
void initCornerPointGrid( const std::array<int, 3>&, const Deck&);
void initDTOPSGrid( const std::array<int, 3>&, const Deck&);
void initDVDEPTHZGrid( const std::array<int, 3>&, const Deck&);
void initGrid( const std::array<int, 3>&, const Deck&);
void assertCornerPointKeywords( const std::array<int, 3>&, const Deck&);
void assertCornerPointKeywords(const std::vector<int>& dims, const Deck&);
static bool hasDVDEPTHZKeywords(const Deck&);
static bool hasDTOPSKeywords(const Deck&);
static void assertVectorSize(const std::vector<double>& vector, size_t expectedSize, const std::string& msg);
static std::vector<double> createTOPSVector(const std::vector<int>& dims, const std::vector<double>& DZ,
static bool hasDTOPSKeywords( const Deck&);
static void assertVectorSize( const std::vector<double>& vector, size_t expectedSize, const std::string& msg);
static std::vector<double> createTOPSVector(const std::array<int, 3>& dims, const std::vector<double>& DZ,
const Deck&);
static std::vector<double> createDVector(const std::vector<int>& dims, size_t dim, const std::string& DKey,
static std::vector<double> createDVector(const std::array<int, 3>& dims, size_t dim, const std::string& DKey,
const std::string& DVKey, const Deck&);
static void scatterDim(const std::vector<int>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D);
static void scatterDim(const std::array<int, 3>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D);
};
typedef std::shared_ptr<EclipseGrid> EclipseGridPtr;
typedef std::shared_ptr<const EclipseGrid> EclipseGridConstPtr;
class ZcornMapper {
public:
ZcornMapper(size_t nx, size_t ny, size_t nz);
size_t index(size_t i, size_t j, size_t k, int c) const;
size_t index(size_t g, int c) const;
private:
std::array<size_t,3> dims;
std::array<size_t,3> stride;
std::array<size_t,8> cell_shift;
};
}
#endif
#endif // OPM_PARSER_ECLIPSE_GRID_HPP

View File

@ -17,14 +17,18 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iterator>
#include <memory>
#include <string>
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp>
@ -33,42 +37,51 @@
namespace Opm {
FaultCollection::FaultCollection()
{}
FaultCollection::FaultCollection( std::shared_ptr<const GRIDSection> deck, std::shared_ptr<const EclipseGrid> grid) {
const auto& faultKeywords = deck->getKeywordList<ParserKeywords::FAULTS>();
FaultCollection::FaultCollection(const GRIDSection& gridSection,
const GridDims& grid) {
const auto& faultKeywords = gridSection.getKeywordList<ParserKeywords::FAULTS>();
for (auto keyword_iter = faultKeywords.begin(); keyword_iter != faultKeywords.end(); ++keyword_iter) {
const auto& faultsKeyword = *keyword_iter;
for (auto iter = faultsKeyword->begin(); iter != faultsKeyword->end(); ++iter) {
const auto& faultRecord = *iter;
const std::string& faultName = faultRecord.getItem(0).get< std::string >(0);
int I1 = faultRecord.getItem(1).get< int >(0) - 1;
int I2 = faultRecord.getItem(2).get< int >(0) - 1;
int J1 = faultRecord.getItem(3).get< int >(0) - 1;
int J2 = faultRecord.getItem(4).get< int >(0) - 1;
int K1 = faultRecord.getItem(5).get< int >(0) - 1;
int K2 = faultRecord.getItem(6).get< int >(0) - 1;
FaceDir::DirEnum faceDir = FaceDir::FromString( faultRecord.getItem(7).get< std::string >(0) );
std::shared_ptr<const FaultFace> face = std::make_shared<const FaultFace>(grid->getNX() , grid->getNY() , grid->getNZ(),
static_cast<size_t>(I1) , static_cast<size_t>(I2) ,
static_cast<size_t>(J1) , static_cast<size_t>(J2) ,
static_cast<size_t>(K1) , static_cast<size_t>(K2) ,
faceDir);
if (!hasFault(faultName)) {
addFault( faultName );
}
{
Fault& fault = getFault( faultName );
fault.addFace( face );
}
addFaultFaces(grid, faultRecord, faultName);
}
}
}
void FaultCollection::addFaultFaces(const GridDims& grid,
const DeckRecord& faultRecord,
const std::string& faultName)
{
int I1 = faultRecord.getItem(1).get<int>(0) - 1;
int I2 = faultRecord.getItem(2).get<int>(0) - 1;
int J1 = faultRecord.getItem(3).get<int>(0) - 1;
int J2 = faultRecord.getItem(4).get<int>(0) - 1;
int K1 = faultRecord.getItem(5).get<int>(0) - 1;
int K2 = faultRecord.getItem(6).get<int>(0) - 1;
FaceDir::DirEnum faceDir = FaceDir::FromString(faultRecord.getItem(7).get<std::string>(0));
std::shared_ptr<const FaultFace> face = std::make_shared<const FaultFace>(
grid.getNX(), grid.getNY(), grid.getNZ(),
static_cast<size_t>(I1), static_cast<size_t>(I2),
static_cast<size_t>(J1), static_cast<size_t>(J2),
static_cast<size_t>(K1), static_cast<size_t>(K2),
faceDir);
if (!hasFault(faultName))
addFault(faultName);
Fault& fault = getFault(faultName);
fault.addFace(face);
}
size_t FaultCollection::size() const {
return m_faults.size();
}

View File

@ -16,29 +16,26 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FAULT_COLLECTION_HPP_
#define FAULT_COLLECTION_HPP_
#ifndef OPM_PARSER_FAULT_COLLECTION_HPP
#define OPM_PARSER_FAULT_COLLECTION_HPP
#include <cstddef>
#include <string>
#include <memory>
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
namespace Opm {
class Deck;
class GRIDSection;
class EclipseGrid;
class DeckRecord;
class GridDims;
class GRIDSection;
class FaultCollection {
public:
FaultCollection();
FaultCollection( std::shared_ptr<const GRIDSection> deck, std::shared_ptr<const EclipseGrid> grid);
FaultCollection(const GRIDSection& gridSection, const GridDims& grid);
size_t size() const;
bool hasFault(const std::string& faultName) const;
@ -52,9 +49,12 @@ public:
void setTransMult(const std::string& faultName , double transMult);
private:
void addFaultFaces(const GridDims& grid,
const DeckRecord& faultRecord,
const std::string& faultName);
OrderedMap<Fault> m_faults;
};
}
#endif
#endif // OPM_PARSER_FAULT_COLLECTION_HPP

View File

@ -16,8 +16,8 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FAULT_FACE_HPP_
#define FAULT_FACE_HPP_
#ifndef OPM_PARSER_FAULT_FACE_HPP
#define OPM_PARSER_FAULT_FACE_HPP
#include <cstddef>
#include <vector>
@ -48,4 +48,4 @@ private:
}
#endif
#endif // OPM_PARSER_FAULT_FACE_HPP

View File

@ -0,0 +1,119 @@
/*
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <array>
#include <stdexcept>
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/D.hpp> // DIMENS
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp> // SPECGRID
namespace Opm {
GridDims::GridDims(std::array<int, 3> xyz) :
GridDims(xyz[0], xyz[1], xyz[2])
{
}
GridDims::GridDims(size_t nx, size_t ny, size_t nz) :
m_nx(nx), m_ny(ny), m_nz(nz)
{
}
GridDims::GridDims(const Deck& deck) {
if (deck.hasKeyword("SPECGRID"))
init(deck.getKeyword("SPECGRID"));
else if (deck.hasKeyword("DIMENS"))
init(deck.getKeyword("DIMENS"));
else
throw std::invalid_argument("Must have either SPECGRID or DIMENS to indicate grid dimensions");
}
size_t GridDims::getNX() const {
return m_nx;
}
size_t GridDims::getNY() const {
return m_ny;
}
size_t GridDims::getNZ() const {
return m_nz;
}
const std::array<int, 3> GridDims::getNXYZ() const {
return std::array<int, 3> {int( m_nx ), int( m_ny ), int( m_nz )};
}
size_t GridDims::getGlobalIndex(size_t i, size_t j, size_t k) const {
return (i + j * getNX() + k * getNX() * getNY());
}
const std::array<int, 3> GridDims::getIJK(size_t globalIndex) const {
std::array<int, 3> r = { { 0, 0, 0 } };
int k = globalIndex / (getNX() * getNY());
globalIndex -= k * (getNX() * getNY());
int j = globalIndex / getNX();
globalIndex -= j * getNX();
int i = globalIndex;
r[0] = i;
r[1] = j;
r[2] = k;
return r;
}
size_t GridDims::getCartesianSize() const {
return m_nx * m_ny * m_nz;
}
void GridDims::assertGlobalIndex(size_t globalIndex) const {
if (globalIndex >= getCartesianSize())
throw std::invalid_argument("input index above valid range");
}
void GridDims::assertIJK(size_t i, size_t j, size_t k) const {
if (i >= getNX() || j >= getNY() || k >= getNZ())
throw std::invalid_argument("input index above valid range");
}
GridDims::GridDims() :
m_nx(0), m_ny(0), m_nz(0)
{
}
// keyword must be DIMENS or SPECGRID
inline std::array< int, 3 > readDims(const DeckKeyword& keyword) {
const auto& record = keyword.getRecord(0);
return { { record.getItem("NX").get<int>(0),
record.getItem("NY").get<int>(0),
record.getItem("NZ").get<int>(0) } };
}
void GridDims::init(const DeckKeyword& keyword) {
auto dims = readDims(keyword);
m_nx = dims[0];
m_ny = dims[1];
m_nz = dims[2];
}
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_PARSER_GRIDDIMS_HPP
#define OPM_PARSER_GRIDDIMS_HPP
#include <array>
#include <stdexcept>
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
namespace Opm {
class GridDims
{
public:
GridDims(std::array<int, 3> xyz);
GridDims(size_t nx, size_t ny, size_t nz);
GridDims(const Deck& deck);
size_t getNX() const;
size_t getNY() const;
size_t getNZ() const;
const std::array<int, 3> getNXYZ() const;
size_t getGlobalIndex(size_t i, size_t j, size_t k) const;
const std::array<int, 3> getIJK(size_t globalIndex) const;
size_t getCartesianSize() const;
void assertGlobalIndex(size_t globalIndex) const;
void assertIJK(size_t i, size_t j, size_t k) const;
protected:
GridDims();
size_t m_nx;
size_t m_ny;
size_t m_nz;
private:
void init(const DeckKeyword& keyword);
};
}
#endif /* OPM_PARSER_GRIDDIMS_HPP */

View File

@ -17,12 +17,26 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/Utility/String.hpp>
namespace Opm {
/*
Before lookup the keyword strings are uppercased and trailing
space is trimmed.
*/
static std::string normalize(const std::string& keyword) {
std::string kw(keyword.begin() , std::find( keyword.begin() , keyword.end() , ' '));
uppercase( kw , kw );
return kw;
}
template <>
GridProperties<double>::GridProperties(const EclipseGrid& eclipseGrid,
const UnitSystem* deckUnitSystem,
@ -46,6 +60,7 @@ namespace Opm {
/*
In the case of integer properties we never really do any
transformation, but we have implemented this dummy int
@ -69,7 +84,7 @@ namespace Opm {
template<>
int GridProperties<int>::convertInputValue(double doubleValue) const {
if (fabs( nearbyint( doubleValue ) - doubleValue ) < 1e-6)
if (std::fabs( std::nearbyint( doubleValue ) - doubleValue ) < 1e-6)
return static_cast<int>( doubleValue );
else
throw std::invalid_argument("Expected integer argument - got: " + std::to_string( doubleValue ));
@ -136,17 +151,14 @@ namespace Opm {
}
template< typename T >
bool GridProperties<T>::supportsKeyword(const std::string& keyword) const {
return m_supportedKeywords.count( keyword ) > 0;
return m_supportedKeywords.count( normalize( keyword ) ) > 0;
}
template< typename T >
bool GridProperties<T>::hasKeyword(const std::string& keyword) const {
const std::string kw = uppercase(keyword);
const std::string kw = normalize( keyword );
const auto cnt = m_properties.count( kw );
const bool positive = cnt > 0;
@ -154,20 +166,22 @@ namespace Opm {
return positive && !isAutoGenerated_(kw);
}
template< typename T >
size_t GridProperties<T>::size() const {
return m_property_list.size();
return m_properties.size();
}
template< typename T >
const GridProperty<T>& GridProperties<T>::getKeyword(const std::string& keyword) const {
const std::string kw = uppercase(keyword);
const std::string kw = normalize(keyword);
if (!hasKeyword(kw))
addAutoGeneratedKeyword_(kw);
GridProperty<T>& property = (*m_properties.at( kw ));
GridProperty<T>& property = m_properties.at( kw );
property.runPostProcessor( );
return property;
}
@ -176,9 +190,10 @@ namespace Opm {
template< typename T >
const GridProperty<T>& GridProperties<T>::getInitializedKeyword(const std::string& keyword) const {
const std::string kw = uppercase(keyword);
const std::string kw = normalize(keyword);
if (hasKeyword(kw))
return *m_properties.at( kw );
return m_properties.at( kw );
else {
if (supportsKeyword(kw))
throw std::invalid_argument("Keyword: " + kw + " is supported - but not initialized.");
@ -188,16 +203,27 @@ namespace Opm {
}
template< typename T >
void GridProperties<T>::insertKeyword(const SupportedKeywordInfo& supportedKeyword) const {
int nx = m_eclipseGrid.getNX();
int ny = m_eclipseGrid.getNY();
int nz = m_eclipseGrid.getNZ();
m_properties.emplace( supportedKeyword.getKeywordName() , GridProperty<T>( nx, ny , nz , supportedKeyword ));
}
template< typename T >
bool GridProperties<T>::addKeyword(const std::string& keywordName) {
const std::string kw = uppercase(keywordName);
if (!supportsKeyword( kw ))
throw std::invalid_argument("The keyword: " + kw + " is not supported in this container");
if (!supportsKeyword( keywordName ))
throw std::invalid_argument("The keyword: " + keywordName + " is not supported in this container");
if (hasKeyword(kw))
if (hasKeyword(keywordName))
return false;
else {
const std::string kw = normalize(keywordName);
// if the property was already added auto generated, we just need to make it
// non-auto generated
if (m_autoGeneratedProperties.count(kw)) {
@ -209,14 +235,7 @@ namespace Opm {
return true;
}
auto supportedKeyword = m_supportedKeywords.at( kw );
int nx = m_eclipseGrid.getNX();
int ny = m_eclipseGrid.getNY();
int nz = m_eclipseGrid.getNZ();
std::shared_ptr<GridProperty<T> > newProperty(new GridProperty<T>(nx , ny , nz , supportedKeyword));
m_properties.insert( std::pair<std::string , std::shared_ptr<GridProperty<T> > > ( kw , newProperty ));
m_property_list.push_back( newProperty );
insertKeyword( m_supportedKeywords.at( kw ) );
return true;
}
}
@ -236,12 +255,11 @@ namespace Opm {
template< typename T >
GridProperty<T>& GridProperties<T>::getOrCreateProperty(const std::string name) {
const std::string kw = uppercase(name);
if (!hasKeyword(kw)) {
addKeyword(kw);
}
return getKeyword(kw);
GridProperty<T>& GridProperties<T>::getOrCreateProperty(const std::string& name) {
if (!hasKeyword(name))
addKeyword(name);
return getKeyword(name);
}
/**
@ -321,7 +339,7 @@ namespace Opm {
regionProperty.initMask( regionValue , mask);
targetProperty.maskedSet( targetValue , mask);
} else
throw std::invalid_argument("Fatal error processing EQUALREG keyword - invalid/undefined keyword: " + targetArray);
throw std::invalid_argument("Fatal error processing EQUALREG record - invalid/undefined keyword: " + targetArray);
}
template< typename T >
@ -337,7 +355,7 @@ namespace Opm {
regionProperty.initMask( regionValue , mask);
targetProperty.maskedAdd( shiftValue , mask);
} else
throw std::invalid_argument("Fatal error processing EQUALREG keyword - invalid/undefined keyword: " + targetArray);
throw std::invalid_argument("Fatal error processing ADDREG record - invalid/undefined keyword: " + targetArray);
}
template< typename T >
@ -353,7 +371,7 @@ namespace Opm {
regionProperty.initMask( regionValue , mask);
targetProperty.maskedMultiply( factor , mask);
} else
throw std::invalid_argument("Fatal error processing EQUALREG keyword - invalid/undefined keyword: " + targetArray);
throw std::invalid_argument("Fatal error processing MULTIREG record - invalid/undefined keyword: " + targetArray);
}
template< typename T >
@ -362,10 +380,10 @@ namespace Opm {
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
if (!supportsKeyword( targetArray))
throw std::invalid_argument("Fatal error processing COPYREG keyword - invalid/undefined keyword: " + targetArray);
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + targetArray);
if (!hasKeyword( srcArray ))
throw std::invalid_argument("Fatal error processing COPYREG keyword - invalid/undefined keyword: " + srcArray);
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + srcArray);
{
int regionValue = record.getItem("REGION_NUMBER").get< int >(0);
@ -393,14 +411,18 @@ namespace Opm {
template< typename T >
GridProperty<T>& GridProperties<T>::getKeyword(const std::string& keyword) {
const std::string kw = uppercase(keyword);
const std::string kw = normalize(keyword);
if (!hasKeyword(kw))
addAutoGeneratedKeyword_(kw);
return *m_properties.at( kw );
return m_properties.at( kw );
}
/*
This is const because of the auto-generation of keywords on get().
*/
template< typename T >
bool GridProperties<T>::addAutoGeneratedKeyword_(const std::string& keywordName) const {
if (!supportsKeyword( keywordName ))
@ -409,23 +431,15 @@ namespace Opm {
if (m_properties.count( keywordName ) > 0)
return false; // property already exists (if it is auto generated or not doesn't matter)
else {
auto& supportedKeyword = m_supportedKeywords.at( keywordName );
int nx = m_eclipseGrid.getNX();
int ny = m_eclipseGrid.getNY();
int nz = m_eclipseGrid.getNZ();
std::shared_ptr<GridProperty<T> > newProperty(new GridProperty<T>(nx , ny , nz , supportedKeyword));
m_autoGeneratedProperties.insert(keywordName);
m_properties.insert( std::pair<std::string , std::shared_ptr<GridProperty<T> > > ( keywordName , newProperty ));
m_property_list.push_back( newProperty );
insertKeyword( m_supportedKeywords.at( keywordName ) );
return true;
}
}
template< typename T >
bool GridProperties<T>::isAutoGenerated_(const std::string& keyword) const {
return m_autoGeneratedProperties.count(keyword);
return m_autoGeneratedProperties.count(keyword) > 0;
}
}

View File

@ -58,13 +58,15 @@ namespace Opm {
void setKeywordBox( const DeckRecord& deckRecord,
BoxManager& boxManager);
class Eclipse3DProperties;
template <typename T>
class GridProperties {
public:
typedef typename GridProperty<T>::SupportedKeywordInfo SupportedKeywordInfo;
struct const_iterator;
GridProperties(const EclipseGrid& eclipseGrid,
const UnitSystem* deckUnitSystem,
std::vector< SupportedKeywordInfo >&& supportedKeywords);
@ -75,12 +77,13 @@ namespace Opm {
T convertInputValue( const GridProperty<T>& property , double doubleValue) const;
T convertInputValue( double doubleValue ) const;
bool supportsKeyword(const std::string& keyword) const;
bool hasKeyword(const std::string& keyword) const;
size_t size() const;
const GridProperty<T>& getKeyword(const std::string& keyword) const;
const GridProperty<T>& getInitializedKeyword(const std::string& keyword) const;
bool addKeyword(const std::string& keywordName);
void copyKeyword(const std::string& srcField ,
const std::string& targetField ,
@ -106,7 +109,7 @@ namespace Opm {
return getInitializedKeyword( Keyword::keywordName );
}
GridProperty<T>& getOrCreateProperty(const std::string name);
GridProperty<T>& getOrCreateProperty(const std::string& name);
/**
The fine print of the manual says the ADD keyword should support
@ -124,6 +127,31 @@ namespace Opm {
void handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
/*
Iterators over initialized properties. The overloaded
operator*() opens the pair which comes natively from the
std::map iterator.
*/
const_iterator begin() const {
return const_iterator( m_properties.begin() );
}
const_iterator end() const {
return const_iterator( m_properties.end() );
}
typedef typename std::map<std::string , GridProperty<T> > storage;
typedef typename storage::const_iterator storage_iterator;
struct const_iterator : public storage_iterator {
const_iterator( storage_iterator iter ) : storage_iterator( iter ) { }
const GridProperty<T>& operator*( ) {
const auto& pair = storage_iterator::operator*( );
return pair.second;
}
};
private:
/// this method exists for (friend) Eclipse3DProperties to be allowed initializing PORV and ACTNUM keyword
@ -133,6 +161,7 @@ namespace Opm {
const std::string& dimString );
GridProperty<T>& getKeyword(const std::string& keyword);
bool addAutoGeneratedKeyword_(const std::string& keywordName) const;
void insertKeyword(const SupportedKeywordInfo& supportedKeyword) const;
bool isAutoGenerated_(const std::string& keyword) const;
friend class Eclipse3DProperties; // needed for PORV keyword entanglement
@ -140,10 +169,11 @@ namespace Opm {
const UnitSystem * m_deckUnitSystem = nullptr;
MessageContainer m_messages;
std::unordered_map<std::string, SupportedKeywordInfo> m_supportedKeywords;
mutable std::map<std::string , std::shared_ptr<GridProperty<T> > > m_properties;
mutable storage m_properties;
mutable std::set<std::string> m_autoGeneratedProperties;
mutable std::vector<std::shared_ptr<GridProperty<T> > > m_property_list;
};
}
#endif // ECLIPSE_GRIDPROPERTIES_HPP_

View File

@ -36,32 +36,32 @@ namespace Opm {
template< typename T >
static std::function< std::vector< T >( size_t ) > constant( T val ) {
return [=]( size_t size ) { return std::vector< T >( size, val ); };
};
}
template< typename T >
static std::function< void( std::vector< T >& ) > noop() {
return []( std::vector< T >& ) { return; };
};
}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
std::function< std::vector< T >( size_t ) > initializer,
std::function< void( std::vector< T >& ) > postProcessor,
std::function< std::vector< T >( size_t ) > init,
std::function< void( std::vector< T >& ) > post,
const std::string& dimString ) :
m_keywordName( name ),
m_initializer( initializer ),
m_postProcessor( postProcessor ),
m_initializer( init ),
m_postProcessor( post ),
m_dimensionString( dimString )
{}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
std::function< std::vector< T >( size_t ) > initializer,
std::function< std::vector< T >( size_t ) > init,
const std::string& dimString ) :
m_keywordName( name ),
m_initializer( initializer ),
m_initializer( init ),
m_postProcessor( noop< T >() ),
m_dimensionString( dimString )
{}
@ -81,11 +81,11 @@ namespace Opm {
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
std::function< void( std::vector< T >& ) > postProcessor,
std::function< void( std::vector< T >& ) > post,
const std::string& dimString ) :
m_keywordName( name ),
m_initializer( constant( defaultValue ) ),
m_postProcessor( postProcessor ),
m_postProcessor( post ),
m_dimensionString( dimString )
{}
@ -141,11 +141,7 @@ namespace Opm {
template< typename T >
T GridProperty< T >::iget( size_t index ) const {
if (index < m_data.size()) {
return m_data[index];
} else {
throw std::invalid_argument("Index out of range \n");
}
return this->m_data.at( index );
}
template< typename T >
@ -156,10 +152,7 @@ namespace Opm {
template< typename T >
void GridProperty< T >::iset(size_t index, T value) {
if (index < m_data.size())
m_data[index] = value;
else
throw std::invalid_argument("Index out of range \n");
this->m_data.at( index ) = value;
}
template< typename T >
@ -413,6 +406,48 @@ const std::string& GridProperty<double>::getDimensionString() const {
}
template<typename T>
std::vector<T> GridProperty<T>::compressedCopy(const EclipseGrid& grid) const {
if (grid.allActive())
return m_data;
else {
return grid.compressedVector( m_data );
}
}
template<typename T>
std::vector<size_t> GridProperty<T>::cellsEqual(T value, const std::vector<int>& activeMap) const {
std::vector<size_t> cells;
for (size_t active_index = 0; active_index < activeMap.size(); active_index++) {
size_t global_index = activeMap[ active_index ];
if (m_data[global_index] == value)
cells.push_back( active_index );
}
return cells;
}
template<typename T>
std::vector<size_t> GridProperty<T>::indexEqual(T value) const {
std::vector<size_t> index_list;
for (size_t index = 0; index < m_data.size(); index++) {
if (m_data[index] == value)
index_list.push_back( index );
}
return index_list;
}
template<typename T>
std::vector<size_t> GridProperty<T>::cellsEqual(T value, const EclipseGrid& grid, bool active) const {
if (active)
return cellsEqual( value , grid.getActiveMap());
else
return indexEqual( value );
}
std::vector< double > temperature_lookup( size_t size,
const TableManager* tables,
const EclipseGrid* grid,

View File

@ -147,8 +147,33 @@ public:
assembling the properties.
*/
void runPostProcessor();
/*
Will scan through the roperty and return a vector of all the
indices where the property value agrees with the input value.
*/
std::vector<size_t> indexEqual(T value) const;
/*
Will run through all the cells in the activeMap and return a
list of the elements where the property value agrees with the
input value. The values returned will be in the space
[0,nactive) - i.e. 'active' indices.
*/
std::vector<size_t> cellsEqual(T value , const std::vector<int>& activeMap) const;
/*
If active == true the method will get the activeMap from the
grid and call the cellsEqual( T , std::vector<int>&) overload,
otherwise it will return indexEqual( value );
*/
std::vector<size_t> cellsEqual(T value, const EclipseGrid& grid, bool active = true) const;
/*
Will return a std::vector<T> of the data in the active cells.
*/
std::vector<T> compressedCopy( const EclipseGrid& grid) const;
private:
const DeckItem& getDeckItem( const DeckKeyword& );
void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem);

View File

@ -127,17 +127,16 @@ namespace Opm {
Then it will go through the different regions and looking for
interface with the wanted region values.
*/
MULTREGTScanner::MULTREGTScanner(const Eclipse3DProperties& cellRegionNumbers,
const std::vector< const DeckKeyword* >& keywords,
const std::string& defaultRegion ) :
m_cellRegionNumbers(cellRegionNumbers) {
MULTREGTScanner::MULTREGTScanner(const Eclipse3DProperties& e3DProps,
const std::vector< const DeckKeyword* >& keywords) :
m_e3DProps(e3DProps) {
for (size_t idx = 0; idx < keywords.size(); idx++)
this->addKeyword(*keywords[idx] , defaultRegion);
this->addKeyword(*keywords[idx] , e3DProps.getDefaultRegionKeyword());
MULTREGTSearchMap searchPairs;
for (std::vector<MULTREGTRecord>::const_iterator record = m_records.begin(); record != m_records.end(); ++record) {
if (cellRegionNumbers.hasDeckIntGridProperty( record->m_region.getValue())) {
if (e3DProps.hasDeckIntGridProperty( record->m_region.getValue())) {
if (record->m_srcRegion.hasValue() && record->m_targetRegion.hasValue()) {
int srcRegion = record->m_srcRegion.getValue();
int targetRegion = record->m_targetRegion.getValue();
@ -148,10 +147,12 @@ namespace Opm {
}
}
else
throw std::logic_error("MULTREGT record is based on region: " + record->m_region.getValue() + " which is not in the deck");
throw std::logic_error(
"MULTREGT record is based on region: "
+ record->m_region.getValue()
+ " which is not in the deck");
}
for (auto iter = searchPairs.begin(); iter != searchPairs.end(); ++iter) {
const MULTREGTRecord * record = (*iter).second;
std::pair<int,int> pair = (*iter).first;
@ -161,8 +162,6 @@ namespace Opm {
m_searchMap[keyword][pair] = record;
}
}
@ -235,7 +234,7 @@ namespace Opm {
double MULTREGTScanner::getRegionMultiplier(size_t globalIndex1 , size_t globalIndex2, FaceDir::DirEnum faceDir) const {
for (auto iter = m_searchMap.begin(); iter != m_searchMap.end(); iter++) {
const Opm::GridProperty<int>& region = m_cellRegionNumbers.getIntGridProperty( (*iter).first );
const Opm::GridProperty<int>& region = m_e3DProps.getIntGridProperty( (*iter).first );
MULTREGTSearchMap map = (*iter).second;
int regionId1 = region.iget(globalIndex1);

View File

@ -18,8 +18,8 @@
*/
#ifndef MULTREGTSCANNER_HPP
#define MULTREGTSCANNER_HPP
#ifndef OPM_PARSER_MULTREGTSCANNER_HPP
#define OPM_PARSER_MULTREGTSCANNER_HPP
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
@ -70,9 +70,8 @@ namespace Opm {
class MULTREGTScanner {
public:
MULTREGTScanner(const Eclipse3DProperties& cellRegionNumbers,
const std::vector< const DeckKeyword* >& keywords,
const std::string& defaultRegion);
MULTREGTScanner(const Eclipse3DProperties& e3DProps,
const std::vector< const DeckKeyword* >& keywords);
double getRegionMultiplier(size_t globalCellIdx1, size_t globalCellIdx2, FaceDir::DirEnum faceDir) const;
private:
@ -80,9 +79,9 @@ namespace Opm {
void assertKeywordSupported(const DeckKeyword& deckKeyword, const std::string& defaultRegion);
std::vector< MULTREGTRecord > m_records;
std::map<std::string , MULTREGTSearchMap> m_searchMap;
const Eclipse3DProperties& m_cellRegionNumbers;
const Eclipse3DProperties& m_e3DProps;
};
}
#endif
#endif // OPM_PARSER_MULTREGTSCANNER_HPP

View File

@ -23,6 +23,7 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/N.hpp>
@ -34,23 +35,27 @@ namespace Opm
NNC(*deck, eclipseGrid)
{}
NNC::NNC(const Deck& deck, EclipseGridConstPtr eclipseGrid) {
/// [[deprecated]]
NNC::NNC(const Deck& deck, EclipseGridConstPtr eclipseGrid) :
NNC(deck, *eclipseGrid)
{}
NNC::NNC(const Deck& deck, const GridDims& gridDims) {
const auto& nncs = deck.getKeywordList<ParserKeywords::NNC>();
for (size_t idx_nnc = 0; idx_nnc<nncs.size(); ++idx_nnc) {
const auto& nnc = *nncs[idx_nnc];
size_t numNNC = nnc.size();
for (size_t i = 0; i<numNNC; ++i) {
for (size_t i = 0; i < nnc.size(); ++i) {
std::array<size_t, 3> ijk1;
ijk1[0] = static_cast<size_t>(nnc.getRecord(i).getItem(0).get< int >(0)-1);
ijk1[1] = static_cast<size_t>(nnc.getRecord(i).getItem(1).get< int >(0)-1);
ijk1[2] = static_cast<size_t>(nnc.getRecord(i).getItem(2).get< int >(0)-1);
size_t global_index1 = eclipseGrid->getGlobalIndex(ijk1[0],ijk1[1],ijk1[2]);
size_t global_index1 = gridDims.getGlobalIndex(ijk1[0],ijk1[1],ijk1[2]);
std::array<size_t, 3> ijk2;
ijk2[0] = static_cast<size_t>(nnc.getRecord(i).getItem(3).get< int >(0)-1);
ijk2[1] = static_cast<size_t>(nnc.getRecord(i).getItem(4).get< int >(0)-1);
ijk2[2] = static_cast<size_t>(nnc.getRecord(i).getItem(5).get< int >(0)-1);
size_t global_index2 = eclipseGrid->getGlobalIndex(ijk2[0],ijk2[1],ijk2[2]);
size_t global_index2 = gridDims.getGlobalIndex(ijk2[0],ijk2[1],ijk2[2]);
const double trans = nnc.getRecord(i).getItem(6).getSIDouble(0);
@ -65,11 +70,11 @@ namespace Opm
void NNC::addNNC(const size_t cell1, const size_t cell2, const double trans) {
NNCdata nncdata;
nncdata.cell1 = cell1;
nncdata.cell2 = cell2;
nncdata.trans = trans;
m_nnc.push_back(nncdata);
NNCdata tmp;
tmp.cell1 = cell1;
tmp.cell2 = cell2;
tmp.trans = trans;
m_nnc.push_back(tmp);
}
size_t NNC::numNNC() const {

View File

@ -22,6 +22,7 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <cstddef>
#include <memory>
@ -46,8 +47,11 @@ public:
/// [[deprecated]]
NNC(std::shared_ptr<const Deck> deck_ptr, std::shared_ptr< const EclipseGrid > eclipseGrid);
/// Construct from input deck.
/// [[deprecated]]
NNC(const Deck& deck, std::shared_ptr< const EclipseGrid > eclipseGrid);
/// Construct from input deck.
NNC(const Deck& deck, const GridDims& gridDims);
void addNNC(const size_t cell1, const size_t cell2, const double trans);
const std::vector<NNCdata>& nncdata() const { return m_nnc; }
size_t numNNC() const;

View File

@ -707,10 +707,11 @@ namespace Opm {
const bool useEnptvd = tableManager->useEnptvd();
const auto& enptvdTables = tableManager->getEnptvdTables();
for( size_t cellIdx = 0; cellIdx < eclipseGrid->getCartesianSize(); cellIdx++ ) {
const auto gridsize = eclipseGrid->getCartesianSize();
for( size_t cellIdx = 0; cellIdx < gridsize; cellIdx++ ) {
int satTableIdx = satnum.iget( cellIdx ) - 1;
int endNum = endnum.iget( cellIdx ) - 1;
double cellDepth = std::get< 2 >( eclipseGrid->getCellCenter( cellIdx ) );
double cellDepth = eclipseGrid->getCellDepth( cellIdx );
values[cellIdx] = selectValue(enptvdTables,
@ -748,10 +749,11 @@ namespace Opm {
// assign a NaN in this case...
const bool useImptvd = tableManager->useImptvd();
const TableContainer& imptvdTables = tableManager->getImptvdTables();
for( size_t cellIdx = 0; cellIdx < eclipseGrid->getCartesianSize(); cellIdx++ ) {
const auto gridsize = eclipseGrid->getCartesianSize();
for( size_t cellIdx = 0; cellIdx < gridsize; cellIdx++ ) {
int imbTableIdx = imbnum.iget( cellIdx ) - 1;
int endNum = endnum.iget( cellIdx ) - 1;
double cellDepth = std::get< 2 >( eclipseGrid->getCellCenter( cellIdx ) );
double cellDepth = eclipseGrid->getCellDepth( cellIdx );
values[cellIdx] = selectValue(imptvdTables,
(useImptvd && endNum >= 0) ? endNum : -1,

View File

@ -16,16 +16,17 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <stdexcept>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
namespace Opm {
TransMult::TransMult(size_t nx , size_t ny , size_t nz) :
@ -78,7 +79,9 @@ namespace Opm {
}
double TransMult::getRegionMultiplier(size_t globalCellIndex1, size_t globalCellIndex2, FaceDir::DirEnum faceDir) const {
return m_multregtScanner->getRegionMultiplier(globalCellIndex1, globalCellIndex2, faceDir);
if (m_multregtScanner == nullptr)
throw new std::logic_error("MULTREGTScanner has not been initialized.");
return m_multregtScanner->getRegionMultiplier(globalCellIndex1, globalCellIndex2, faceDir);
}
bool TransMult::hasDirectionProperty(FaceDir::DirEnum faceDir) const {
@ -134,7 +137,8 @@ namespace Opm {
void TransMult::setMultregtScanner( std::shared_ptr<const MULTREGTScanner> multregtScanner) {
m_multregtScanner = multregtScanner;
void TransMult::createMultregtScanner(const Eclipse3DProperties& e3DProps,
std::vector< const DeckKeyword* > multregtKeywords) {
m_multregtScanner = new MULTREGTScanner(e3DProps, multregtKeywords);
}
}

View File

@ -26,8 +26,8 @@
{MULTX , MULTX- , MULTY , MULTY- , MULTZ , MULTZ-, MULTFLT , MULTREGT}
*/
#ifndef TRANSMULT_HPP
#define TRANSMULT_HPP
#ifndef OPM_PARSER_TRANSMULT_HPP
#define OPM_PARSER_TRANSMULT_HPP
#include <cstddef>
@ -35,13 +35,12 @@
#include <memory>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
namespace Opm {
template< typename > class GridProperty;
class Fault;
class FaultCollection;
class MULTREGTScanner;
class TransMult {
@ -53,7 +52,8 @@ namespace Opm {
void applyMULT(const GridProperty<double>& srcMultProp, FaceDir::DirEnum faceDir);
void applyMULTFLT(const FaultCollection& faults);
void applyMULTFLT(const Fault& fault);
void setMultregtScanner(std::shared_ptr<const MULTREGTScanner> multregtScanner);
void createMultregtScanner(const Eclipse3DProperties& e3DProps,
std::vector<const DeckKeyword*> multregtKeywords);
private:
size_t getGlobalIndex(size_t i , size_t j , size_t k) const;
@ -66,9 +66,9 @@ namespace Opm {
size_t m_nx , m_ny , m_nz;
std::map<FaceDir::DirEnum , GridProperty<double> > m_trans;
std::map<FaceDir::DirEnum , std::string> m_names;
std::shared_ptr<const MULTREGTScanner> m_multregtScanner;
MULTREGTScanner* m_multregtScanner = nullptr;
};
}
#endif
#endif // OPM_PARSER_TRANSMULT_HPP

View File

@ -149,6 +149,14 @@ static Opm::DeckPtr createValidIntDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
@ -180,6 +188,14 @@ static Opm::DeckPtr createValidPERMXDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
@ -218,31 +234,31 @@ static Opm::DeckPtr createValidPERMXDeck() {
BOOST_AUTO_TEST_CASE(InvalidArrayThrows) {
Opm::DeckPtr deck = createDeckInvalidArray();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(InvalidRegionThrows) {
Opm::DeckPtr deck = createDeckInvalidRegion();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(ExpectedIntThrows) {
Opm::DeckPtr deck = createDeckInvalidValue();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(UnInitializedRegionThrows) {
Opm::DeckPtr deck = createDeckUnInitializedRegion();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
Opm::DeckPtr deck = createDeckUnInitializedVector();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}

View File

@ -23,11 +23,9 @@
#define BOOST_TEST_MODULE BoxManagereTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>

View File

@ -149,6 +149,14 @@ static Opm::DeckPtr createValidIntDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
@ -175,19 +183,19 @@ static Opm::DeckPtr createValidIntDeck() {
BOOST_AUTO_TEST_CASE(InvalidArrayThrows1) {
Opm::DeckPtr deck = createDeckInvalidArray1();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(InvalidArrayThrows2) {
Opm::DeckPtr deck = createDeckInvalidArray2();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(InvalidRegionThrows) {
Opm::DeckPtr deck = createDeckInvalidRegion();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
@ -195,13 +203,13 @@ BOOST_AUTO_TEST_CASE(InvalidRegionThrows) {
BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
Opm::DeckPtr deck = createDeckUnInitialized();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(TypeMismatchThrows) {
Opm::DeckPtr deck = createDeckInvalidTypeMismatch();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}

View File

@ -23,22 +23,21 @@
#include <cstdio>
#define BOOST_TEST_MODULE EclipseGridTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
BOOST_AUTO_TEST_CASE(CreateMissingDIMENS_throws) {
@ -50,8 +49,6 @@ BOOST_AUTO_TEST_CASE(CreateMissingDIMENS_throws) {
BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument);
}
static Opm::DeckPtr createDeckHeaders() {
const char *deckData =
"RUNSPEC\n"
@ -66,6 +63,35 @@ static Opm::DeckPtr createDeckHeaders() {
return parser->parseString(deckData, Opm::ParseContext());
}
static Opm::DeckPtr createDeckDIMENS() {
const char *deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 13 17 19/\n"
"GRID\n"
"EDIT\n"
"\n";
Opm::ParserPtr parser(new Opm::Parser());
return parser->parseString(deckData, Opm::ParseContext());
}
static Opm::DeckPtr createDeckSPECGRID() {
const char *deckData =
"GRID\n"
"SPECGRID \n"
" 13 17 19 / \n"
"COORD\n"
" 726*1 / \n"
"ZCORN \n"
" 8000*1 / \n"
"ACTNUM \n"
" 1000*1 / \n"
"EDIT\n"
"\n";
Opm::ParserPtr parser(new Opm::Parser());
return parser->parseString(deckData, Opm::ParseContext());
}
static Opm::DeckPtr createDeckMissingDIMS() {
const char *deckData =
@ -93,8 +119,14 @@ BOOST_AUTO_TEST_CASE(HasGridKeywords) {
BOOST_AUTO_TEST_CASE(CreateGridNoCells) {
Opm::DeckPtr deck = createDeckHeaders();
Opm::EclipseGrid grid( deck );
Opm::DeckPtr deckptr = createDeckHeaders();
const Opm::Deck& deck = *deckptr;
{
Opm::EclipseGrid* gridptr = nullptr;
BOOST_CHECK_THROW( gridptr = new Opm::EclipseGrid( deck ) , std::invalid_argument);
delete gridptr;
}
const Opm::GridDims grid(deck);
BOOST_CHECK_EQUAL( 10 , grid.getNX());
BOOST_CHECK_EQUAL( 10 , grid.getNY());
BOOST_CHECK_EQUAL( 10 , grid.getNZ());
@ -318,8 +350,6 @@ BOOST_AUTO_TEST_CASE(CREATE_SIMPLE) {
BOOST_CHECK_EQUAL( grid.getNY() , 20 );
BOOST_CHECK_EQUAL( grid.getNZ() , 30 );
BOOST_CHECK_EQUAL( grid.getCartesianSize() , 6000 );
BOOST_CHECK_EQUAL( true , grid.hasCellInfo() );
}
BOOST_AUTO_TEST_CASE(DEPTHZ_EQUAL_TOPS) {
@ -399,9 +429,13 @@ BOOST_AUTO_TEST_CASE(HasINVALIDCartKeywords) {
BOOST_AUTO_TEST_CASE(CreateMissingGRID_throws) {
Opm::DeckPtr deck = createDeckHeaders();
Opm::EclipseGrid grid( deck );
BOOST_CHECK_EQUAL( false , grid.hasCellInfo() );
auto deckptr = createDeckHeaders();
const Opm::Deck& deck = *deckptr;
{
Opm::EclipseGrid* gridptr = nullptr;
BOOST_CHECK_THROW( gridptr = new Opm::EclipseGrid( deck ) , std::invalid_argument);
delete gridptr;
}
}
@ -430,7 +464,8 @@ static Opm::DeckPtr createInvalidDXYZCARTDeck() {
BOOST_AUTO_TEST_CASE(CreateCartesianGRID) {
Opm::DeckPtr deck = createInvalidDXYZCARTDeck();
auto deckptr = createInvalidDXYZCARTDeck();
const Opm::Deck& deck = *deckptr;
BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument);
}
@ -460,9 +495,13 @@ static Opm::DeckPtr createInvalidDXYZCARTDeckDEPTHZ() {
BOOST_AUTO_TEST_CASE(CreateCartesianGRIDDEPTHZ) {
Opm::DeckPtr deck = createInvalidDXYZCARTDeckDEPTHZ();
Opm::EclipseGrid grid( deck );
BOOST_CHECK_EQUAL( false , grid.hasCellInfo() );
auto deckptr = createInvalidDXYZCARTDeckDEPTHZ();
const Opm::Deck& deck = *deckptr;
{
Opm::EclipseGrid* gridptr = nullptr;
BOOST_CHECK_THROW( gridptr = new Opm::EclipseGrid( deck ) , std::invalid_argument);
delete gridptr;
}
}
@ -513,8 +552,14 @@ static Opm::DeckPtr createInvalidDEPTHZDeck1 () {
BOOST_AUTO_TEST_CASE(CreateCartesianGRIDInvalidDEPTHZ1) {
Opm::DeckPtr deck = createInvalidDEPTHZDeck1();
BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument);
auto deckptr = createInvalidDEPTHZDeck1();
const Opm::Deck& deck = *deckptr;
{
Opm::EclipseGrid* gridptr = nullptr;
BOOST_CHECK_THROW( gridptr = new Opm::EclipseGrid( deck ) , std::invalid_argument);
delete gridptr;
}
}
@ -541,20 +586,26 @@ static Opm::DeckPtr createInvalidDEPTHZDeck2 () {
}
BOOST_AUTO_TEST_CASE(CreateCartesianGRIDInvalidDEPTHZ2) {
Opm::DeckPtr deck = createInvalidDEPTHZDeck2();
BOOST_CHECK_THROW(new Opm::EclipseGrid( deck ) , std::invalid_argument);
auto deckptr = createInvalidDEPTHZDeck2();
const Opm::Deck& deck = *deckptr;
{
Opm::EclipseGrid* gridptr = nullptr;
BOOST_CHECK_THROW( gridptr = new Opm::EclipseGrid( deck ) , std::invalid_argument);
delete gridptr;
}
}
BOOST_AUTO_TEST_CASE(CreateCartesianGRIDOnlyTopLayerDZ) {
Opm::DeckPtr deck = createOnlyTopDZCartGrid();
std::shared_ptr<Opm::EclipseGrid> grid(new Opm::EclipseGrid( deck ));
Opm::EclipseGrid grid( *deck );
BOOST_CHECK_EQUAL( 10 , grid->getNX( ));
BOOST_CHECK_EQUAL( 5 , grid->getNY( ));
BOOST_CHECK_EQUAL( 20 , grid->getNZ( ));
BOOST_CHECK_EQUAL( 1000 , grid->getNumActive());
BOOST_CHECK_EQUAL( 10 , grid.getNX( ));
BOOST_CHECK_EQUAL( 5 , grid.getNY( ));
BOOST_CHECK_EQUAL( 20 , grid.getNZ( ));
BOOST_CHECK_EQUAL( 1000 , grid.getNumActive());
}
@ -640,11 +691,42 @@ BOOST_AUTO_TEST_CASE(ResetACTNUM) {
BOOST_CHECK_EQUAL( 1000U , grid.getNumActive());
std::vector<int> actnum(1000);
actnum[0] = 1;
actnum[2] = 1;
actnum[4] = 1;
actnum[6] = 1;
grid.resetACTNUM( actnum.data() );
BOOST_CHECK_EQUAL( 1U , grid.getNumActive() );
BOOST_CHECK_EQUAL( 4U , grid.getNumActive() );
{
std::vector<int> full(grid.getCartesianSize());
std::iota(full.begin(), full.end(), 0);
auto compressed = grid.compressedVector( full );
BOOST_CHECK_EQUAL( compressed.size() , 4U );
BOOST_CHECK_EQUAL( compressed[0] , 0 );
BOOST_CHECK_EQUAL( compressed[1] , 2 );
BOOST_CHECK_EQUAL( compressed[2] , 4 );
BOOST_CHECK_EQUAL( compressed[3] , 6 );
}
{
const auto& activeMap = grid.getActiveMap( );
BOOST_CHECK_EQUAL( 4U , activeMap.size() );
BOOST_CHECK_EQUAL( 0 , activeMap[0] );
BOOST_CHECK_EQUAL( 2 , activeMap[1] );
BOOST_CHECK_EQUAL( 4 , activeMap[2] );
BOOST_CHECK_EQUAL( 6 , activeMap[3] );
}
grid.resetACTNUM( NULL );
BOOST_CHECK_EQUAL( 1000U , grid.getNumActive() );
{
const auto& activeMap = grid.getActiveMap( );
BOOST_CHECK_EQUAL( 1000U , activeMap.size() );
BOOST_CHECK_EQUAL( 0 , activeMap[0] );
BOOST_CHECK_EQUAL( 1 , activeMap[1] );
BOOST_CHECK_EQUAL( 2 , activeMap[2] );
BOOST_CHECK_EQUAL( 999 , activeMap[999] );
}
}
@ -699,32 +781,6 @@ BOOST_AUTO_TEST_CASE(LoadFromBinary) {
BOOST_AUTO_TEST_CASE(Fwrite) {
const char *deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"COORD\n"
" 726*1 / \n"
"ZCORN \n"
" 8000*1 / \n"
"EDIT\n"
"\n";
Opm::ParserPtr parser(new Opm::Parser());
Opm::DeckConstPtr deck = parser->parseString(deckData, Opm::ParseContext()) ;
Opm::EclipseGrid grid1(deck );
grid1.fwriteEGRID( "TEST.EGRID" , true);
Opm::EclipseGrid grid2( "TEST.EGRID" );
BOOST_CHECK( grid1.equal( grid2 ));
remove("TEST.EGRID");
}
@ -884,7 +940,7 @@ static Opm::DeckPtr createActnumBoxDeck() {
BOOST_AUTO_TEST_CASE(GridBoxActnum) {
Opm::DeckConstPtr deck = createActnumBoxDeck();
Opm::EclipseState es(deck, Opm::ParseContext());
Opm::EclipseState es(*deck, Opm::ParseContext());
auto ep = es.get3DProperties();
auto grid = es.getInputGrid();
@ -935,26 +991,111 @@ BOOST_AUTO_TEST_CASE(GridBoxActnum) {
BOOST_AUTO_TEST_CASE(GridActnumVia3D) {
Opm::DeckConstPtr deck = createActnumDeck();
Opm::EclipseState es(deck, Opm::ParseContext());
Opm::EclipseState es(*deck, Opm::ParseContext());
auto ep = es.get3DProperties();
auto grid = es.getInputGrid();
Opm::EclipseGrid grid2( *grid );
BOOST_CHECK_NO_THROW(ep.getIntGridProperty("ACTNUM"));
BOOST_CHECK_NO_THROW(grid->getNumActive());
BOOST_CHECK(grid->hasCellInfo());
BOOST_CHECK_EQUAL(grid->getNumActive(), 2 * 2 * 2 - 1);
BOOST_CHECK_NO_THROW(grid2.getNumActive());
BOOST_CHECK(grid2.hasCellInfo());
BOOST_CHECK_EQUAL(grid2.getNumActive(), 2 * 2 * 2 - 1);
}
BOOST_AUTO_TEST_CASE(GridActnumViaState) {
Opm::DeckConstPtr deck = createActnumDeck();
BOOST_CHECK_NO_THROW(Opm::EclipseState(deck, Opm::ParseContext()));
Opm::EclipseState es(deck, Opm::ParseContext());
BOOST_CHECK(es.getInputGrid()->hasCellInfo());
BOOST_CHECK_NO_THROW(Opm::EclipseState(*deck, Opm::ParseContext()));
Opm::EclipseState es(*deck, Opm::ParseContext());
BOOST_CHECK_EQUAL(es.getInputGrid()->getNumActive(), 2 * 2 * 2 - 1);
}
BOOST_AUTO_TEST_CASE(GridDimsSPECGRID) {
auto deckptr = createDeckSPECGRID();
auto gd = Opm::GridDims(*deckptr);
BOOST_CHECK_EQUAL(gd.getNX(), 13);
BOOST_CHECK_EQUAL(gd.getNY(), 17);
BOOST_CHECK_EQUAL(gd.getNZ(), 19);
}
BOOST_AUTO_TEST_CASE(GridDimsDIMENS) {
auto deckptr = createDeckDIMENS();
auto gd = Opm::GridDims(*deckptr);
BOOST_CHECK_EQUAL(gd.getNX(), 13);
BOOST_CHECK_EQUAL(gd.getNY(), 17);
BOOST_CHECK_EQUAL(gd.getNZ(), 19);
}
BOOST_AUTO_TEST_CASE(ProcessedCopy) {
Opm::EclipseGrid gd(10,10,10);
std::vector<double> zcorn;
std::vector<int> actnum;
gd.exportZCORN( zcorn );
gd.exportACTNUM( actnum );
{
Opm::EclipseGrid gd2(gd , zcorn , actnum );
BOOST_CHECK( gd.equal( gd2 ));
}
zcorn[0] -= 1;
{
Opm::EclipseGrid gd2(gd , zcorn , actnum );
BOOST_CHECK( !gd.equal( gd2 ));
}
{
Opm::EclipseGrid gd2(gd , actnum );
BOOST_CHECK( gd.equal( gd2 ));
}
actnum.assign( gd.getCartesianSize() , 1);
actnum[0] = 0;
{
Opm::EclipseGrid gd2(gd , actnum );
BOOST_CHECK( !gd.equal( gd2 ));
BOOST_CHECK( !gd2.cellActive( 0 ));
}
}
BOOST_AUTO_TEST_CASE(ZcornMapper) {
int nx = 3;
int ny = 4;
int nz = 5;
Opm::EclipseGrid grid(nx,ny,nz);
Opm::ZcornMapper zmp = grid.zcornMapper( );
const ecl_grid_type * ert_grid = grid.c_ptr();
BOOST_CHECK_THROW(zmp.index(nx,1,1,0) , std::invalid_argument);
BOOST_CHECK_THROW(zmp.index(0,ny,1,0) , std::invalid_argument);
BOOST_CHECK_THROW(zmp.index(0,1,nz,0) , std::invalid_argument);
BOOST_CHECK_THROW(zmp.index(0,1,2,8) , std::invalid_argument);
for (int k=0; k < nz; k++)
for (int j=0; j < ny; j++)
for (int i=0; i < nx; i++)
for (int c=0; c < 8; c++) {
size_t g = i + j*nx + k*nx*ny;
BOOST_CHECK_EQUAL( zmp.index(g , c) , zmp.index( i,j,k,c));
BOOST_CHECK_EQUAL( zmp.index(i,j,k,c) , ecl_grid_zcorn_index( ert_grid, i , j , k, c));
}
}
BOOST_AUTO_TEST_CASE(MoveTest) {
int nx = 3;
int ny = 4;
int nz = 5;
Opm::EclipseGrid grid1(nx,ny,nz);
Opm::EclipseGrid grid2( std::move( grid1 )); // grid2 should be move constructed from grid1
BOOST_CHECK( !grid1.c_ptr() ); // We peek at some internal details ...
}

View File

@ -123,6 +123,14 @@ static Opm::DeckPtr createValidIntDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"FLUXNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
@ -158,6 +166,14 @@ static Opm::DeckPtr createValidPERMXDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
@ -195,23 +211,23 @@ static Opm::DeckPtr createValidPERMXDeck() {
BOOST_AUTO_TEST_CASE(InvalidArrayThrows) {
Opm::DeckPtr deck = createDeckInvalidArray();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(InvalidRegionThrows) {
Opm::DeckPtr deck = createDeckInvalidRegion();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(ExpectedIntThrows) {
Opm::DeckPtr deck = createDeckInvalidValue();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
Opm::DeckPtr deck = createDeckUnInitialized();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {

View File

@ -22,11 +22,9 @@
#define BOOST_TEST_MODULE FaultTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>

View File

@ -22,11 +22,9 @@
#define BOOST_TEST_MODULE EclipseGridTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Parser/Parser.hpp>

View File

@ -23,11 +23,9 @@
#define BOOST_TEST_MODULE EclipseGridTests
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@ -260,6 +258,8 @@ BOOST_AUTO_TEST_CASE(GridPropertyInitialization) {
"\n"
"GRID\n"
"\n"
"ACTNUM\n"
" 0 8*1 0 8*1 0 8*1 /\n"
"DXV\n"
"1 1 1 /\n"
"\n"
@ -382,10 +382,62 @@ BOOST_AUTO_TEST_CASE(GridPropertyInitialization) {
BOOST_CHECK_EQUAL(sguPropData[0 * 3*3], 0.9);
BOOST_CHECK_EQUAL(sguPropData[1 * 3*3], 0.85);
BOOST_CHECK_EQUAL(sguPropData[2 * 3*3], 0.80);
const auto& satnum = props.getIntGridProperty("SATNUM");
{
const auto& activeMap = eg.getActiveMap();
const auto cells1 = satnum.cellsEqual(1 , activeMap);
const auto cells2 = satnum.cellsEqual(2 , activeMap);
const auto cells3 = satnum.cellsEqual(3 , activeMap);
BOOST_CHECK_EQUAL( cells1.size() , 8 );
BOOST_CHECK_EQUAL( cells2.size() , 8 );
BOOST_CHECK_EQUAL( cells3.size() , 8 );
for (size_t i = 0; i < 8; i++) {
BOOST_CHECK_EQUAL( cells1[i] , i );
BOOST_CHECK_EQUAL( cells2[i] , i + 8);
BOOST_CHECK_EQUAL( cells3[i] , i + 16);
}
}
{
const auto cells1 = satnum.indexEqual(1 );
const auto cells2 = satnum.indexEqual(2 );
const auto cells3 = satnum.indexEqual(3 );
BOOST_CHECK_EQUAL( cells1.size() , 9 );
BOOST_CHECK_EQUAL( cells2.size() , 9 );
BOOST_CHECK_EQUAL( cells3.size() , 9 );
for (size_t i = 0; i < 9; i++) {
BOOST_CHECK_EQUAL( cells1[i] , i );
BOOST_CHECK_EQUAL( cells2[i] , i + 9);
BOOST_CHECK_EQUAL( cells3[i] , i + 18);
}
}
{
const auto cells3_a = satnum.cellsEqual(3 , eg);
const auto cells3_g = satnum.cellsEqual(3 , eg , false);
for (size_t i = 0; i < 8; i++) {
BOOST_CHECK_EQUAL( cells3_a[i] , i + 16);
BOOST_CHECK_EQUAL( cells3_g[i] , i + 18);
}
BOOST_CHECK_EQUAL( cells3_g[8] , 26);
}
const auto compressedSatnum = satnum.compressedCopy( eg );
BOOST_CHECK_EQUAL( compressedSatnum.size() , eg.getNumActive());
for (size_t i=0; i < eg.getNumActive(); i++) {
size_t g = eg.getGlobalIndex( i );
BOOST_CHECK_EQUAL( compressedSatnum[i] , satnum.getData()[g]);
}
}
void TestPostProcessorMul(std::vector< double >& values,
inline void TestPostProcessorMul(std::vector< double >& values,
const Opm::TableManager*,
const Opm::EclipseGrid*,
Opm::GridProperties<int>*,

View File

@ -73,6 +73,14 @@ static Opm::DeckPtr createInvalidMULTREGTDeck() {
"DIMENS\n"
" 3 3 2 /\n"
"GRID\n"
"DX\n"
"18*0.25 /\n"
"DY\n"
"18*0.25 /\n"
"DZ\n"
"18*0.25 /\n"
"TOPS\n"
"9*0.25 /\n"
"FLUXNUM\n"
"1 1 2\n"
"1 1 2\n"
@ -110,19 +118,19 @@ BOOST_AUTO_TEST_CASE(InvalidInput) {
std::vector<const Opm::DeckKeyword*> keywords0;
const auto& multregtKeyword0 = deck->getKeyword( "MULTREGT", 0 );
keywords0.push_back( &multregtKeyword0 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords0, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords0 ); , std::invalid_argument );
// Not supported region
std::vector<const Opm::DeckKeyword*> keywords1;
const auto& multregtKeyword1 = deck->getKeyword( "MULTREGT", 1 );
keywords1.push_back( &multregtKeyword1 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords1, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords1 ); , std::invalid_argument );
// The keyword is ok; but it refers to a region which is not in the deck.
std::vector<const Opm::DeckKeyword*> keywords2;
const auto& multregtKeyword2 = deck->getKeyword( "MULTREGT", 2 );
keywords2.push_back( &multregtKeyword2 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords2, "MULTNUM" ); , std::logic_error );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords2 ); , std::logic_error );
}
@ -133,6 +141,14 @@ static Opm::DeckPtr createNotSupportedMULTREGTDeck() {
"DIMENS\n"
" 3 3 2 /\n"
"GRID\n"
"DX\n"
"18*0.25 /\n"
"DY\n"
"18*0.25 /\n"
"DZ\n"
"18*0.25 /\n"
"TOPS\n"
"9*0.25 /\n"
"FLUXNUM\n"
"1 1 2\n"
"1 1 2\n"
@ -175,26 +191,26 @@ BOOST_AUTO_TEST_CASE(NotSupported) {
std::vector<const Opm::DeckKeyword*> keywords0;
const auto& multregtKeyword0 = deck->getKeyword( "MULTREGT", 0 );
keywords0.push_back( &multregtKeyword0 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords0, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords0 ); , std::invalid_argument );
// Defaulted from value - not supported
std::vector<const Opm::DeckKeyword*> keywords1;
const auto& multregtKeyword1 = deck->getKeyword( "MULTREGT", 1 );
keywords1.push_back( &multregtKeyword1 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords1, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords1 ); , std::invalid_argument );
// Defaulted to value - not supported
std::vector<const Opm::DeckKeyword*> keywords2;
const auto& multregtKeyword2 = deck->getKeyword( "MULTREGT", 2 );
keywords2.push_back( &multregtKeyword2 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords2, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords2 ); , std::invalid_argument );
// srcValue == targetValue - not supported
std::vector<const Opm::DeckKeyword*> keywords3;
const Opm::DeckKeyword& multregtKeyword3 = deck->getKeyword( "MULTREGT", 3 );
keywords3.push_back( &multregtKeyword3 );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords3, "MULTNUM" ); , std::invalid_argument );
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner( props, keywords3 ); , std::invalid_argument );
}
static Opm::DeckPtr createCopyMULTNUMDeck() {
@ -204,6 +220,14 @@ static Opm::DeckPtr createCopyMULTNUMDeck() {
"DIMENS\n"
"2 2 2 /\n"
"GRID\n"
"DX\n"
"8*0.25 /\n"
"DY\n"
"8*0.25 /\n"
"DZ\n"
"8*0.25 /\n"
"TOPS\n"
"4*0.25 /\n"
"FLUXNUM\n"
"1 2\n"
"1 2\n"

View File

@ -146,6 +146,14 @@ static Opm::DeckPtr createValidIntDeck() {
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"REGIONS\n"
"SATNUM \n"
"1 1 2 2 2\n"
@ -179,29 +187,29 @@ static Opm::DeckPtr createValidIntDeck() {
BOOST_AUTO_TEST_CASE(InvalidArrayThrows) {
Opm::DeckPtr deck = createDeckInvalidArray();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(InvalidRegionThrows) {
Opm::DeckPtr deck = createDeckInvalidRegion();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(ExpectedIntThrows) {
Opm::DeckPtr deck = createDeckInvalidValue();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(MissingRegionVectorThrows) {
Opm::DeckPtr deck = createDeckMissingVector();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
Opm::DeckPtr deck = createDeckUnInitialized();
BOOST_CHECK_THROW( new Opm::EclipseState( deck, Opm::ParseContext()) , std::invalid_argument );
BOOST_CHECK_THROW( new Opm::EclipseState( *deck, Opm::ParseContext()) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {

View File

@ -228,6 +228,39 @@ static Opm::DeckPtr createDeckWithNTG() {
return parser->parseString(deckData, Opm::ParseContext()) ;
}
static Opm::DeckPtr createDeckWithMULTREGP() {
const char *deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORV\n"
"1000*77 /\n"
"MULTNUM\n"
"100*1 700*2 200*3 / \n"
"FLUXNUM\n"
"200*1 700*2 100*3 / \n"
"MULTREGP\n"
"1 10.0 / \n"
"1 2.0 F/ \n"
"0 123.0 F/ \n" // ignored
"2 20.0 M / \n"
"/\n"
"\n";
Opm::ParserPtr parser(new Opm::Parser());
return parser->parseString(deckData, Opm::ParseContext()) ;
}
BOOST_AUTO_TEST_CASE(PORV_cartesianDeck) {
/* Check that an exception is raised if we try to create a PORV field without PORO. */
Opm::DeckPtr deck = createCARTDeck();
@ -324,6 +357,29 @@ BOOST_AUTO_TEST_CASE(PORV_multpvAndNtg) {
BOOST_CHECK_CLOSE( cell_volume * poro*multpv*NTG , porv.iget(9,9,9) , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_multregp) {
Opm::DeckPtr deck = createDeckWithMULTREGP();
const auto props = getProps(deck);
const auto& porv = props.getDoubleGridProperty("PORV");
const auto& porvData = porv.getData();
double basePorv = 77.0;
// the cumlative effect of the base pore volume is multiplied 2 for the cells in
// region 1 of FLUXNUM and by 20 for region 2 of MULTNUM. This means that the first
// 100 cels are multiplied by 2, then follow 100 cells multiplied by 2*20, then
// 600 cells multiplied by 20 while the last 200 cells are not modified at all.
for (int i=0; i < 100; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*2, 1e-8);
for (int i=100; i < 200; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*2*20, 1e-8);
for (int i=200; i < 800; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*20, 1e-8);
for (int i=800; i < 1000; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv, 1e-8);
}
static Opm::DeckPtr createDeckNakedGRID() {
@ -346,8 +402,7 @@ static Opm::DeckPtr createDeckNakedGRID() {
BOOST_AUTO_TEST_CASE(NAKED_GRID_THROWS) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work and NTG */
Opm::DeckPtr deck = createDeckNakedGRID();
const auto props = getProps(deck);
BOOST_CHECK_THROW( props.getDoubleGridProperty("PORV") , std::invalid_argument );
BOOST_CHECK_THROW( getProps(deck) , std::invalid_argument );
}
static Opm::DeckPtr createDeckWithPOROZero() {
@ -386,7 +441,7 @@ static Opm::DeckPtr createDeckWithPOROZero() {
BOOST_AUTO_TEST_CASE(PORO_ZERO_ACTNUM_CORRECT) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work and NTG */
Opm::DeckPtr deck = createDeckWithPOROZero();
Opm::EclipseState state( deck , Opm::ParseContext());
Opm::EclipseState state( *deck , Opm::ParseContext());
auto grid = state.getInputGrid( );
/* Top layer is active */

View File

@ -34,14 +34,16 @@
using namespace Opm;
void check_property(const Eclipse3DProperties& props1, const Eclipse3DProperties& props2, const std::string& propertyName) {
inline void check_property(const Eclipse3DProperties& props1,
const Eclipse3DProperties& props2,
const std::string& propertyName) {
auto& data1 = props1.getDoubleGridProperty(propertyName).getData();
auto& data2 = props2.getDoubleGridProperty(propertyName).getData();
BOOST_CHECK_CLOSE(data1[0], data2[0], 1e-12);
}
static Opm::Eclipse3DProperties getProps(Opm::DeckPtr deck) {
inline Opm::Eclipse3DProperties getProps(Opm::DeckPtr deck) {
return Opm::Eclipse3DProperties(*deck, *new Opm::TableManager(*deck), *new Opm::EclipseGrid(deck));
}

View File

@ -28,7 +28,6 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Deck/SCHEDULESection.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
@ -54,182 +53,14 @@ namespace Opm {
return dir;
}
inline bool is_int( const std::string& x ) {
auto is_digit = []( char c ) { return std::isdigit( c ); };
return !x.empty()
&& ( x.front() == '-' || is_digit( x.front() ) )
&& std::all_of( x.begin() + 1, x.end(), is_digit );
}
}
IOConfig::restartConfig IOConfig::rptrst( const DeckKeyword& kw, size_t step ) {
const auto& items = kw.getStringData();
/* if any of the values are pure integers we assume this is meant to be
* the slash-terminated list of integers way of configuring. If
* integers and non-integers are mixed, this is an error.
*/
const auto ints = std::any_of( items.begin(), items.end(), is_int );
const auto strs = !std::all_of( items.begin(), items.end(), is_int );
if( ints && strs ) throw std::runtime_error(
"RPTRST does not support mixed mnemonics and integer list."
);
size_t basic = 1;
size_t freq = 0;
bool found_basic = false;
for( const auto& mnemonic : items ) {
const auto freq_pos = mnemonic.find( "FREQ=" );
if( freq_pos != std::string::npos ) {
freq = std::stoul( mnemonic.substr( freq_pos + 5 ) );
}
const auto basic_pos = mnemonic.find( "BASIC=" );
if( basic_pos != std::string::npos ) {
basic = std::stoul( mnemonic.substr( basic_pos + 6 ) );
found_basic = true;
}
}
if( found_basic ) return restartConfig( step, basic, freq );
/* If no BASIC mnemonic is found, either it is not present or we might
* have an old data set containing integer controls instead of mnemonics.
* BASIC integer switch is integer control nr 1, FREQUENCY is integer
* control nr 6.
*/
/* mnemonics, but without basic and freq. Effectively ignored */
if( !ints ) return {};
const int BASIC_index = 0;
const int FREQ_index = 5;
if( items.size() > BASIC_index )
basic = std::stoul( items[ BASIC_index ] );
// Peculiar special case in eclipse, - not documented
// This ignore of basic = 0 for the integer mnemonics case
// is done to make flow write restart file at the same intervals
// as eclipse for the Norne data set. There might be some rules
// we are missing here.
if( 0 == basic ) return {};
if( items.size() > FREQ_index ) // if frequency is set
freq = std::stoul( items[ FREQ_index ] );
return restartConfig( step, basic, freq );
}
IOConfig::restartConfig IOConfig::rptsched( const DeckKeyword& keyword ) {
size_t restart = 0;
bool restart_found = false;
const auto& items = keyword.getStringData();
const auto ints = std::any_of( items.begin(), items.end(), is_int );
const auto strs = !std::all_of( items.begin(), items.end(), is_int );
if( ints && strs ) throw std::runtime_error(
"RPTSCHED does not support mixed mnemonics and integer list."
);
for( const auto& mnemonic : items ) {
const auto restart_pos = mnemonic.find( "RESTART=" );
if( restart_pos != std::string::npos ) {
restart = std::stoul( mnemonic.substr( restart_pos + 8 ) );
restart_found = true;
}
const auto nothing_pos = mnemonic.find( "NOTHING" );
if( nothing_pos != std::string::npos ) {
restart = 0;
restart_found = true;
}
}
if( restart_found ) return restartConfig( restart );
/* No RESTART or NOTHING found, but it is not an integer list */
if( strs ) return {};
/* We might have an old data set containing integer controls instead of
* mnemonics. Restart integer switch is integer control nr 7
*/
const int RESTART_index = 6;
if( items.size() <= RESTART_index ) return {};
return restartConfig( std::stoul( items[ RESTART_index ] ) );
}
DynamicState< IOConfig::restartConfig > IOConfig::rstconf(
const SCHEDULESection& schedule,
std::shared_ptr< const TimeMap > timemap ) {
size_t current_step = 1;
bool ignore_RPTSCHED_restart = false;
restartConfig unset;
DynamicState< IOConfig::restartConfig >
restart_config( timemap, restartConfig( 0, 0, 1 ) );
for( const auto& keyword : schedule ) {
const auto& name = keyword.name();
if( name == "DATES" ) {
current_step += keyword.size();
continue;
}
if( name == "TSTEP" ) {
current_step += keyword.getRecord( 0 ).getItem( 0 ).size();
continue;
}
if( !( name == "RPTRST" || name == "RPTSCHED" ) ) continue;
if( timemap->size() <= current_step ) continue;
const bool is_RPTRST = name == "RPTRST";
if( !is_RPTRST && ignore_RPTSCHED_restart ) continue;
const auto rs = is_RPTRST
? rptrst( keyword, current_step - 1 )
: rptsched( keyword );
if( is_RPTRST ) ignore_RPTSCHED_restart = rs.basic > 2;
/* we're using the default state of restartConfig to signal "no
* update". The default state is non-sensical
*/
if( rs == unset ) continue;
if( 6 == rs.rptsched_restart || 6 == rs.basic )
throw std::runtime_error(
"OPM does not support the RESTART=6 setting"
"(write restart file every timestep)"
);
restart_config.update( current_step, rs );
}
return restart_config;
}
IOConfig::IOConfig( const Deck& deck ) :
IOConfig( GRIDSection( deck ),
RUNSPECSection( deck ),
SCHEDULESection( deck ),
std::make_shared< const TimeMap >( deck ),
deck.hasKeyword("NOSIM"),
deck.getDataFile() )
{}
@ -266,8 +97,8 @@ namespace Opm {
IOConfig::IOConfig( const GRIDSection& grid,
const RUNSPECSection& runspec,
const SCHEDULESection& schedule,
std::shared_ptr< const TimeMap > timemap,
bool nosim,
const std::string& input_path ) :
m_timemap( timemap ),
m_write_INIT_file( grid.hasKeyword( "INIT" ) ),
@ -279,10 +110,10 @@ namespace Opm {
m_deck_filename( input_path ),
m_output_dir( outputdir( input_path ) ),
m_base_name( basename( input_path ) ),
m_restart_output_config( std::make_shared< DynamicState< restartConfig > >(
rstconf( schedule, timemap ) ) )
m_nosim( nosim )
{}
bool IOConfig::getWriteEGRIDFile() const {
return m_write_EGRID_file;
}
@ -291,153 +122,34 @@ namespace Opm {
return m_write_INIT_file;
}
bool IOConfig::getWriteRestartFile(size_t timestep) const {
bool write_restart_ts = false;
if (0 == timestep) {
write_restart_ts = m_write_initial_RST_file;
} else if (m_restart_output_config) {
restartConfig ts_restart_config = m_restart_output_config->get(timestep);
//Look at rptsched restart setting
if (ts_restart_config.rptsched_restart_set) {
if (ts_restart_config.rptsched_restart > 0) {
write_restart_ts = true;
}
} else { //Look at rptrst basic setting
switch (ts_restart_config.basic) {
case 0: //Do not write restart files
write_restart_ts = false;
break;
case 1: //Write restart file every report time
write_restart_ts = true;
break;
case 2: //Write restart file every report time
write_restart_ts = true;
break;
case 3: //Every n'th report time
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency);
break;
case 4: //First reportstep of every year, or if n > 1, n'th years
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, true);
break;
case 5: //First reportstep of every month, or if n > 1, n'th months
write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, false, true);
break;
default:
// do nothing
break;
}
}
}
return write_restart_ts;
}
bool IOConfig::getWriteRestartFileFrequency(size_t timestep,
size_t start_timestep,
size_t frequency,
bool years,
bool months) const {
bool write_restart_file = false;
if ((!years && !months) && (timestep >= start_timestep)) {
write_restart_file = ((timestep % frequency) == 0) ? true : false;
} else {
write_restart_file = m_timemap->isTimestepInFirstOfMonthsYearsSequence(timestep, years, start_timestep, frequency);
}
return write_restart_file;
}
void IOConfig::assertTimeMap(TimeMapConstPtr timemap) {
if (!m_timemap) {
restartConfig rs;
rs.timestep = 0;
rs.basic = 0;
rs.frequency = 1;
rs.rptsched_restart_set = false;
rs.rptsched_restart = 0;
m_timemap = timemap;
m_restart_output_config = std::make_shared<DynamicState<restartConfig>>(timemap, rs);
}
}
/*
Will initialize the two internal variables holding the first
report step when restart and rft output is queried.
The reason we are interested in this report step is that when we
reach this step the output files should be opened with mode 'w'
- whereas for subsequent steps they should be opened with mode
'a'.
Will initialize an internal variable holding the first report
step when rft output is queried. The reason we are interested in
this report step is that when we reach this step the output
files should be opened with mode 'w' - whereas for subsequent
steps it should be opened with mode 'a'.
*/
void IOConfig::initFirstOutput(const Schedule& schedule) {
m_first_restart_step = -1;
void IOConfig::initFirstRFTOutput(const Schedule& schedule) {
m_first_rft_step = -1;
assertTimeMap( this->m_timemap );
{
size_t report_step = 0;
while (true) {
if (getWriteRestartFile(report_step)) {
m_first_restart_step = report_step;
break;
}
report_step++;
if (report_step == m_timemap->size())
break;
}
}
{
for (const auto& well : schedule.getWells( )) {
int well_output = well->firstRFTOutput();
if (well_output >= 0) {
if ((m_first_rft_step < 0) || (well_output < m_first_rft_step))
m_first_rft_step = well_output;
}
for (const auto& well : schedule.getWells( )) {
int well_output = well->firstRFTOutput();
if (well_output >= 0) {
if ((m_first_rft_step < 0) || (well_output < m_first_rft_step))
m_first_rft_step = well_output;
}
}
}
void IOConfig::handleSolutionSection(TimeMapConstPtr timemap, std::shared_ptr<const SOLUTIONSection> solutionSection) {
if (solutionSection->hasKeyword("RPTRST")) {
const auto& rptrstkeyword = solutionSection->getKeyword("RPTRST");
auto rs = rptrst( rptrstkeyword, 0 );
if( rs != restartConfig() )
m_restart_output_config->updateInitial( rs );
setWriteInitialRestartFile(true); // Guessing on eclipse rules for write of initial RESTART file (at time 0):
// Write of initial restart file is (due to the eclipse reference manual)
// governed by RPTSOL RESTART in solution section,
// if RPTSOL RESTART > 1 initial restart file is written.
// but - due to initial restart file written from Eclipse
// for data where RPTSOL RESTART not set - guessing that
// when RPTRST is set in SOLUTION (no basic though...) -> write inital restart.
} //RPTRST
if (solutionSection->hasKeyword("RPTSOL") && (timemap->size() > 0)) {
handleRPTSOL(solutionSection->getKeyword("RPTSOL"));
} //RPTSOL
void IOConfig::overrideNOSIM(bool nosim) {
m_nosim = nosim;
}
void IOConfig::overrideRestartWriteInterval(size_t interval) {
size_t step = 0;
/* write restart files if the interval is non-zero. The restart
* mnemonic (setting) that governs restart-on-interval is BASIC=3
*/
size_t basic = interval > 0 ? 3 : 0;
restartConfig rs( step, basic, interval );
m_restart_output_config->globalReset( rs );
setWriteInitialRestartFile( interval > 0 );
}
bool IOConfig::getUNIFIN() const {
return m_UNIFIN;
@ -455,57 +167,6 @@ namespace Opm {
return m_FMTOUT;
}
void IOConfig::setWriteInitialRestartFile(bool writeInitialRestartFile) {
m_write_initial_RST_file = writeInitialRestartFile;
}
void IOConfig::handleRPTSOL( const DeckKeyword& keyword) {
const auto& record = keyword.getRecord(0);
size_t restart = 0;
size_t found_mnemonic_RESTART = 0;
bool handle_RPTSOL_RESTART = false;
const auto& item = record.getItem(0);
for (size_t index = 0; index < item.size(); ++index) {
const std::string& mnemonic = item.get< std::string >(index);
found_mnemonic_RESTART = mnemonic.find("RESTART=");
if (found_mnemonic_RESTART != std::string::npos) {
std::string restart_no = mnemonic.substr(found_mnemonic_RESTART+8, mnemonic.size());
restart = boost::lexical_cast<size_t>(restart_no);
handle_RPTSOL_RESTART = true;
}
}
/* If no RESTART mnemonic is found, either it is not present or we might
have an old data set containing integer controls instead of mnemonics.
Restart integer switch is integer control nr 7 */
if (found_mnemonic_RESTART == std::string::npos) {
if (item.size() >= 7) {
const std::string& integer_control = item.get< std::string >(6);
try {
restart = boost::lexical_cast<size_t>(integer_control);
handle_RPTSOL_RESTART = true;
} catch (boost::bad_lexical_cast &) {
//do nothing
}
}
}
if (handle_RPTSOL_RESTART) {
if (restart > 1) {
setWriteInitialRestartFile(true);
} else {
setWriteInitialRestartFile(false);
}
}
}
boost::gregorian::date IOConfig::getTimestepDate(size_t reportStep) const {
@ -514,17 +175,6 @@ namespace Opm {
}
void IOConfig::dumpRestartConfig() const {
for (size_t reportStep = 0; reportStep < m_timemap->size(); reportStep++) {
if (getWriteRestartFile(reportStep)) {
auto time = (*m_timemap)[reportStep];
boost::gregorian::date date = time.date();
printf("%04zu : %02hu/%02hu/%hu \n" , reportStep ,
date.day().as_number() , date.month().as_number() , static_cast<unsigned short>(date.year()));
}
}
}
std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const {
bool unified = output ? getUNIFOUT() : getUNIFIN();
@ -539,11 +189,6 @@ namespace Opm {
}
int IOConfig::getFirstRestartStep() const {
return m_first_restart_step;
}
int IOConfig::getFirstRFTStep() const {
return m_first_rft_step;
}
@ -556,7 +201,7 @@ namespace Opm {
m_output_enabled = enabled;
}
std::string IOConfig::getOutputDir() {
std::string IOConfig::getOutputDir() const {
return m_output_dir;
}
@ -572,4 +217,33 @@ namespace Opm {
m_base_name = baseName;
}
std::string IOConfig::fullBasePath( ) const {
namespace fs = boost::filesystem;
fs::path dir( m_output_dir );
fs::path base( m_base_name );
fs::path full_path = dir.make_preferred() / base.make_preferred();
return full_path.string();
}
bool IOConfig::initOnly( ) const {
return m_nosim;
}
/*****************************************************************/
/* Here at the bottom are some forwarding proxy methods which just
forward to the appropriate RestartConfig method. They are
retained here as a temporary convenience method to prevent
downstream breakage.
Currently the EclipseState object can return a mutable IOConfig
object, which application code can alter to override settings
from the deck - this is quite ugly. When the API is reworked to
remove the ability modify IOConfig objects we should also
remove these forwarding methods.
*/
} //namespace Opm

View File

@ -30,8 +30,6 @@ namespace Opm {
class DeckKeyword;
class GRIDSection;
class RUNSPECSection;
class SCHEDULESection;
class SOLUTIONSection;
class TimeMap;
class Schedule;
@ -124,9 +122,8 @@ namespace Opm {
explicit IOConfig( const Deck& );
explicit IOConfig( const std::string& input_path );
int getFirstRestartStep() const;
int getFirstRFTStep() const;
bool getWriteRestartFile(size_t timestep) const;
bool getWriteEGRIDFile() const;
bool getWriteINITFile() const;
bool getUNIFOUT() const;
@ -135,52 +132,40 @@ namespace Opm {
bool getFMTOUT() const;
const std::string& getEclipseInputPath() const;
void overrideRestartWriteInterval(size_t interval);
void overrideNOSIM(bool nosim);
void handleSolutionSection(std::shared_ptr< const TimeMap > timemap, std::shared_ptr<const SOLUTIONSection> solutionSection);
void setWriteInitialRestartFile(bool writeInitialRestartFile);
/// This method will internalize variables with information of
/// the first report step with restart and rft output
/// respectively. This information is important because right
/// at the first output step we must reset the files to size
/// zero, for subsequent output steps we should append.
void initFirstOutput(const Schedule& schedule);
boost::gregorian::date getTimestepDate(size_t timestep) const;
void dumpRestartConfig() const;
std::string getRestartFileName(const std::string& restart_base, int report_step, bool output) const;
bool getOutputEnabled();
void setOutputEnabled(bool enabled);
std::string getOutputDir();
std::string getOutputDir() const;
void setOutputDir(const std::string& outputDir);
const std::string& getBaseName() const;
void setBaseName(std::string baseName);
/// Return a string consisting of outputpath and basename;
/// i.e. /path/to/sim/CASE
std::string fullBasePath( ) const;
bool initOnly() const;
void initFirstRFTOutput(const Schedule& schedule);
// Proxy methods forwarding directly to corresponding RestartConfig
bool getWriteRestartFile(size_t timestep) const;
int getFirstRestartStep() const;
void overrideRestartWriteInterval(size_t interval);
void setWriteInitialRestartFile(bool writeInitialRestartFile);
private:
IOConfig( const GRIDSection&,
const RUNSPECSection&,
const SCHEDULESection&,
std::shared_ptr< const TimeMap >,
const std::string& input_path );
void assertTimeMap(std::shared_ptr< const TimeMap > timemap);
bool getWriteRestartFileFrequency(size_t timestep,
size_t start_timestep,
size_t frequency,
bool years = false,
bool months = false) const;
void handleRPTSOL( const DeckKeyword& keyword);
std::shared_ptr< const TimeMap > m_timemap;
bool m_write_INIT_file = false;
bool m_write_EGRID_file = true;
bool m_write_initial_RST_file = false;
bool m_UNIFIN = false;
bool m_UNIFOUT = false;
bool m_FMTIN = false;
@ -191,57 +176,13 @@ namespace Opm {
bool m_output_enabled = true;
std::string m_output_dir;
std::string m_base_name;
bool m_nosim;
struct restartConfig {
/*
The content of this struct is logically divided in two; either the
restart behaviour is governed by { timestep , basic , frequency }, or
alternatively by { rptshec_restart_set , rptsched_restart }.
The former triplet is mainly governed by the RPTRST keyword and the
latter pair by the RPTSCHED keyword.
*/
size_t timestep = 0;
size_t basic = 0;
size_t frequency = 0;
bool rptsched_restart_set = false;
size_t rptsched_restart = 0;
restartConfig() = default;
restartConfig( size_t sched_restart ) :
rptsched_restart_set( true ),
rptsched_restart( sched_restart )
{}
restartConfig( size_t step, size_t b, size_t freq ) :
timestep( step ),
basic( b ),
frequency( freq )
{}
bool operator!=(const restartConfig& rhs) const {
return !( *this == rhs );
}
bool operator==( const restartConfig& rhs ) const {
if( this->rptsched_restart_set ) {
return rhs.rptsched_restart_set
&& this->rptsched_restart == rhs.rptsched_restart;
}
return this->timestep == rhs.timestep &&
this->basic == rhs.basic &&
this->frequency == rhs.frequency;
}
};
static DynamicState< restartConfig > rstconf( const SCHEDULESection&,
std::shared_ptr< const TimeMap > );
static restartConfig rptrst( const DeckKeyword&, size_t );
static restartConfig rptsched( const DeckKeyword& );
std::shared_ptr<DynamicState<restartConfig>> m_restart_output_config;
IOConfig( const GRIDSection&,
const RUNSPECSection&,
std::shared_ptr< const TimeMap >,
bool nosim,
const std::string& input_path );
};

View File

@ -0,0 +1,650 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/lexical_cast.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <ert/ecl/ecl_util.h>
namespace Opm {
namespace {
inline bool is_int( const std::string& x ) {
auto is_digit = []( char c ) { return std::isdigit( c ); };
return !x.empty()
&& ( x.front() == '-' || is_digit( x.front() ) )
&& std::all_of( x.begin() + 1, x.end(), is_digit );
}
constexpr const char* RSTIntegerKeywords[] = { "BASIC", // 1
"FLOWS", // 2
"FIP", // 3
"POT", // 4
"PBPD", // 5
"FREQ", // 6
"PRES", // 7
"VISC", // 8
"DEN", // 9
"DRAIN", // 10
"KRO", // 11
"KRW", // 12
"KRG", // 13
"PORO", // 14
"NOGRAD", // 15
"NORST", // 16 NORST - not supported
"SAVE", // 17
"SFREQ", // 18 SFREQ=?? - not supported
"ALLPROPS", // 19
"ROCKC", // 20
"SGTRAP", // 21
"", // 22 - Blank - ignored.
"RSSAT", // 23
"RVSAT", // 24
"GIMULT", // 25
"SURFBLK", // 26
"", // 27 - PCOW, PCOG, special cased
"STREAM", // 28 STREAM=?? - not supported
"RK", // 29
"VELOCITY", // 30
"COMPRESS" }; // 31
constexpr const char* SCHEDIntegerKeywords[] = { "PRES", // 1
"SOIL", // 2
"SWAT", // 3
"SGAS", // 4
"RS", // 5
"RV", // 6
"RESTART", // 7
"FIP", // 8
"WELLS", // 9
"VFPPROD", // 10
"SUMMARY", // 11
"CPU", // 12
"AQUCT", // 13
"WELSPECS",// 14
"NEWTON", // 15
"POILD", // 16
"PWAT", // 17
"PWATD", // 18
"PGAS", // 19
"PGASD", // 20
"FIPVE", // 21
"WOC", // 22
"GOC", // 23
"WOCDIFF", // 24
"GOCDIFF", // 25
"WOCGOC", // 26
"ODGAS", // 27
"ODWAT", // 28
"GDOWAT", // 29
"WDOGAS", // 30
"OILAPI", // 31
"FIPITR", // 32
"TBLK", // 33
"PBLK", // 34
"SALT", // 35
"PLYADS", // 36
"RK", // 37
"FIPSALT", // 38
"TUNING", // 39
"GI", // 40
"ROCKC", // 41
"SPENWAT", // 42
"FIPSOL", // 43
"SURFBLK", // 44
"SURFADS", // 45
"FIPSURF", // 46
"TRADS", // 47
"VOIL", // 48
"VWAT", // 49
"VGAS", // 50
"DENO", // 51
"DENW", // 52
"DENG", // 53
"GASCONC", // 54
"PB", // 55
"PD", // 56
"KRW", // 57
"KRO", // 58
"KRG", // 59
"MULT", // 60
"UNKNOWN", // 61 61 and 62 are not listed in the manual
"UNKNOWN", // 62
"FOAM", // 63
"FIPFOAM", // 64
"TEMP", // 65
"FIPTEMP", // 66
"POTC", // 67
"FOAMADS", // 68
"FOAMDCY", // 69
"FOAMMOB", // 70
"RECOV", // 71
"FLOOIL", // 72
"FLOWAT", // 73
"FLOGAS", // 74
"SGTRAP", // 75
"FIPRESV", // 76
"FLOSOL", // 77
"KRN", // 78
"GRAD", // 79
};
bool is_RPTRST_mnemonic( const std::string& kw ) {
/* all eclipse 100 keywords we want to not simply ignore. The list is
* sorted, so we can use binary_search for log(n) lookup. It is important
* that the list is sorted, but these are all the keywords listed in the
* manual and unlikely to change at all
*/
static constexpr const char* valid[] = {
"ACIP", "ACIS", "ALLPROPS", "BASIC", "BG", "BO",
"BW", "CELLINDX", "COMPRESS", "CONV", "DEN", "DRAIN",
"DRAINAGE", "DYNREG", "FIP", "FLORES", "FLOWS", "FREQ",
"GIMULT", "HYDH", "HYDHFW", "KRG", "KRO", "KRW",
"NOGRAD", "NORST", "NPMREB", "PBPD", "PCOG", "PCOW",
"PERMREDN", "POIS", "PORO", "PORV", "POT", "PRES",
"RFIP", "RK", "ROCKC", "RPORV", "RSSAT", "RVSAT",
"SAVE", "SDENO", "SFIP", "SFREQ", "SGTRAP", "SIGM_MOD",
"STREAM", "SURFBLK", "TRAS", "VELGAS", "VELOCITY", "VELOIL",
"VELWAT", "VISC",
};
return std::binary_search( std::begin( valid ), std::end( valid ), kw );
}
bool is_RPTSCHED_mnemonic( const std::string& kw ) {
static constexpr const char* valid[] = {
"ALKALINE", "ANIONS", "AQUCT", "AQUFET", "AQUFETP", "BFORG",
"CATIONS", "CPU", "DENG", "DENO", "DENW", "ESALPLY",
"ESALSUR", "FFORG", "FIP", "FIPFOAM", "FIPHEAT", "FIPRESV",
"FIPSALT", "FIPSOL", "FIPSURF", "FIPTEMP", "FIPTR", "FIPVE",
"FLOGAS", "FLOOIL", "FLOSOL", "FLOWAT", "FMISC", "FOAM",
"FOAMADS", "FOAMCNM", "FOAMDCY", "FOAMMOB", "GASCONC", "GASSATC",
"GDOWAT", "GI", "GOC", "GOCDIFF", "GRAD", "KRG",
"KRN", "KRO", "KRW", "MULT", "NEWTON", "NOTHING",
"NPMREB", "ODGAS", "ODWAT", "OILAPI", "PB", "PBLK",
"PBU", "PD", "PDEW", "PGAS", "PGASD", "PLYADS",
"POIL", "POILD", "POLYMER", "POTC", "POTG", "POTO",
"POTW", "PRES", "PRESSURE", "PWAT", "PWATD", "RECOV",
"RESTART", "ROCKC", "RS", "RSSAT", "RV", "RVSAT",
"SALT", "SGAS", "SGTRAP", "SIGM_MOD", "SOIL", "SSOL",
"SUMMARY", "SURFADS", "SURFBLK", "SWAT", "TBLK", "TEMP",
"TRACER", "TRADS", "TRDCY", "TUNING", "VFPPROD", "VGAS",
"VOIL", "VWAT", "WDOGAS", "WELLS", "WELSPECL", "WELSPECS",
"WOC", "WOCDIFF", "WOCGOC",
};
return std::binary_search( std::begin( valid ), std::end( valid ), kw );
}
}
RestartSchedule::RestartSchedule( size_t sched_restart) :
rptsched_restart_set( true ),
rptsched_restart( sched_restart )
{
}
RestartSchedule::RestartSchedule( size_t step, size_t b, size_t freq) :
timestep( step ),
basic( b ),
frequency( basic > 2 ? std::max( freq, size_t{ 1 } ) : freq )
{
/*
* if basic > 2 and freq is default (zero) we're looking at an error
* (every Nth step where N = 0). Instead of throwing we default this to
* 1 so that basic > 2 and freq unset essentially is
* write-every-timestep. It could've just as easily been an exception,
* but to be more robust handling poorly written decks we instead set a
* reasonable default and carry on.
*/
}
bool RestartSchedule::operator!=(const RestartSchedule & rhs) const {
return !( *this == rhs );
}
bool RestartSchedule::operator==( const RestartSchedule& rhs ) const {
if( this->rptsched_restart_set ) {
return rhs.rptsched_restart_set
&& this->rptsched_restart == rhs.rptsched_restart;
}
return this->timestep == rhs.timestep &&
this->basic == rhs.basic &&
this->frequency == rhs.frequency;
}
inline std::map< std::string, int >
RPTRST_integer( const std::vector< int >& ints ) {
const size_t PCO_index = 26;
const size_t BASIC_index = 0;
std::map< std::string, int > mnemonics;
const size_t size = std::min( ints.size(), sizeof( RSTIntegerKeywords ) );
/* fun with special cases. Eclipse seems to ignore the BASIC=0,
* interpreting it as sort-of "don't modify". Handle this by *not*
* adding/updating the integer list sourced BASIC mnemonic, should it be
* zero. I'm not sure if this applies to other mnemonics, but the eclipse
* manual indicates that any zero here should disable the output.
*
* See https://github.com/OPM/opm-parser/issues/886 for reference
*/
if( size > 0 && ints[ BASIC_index ] != 0 )
mnemonics[ RSTIntegerKeywords[ BASIC_index ] ] = ints[ BASIC_index ];
for( size_t i = 1; i < std::min( size, PCO_index ); ++i )
mnemonics[ RSTIntegerKeywords[ i ] ] = ints[ i ];
for( size_t i = PCO_index + 1; i < size; ++i )
mnemonics[ RSTIntegerKeywords[ i ] ] = ints[ i ];
/* item 27 (index 26) sets both PCOW and PCOG, so we special case it */
if( ints.size() >= PCO_index ) {
mnemonics[ "PCOW" ] = ints[ PCO_index ];
mnemonics[ "PCOG" ] = ints[ PCO_index ];
}
return std::move( mnemonics );
}
inline std::map< std::string, int >
RPTSCHED_integer( const std::vector< int >& ints ) {
const size_t size = std::min( ints.size(), sizeof( SCHEDIntegerKeywords ) );
std::map< std::string, int > mnemonics;
for( size_t i = 0; i < size; ++i )
mnemonics[ SCHEDIntegerKeywords[ i ] ] = ints[ i ];
return std::move( mnemonics );
}
template< typename F, typename G >
inline std::map< std::string, int > RPT( const DeckKeyword& keyword,
F is_mnemonic,
G integer_mnemonic ) {
const auto& items = keyword.getStringData();
const auto ints = std::any_of( items.begin(), items.end(), is_int );
const auto strs = !std::all_of( items.begin(), items.end(), is_int );
/* if any of the values are pure integers we assume this is meant to be
* the slash-terminated list of integers way of configuring. If
* integers and non-integers are mixed, this is an error.
*/
if( ints && strs ) throw std::runtime_error(
"RPTRST does not support mixed mnemonics and integer list."
);
auto stoi = []( const std::string& str ) { return std::stoi( str ); };
if( ints )
return integer_mnemonic( fun::map( stoi, items ) );
std::map< std::string, int > mnemonics;
for( const auto& mnemonic : items ) {
const auto pos = mnemonic.find( '=' );
std::string base = mnemonic.substr( 0, pos );
if( !is_mnemonic( base ) ) continue;
const int val = pos != std::string::npos
? std::stoi( mnemonic.substr( pos + 1 ) )
: 1;
mnemonics.emplace( base, val );
}
return std::move( mnemonics );
}
void expand_RPTRST_mnemonics(std::map< std::string, int >& mnemonics) {
const auto allprops = mnemonics.find( "ALLPROPS");
if (allprops != mnemonics.end()) {
const auto value = allprops->second;
mnemonics.erase( "ALLPROPS" );
for (const auto& kw : {"BG","BO","BW","KRG","KRO","KRW","VOIL","VGAS","VWAT","DEN"})
mnemonics[kw] = value;
}
}
inline std::pair< std::map< std::string, int >, RestartSchedule >
RPTRST( const DeckKeyword& keyword, RestartSchedule prev, size_t step ) {
auto mnemonics = RPT( keyword, is_RPTRST_mnemonic, RPTRST_integer );
const bool has_freq = mnemonics.find( "FREQ" ) != mnemonics.end();
const bool has_basic = mnemonics.find( "BASIC" ) != mnemonics.end();
expand_RPTRST_mnemonics( mnemonics );
if( !has_freq && !has_basic ) return { std::move( mnemonics ), {} };
const auto basic = has_basic ? mnemonics.at( "BASIC" ) : prev.basic;
const auto freq = has_freq ? mnemonics.at( "FREQ" ) : prev.frequency;
return { std::move( mnemonics ), { step, basic, freq } };
}
inline std::pair< std::map< std::string, int >, RestartSchedule >
RPTSCHED( const DeckKeyword& keyword ) {
auto mnemonics = RPT( keyword, is_RPTSCHED_mnemonic, RPTSCHED_integer );
if( mnemonics.count( "NOTHING" ) )
return { std::move( mnemonics ), { 0 } };
if( mnemonics.count( "RESTART" ) )
return { std::move( mnemonics ), size_t( mnemonics.at( "RESTART" ) ) };
return { std::move( mnemonics ), {} };
}
void RestartConfig::handleScheduleSection(const SCHEDULESection& schedule) {
size_t current_step = 1;
RestartSchedule unset;
auto ignore_RPTSCHED_RESTART = []( decltype( restart_schedule )& x ) {
return x.back().basic > 2;
};
for( const auto& keyword : schedule ) {
const auto& name = keyword.name();
if( name == "DATES" ) {
current_step += keyword.size();
continue;
}
if( name == "TSTEP" ) {
current_step += keyword.getRecord( 0 ).getItem( 0 ).size();
continue;
}
if( !( name == "RPTRST" || name == "RPTSCHED" ) ) continue;
if( this->m_timemap->size() <= current_step ) continue;
const bool is_RPTRST = name == "RPTRST";
const auto& prev_sched = this->restart_schedule.back();
auto config = is_RPTRST
? RPTRST( keyword, prev_sched, current_step )
: RPTSCHED( keyword );
/* add the missing entries from the previous step */
{
auto& mnemonics = config.first;
const auto& prev_mnemonics = this->restart_keywords.back();
mnemonics.insert( prev_mnemonics.begin(), prev_mnemonics.end() );
if( mnemonics.find( "NOTHING" ) != mnemonics.end() )
mnemonics.clear();
this->restart_keywords.update( current_step , mnemonics );
}
const bool ignore_RESTART =
!is_RPTRST && ignore_RPTSCHED_RESTART( this->restart_schedule );
const auto& rs = config.second;
if( rs == unset || ignore_RESTART ) continue;
if( 6 == rs.rptsched_restart || 6 == rs.basic )
throw std::runtime_error(
"OPM does not support the RESTART=6 setting "
"(write restart file every timestep)"
);
this->restart_schedule.update( current_step, rs );
}
}
bool RestartSchedule::writeRestartFile( size_t input_timestep , const TimeMap& timemap) const {
if (this->rptsched_restart_set && (this->rptsched_restart > 0))
return true;
switch (basic) {
//Do not write restart files
case 0: return false;
//Write restart file every report time
case 1: return true;
//Write restart file every report time
case 2: return true;
//Every n'th report time
case 3: return ((input_timestep % this->frequency) == 0) ? true : false;
//First reportstep of every year, or if n > 1, n'th years
case 4: return timemap.isTimestepInFirstOfMonthsYearsSequence(input_timestep, true , this->timestep, this->frequency);
//First reportstep of every month, or if n > 1, n'th months
case 5: return timemap.isTimestepInFirstOfMonthsYearsSequence(input_timestep, false , this->timestep, this->frequency);
default: return false;
}
}
RestartConfig::RestartConfig( const Deck& deck ) :
RestartConfig( SCHEDULESection( deck ),
SOLUTIONSection( deck ),
std::make_shared< const TimeMap >( deck ))
{}
RestartConfig::RestartConfig( const SCHEDULESection& schedule,
const SOLUTIONSection& solution,
std::shared_ptr< const TimeMap > timemap) :
m_timemap( timemap ),
m_first_restart_step( -1 ),
restart_schedule( timemap, { 0, 0, 1 } ),
restart_keywords( timemap, {} )
{
handleSolutionSection( solution );
handleScheduleSection( schedule );
initFirstOutput( );
}
RestartSchedule RestartConfig::getNode( size_t timestep ) const{
return restart_schedule.get(timestep);
}
bool RestartConfig::getWriteRestartFile(size_t timestep) const {
if (0 == timestep)
return m_write_initial_RST_file;
{
RestartSchedule ts_restart_config = getNode( timestep );
return ts_restart_config.writeRestartFile( timestep , *m_timemap );
}
}
const std::map< std::string, int >& RestartConfig::getRestartKeywords( size_t timestep ) const {
return restart_keywords.at( timestep );
}
int RestartConfig::getKeyword( const std::string& keyword, size_t timeStep) const {
const std::map< std::string, int >& keywords = this->getRestartKeywords( timeStep );
const auto iter = keywords.find( keyword );
if (iter == keywords.end()) {
if (is_RPTRST_mnemonic( keyword ))
return 0;
else
throw std::invalid_argument("The mnenomic " + keyword + " is not recognized");
} else
return iter->second;
}
/*
Will initialize the internal variable holding the first report
step when restart output is queried.
The reason we are interested in this report step is that when we
reach this step the output files should be opened with mode 'w'
- whereas for subsequent steps they should be opened with mode
'a'.
*/
void RestartConfig::initFirstOutput( ) {
size_t report_step = 0;
while (true) {
if (getWriteRestartFile(report_step)) {
m_first_restart_step = report_step;
break;
}
report_step++;
if (report_step == m_timemap->size())
break;
}
}
void RestartConfig::handleSolutionSection(const SOLUTIONSection& solutionSection) {
if (solutionSection.hasKeyword("RPTRST")) {
const auto& rptrstkeyword = solutionSection.getKeyword("RPTRST");
const auto rptrst = RPTRST( rptrstkeyword, {}, 0 );
this->restart_keywords.updateInitial( rptrst.first );
this->restart_schedule.updateInitial( rptrst.second );
setWriteInitialRestartFile(true); // Guessing on eclipse rules for write of initial RESTART file (at time 0):
// Write of initial restart file is (due to the eclipse reference manual)
// governed by RPTSOL RESTART in solution section,
// if RPTSOL RESTART > 1 initial restart file is written.
// but - due to initial restart file written from Eclipse
// for data where RPTSOL RESTART not set - guessing that
// when RPTRST is set in SOLUTION (no basic though...) -> write inital restart.
} //RPTRST
if (solutionSection.hasKeyword("RPTSOL") && (m_timemap->size() > 0)) {
handleRPTSOL(solutionSection.getKeyword("RPTSOL"));
} //RPTSOL
}
void RestartConfig::overrideRestartWriteInterval(size_t interval) {
size_t step = 0;
/* write restart files if the interval is non-zero. The restart
* mnemonic (setting) that governs restart-on-interval is BASIC=3
*/
size_t basic = interval > 0 ? 3 : 0;
RestartSchedule rs( step, basic, interval );
restart_schedule.globalReset( rs );
setWriteInitialRestartFile( interval > 0 );
}
void RestartConfig::setWriteInitialRestartFile(bool writeInitialRestartFile) {
m_write_initial_RST_file = writeInitialRestartFile;
}
void RestartConfig::handleRPTSOL( const DeckKeyword& keyword) {
const auto& record = keyword.getRecord(0);
size_t restart = 0;
size_t found_mnemonic_RESTART = 0;
bool handle_RPTSOL_RESTART = false;
const auto& item = record.getItem(0);
for (size_t index = 0; index < item.size(); ++index) {
const std::string& mnemonic = item.get< std::string >(index);
found_mnemonic_RESTART = mnemonic.find("RESTART=");
if (found_mnemonic_RESTART != std::string::npos) {
std::string restart_no = mnemonic.substr(found_mnemonic_RESTART+8, mnemonic.size());
restart = boost::lexical_cast<size_t>(restart_no);
handle_RPTSOL_RESTART = true;
}
}
/* If no RESTART mnemonic is found, either it is not present or we might
have an old data set containing integer controls instead of mnemonics.
Restart integer switch is integer control nr 7 */
if (found_mnemonic_RESTART == std::string::npos) {
if (item.size() >= 7) {
const std::string& integer_control = item.get< std::string >(6);
try {
restart = boost::lexical_cast<size_t>(integer_control);
handle_RPTSOL_RESTART = true;
} catch (boost::bad_lexical_cast &) {
//do nothing
}
}
}
if (handle_RPTSOL_RESTART) {
if (restart > 1) {
setWriteInitialRestartFile(true);
} else {
setWriteInitialRestartFile(false);
}
}
}
std::string RestartConfig::getRestartFileName(const std::string& restart_base, int report_step, bool unified , bool fmt_file) {
ecl_file_enum file_type = (unified) ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE;
char * c_str = ecl_util_alloc_filename( NULL , restart_base.c_str() , file_type, fmt_file , report_step);
std::string restart_filename = c_str;
free( c_str );
return restart_filename;
}
int RestartConfig::getFirstRestartStep() const {
return m_first_restart_step;
}
}

View File

@ -0,0 +1,375 @@
/*
Copyright 2015 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_RESTART_CONFIG_HPP
#define OPM_RESTART_CONFIG_HPP
#include <vector>
#include <set>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <boost/date_time.hpp>
/*
The RestartConfig class internalizes information of when (at which
report steps) we should save restart files, and which properties
should be included in the restart files. The configuration of this
immensely complex, and this code is unfortunately also way too
complex.
The most basic question to disentangle is the "When to write restart
files" versus "What data to store write in the restart file". As
expressed in the deck keywords this completely entangled, in this
implementation we have tried to disentangle it:
Keywords involved
-----------------
RPTRST: This is the main keyword for configuring restart output; it
can be used to configure bothe when to write the files and which
properties should be included in the restart files.
RPTSCHED: The main purpose of the RPTSCHED keyword is to configure
output from the SCHEDULE section to the PRINT file. However the
mneomnic RESTART=n can be used to turn writing of restart files
on, and also for values > 2 to some configuration of what is
written to the restart file:
RESTART=1 : As RPTRST,BASIC=1
RESTART>1 : As RPTRST,BASIC=2
RESTART>2 : Flow is added to restart file
RESTART>3 : Fluid in place is added to restart file
RESTART=6 : Restart file for every timestep.
RPTSOL: The RPTSOL keyword is very similar to the RPTCHED keyword,
it configures output from the SOLUTION section to the PRINT file,
but just as the RPTSCHED keyword it accepts a RESTART=n mnenonic
which can be used similarly to the BASIC=n mnenonic of the RPTRST
keyword. In particular the writing of an initial restart files
with initial equilibrium solution is controlled by the RPTSOL
keyword. If the restart mneonic is greater than 2 that can be
used to configure FLOWS and FIP keywords in the restart file.
RESTART=1 : As RPTRST,BASIC=1
RESTART>1 : As RPTRST,BASIC=2
RESTART>2 : Flow is added to restart file
RESTART>3 : Fluid in place is added to restart file
The basic rule in ECLIPSE is generally that the 'last keyword wins',
but for the RPTRST RPTSHCED combination a BASIC setting with n >= 3
will override consecutive RESTART=n settings from RPTSCHED.
When to write restart files:
----------------------------
When to write the restart file is governed by the BASIC=n setting in
the RPTRST keyword and the RESTART=n settings in the RPTSOL and
RPTSCHED keywords. The most common setting is 'ON' - i.e. BASIC=2
which means write a restart file for every report step, that can be
turned off again with BASIC=0. For BASIC>2 there are varietes of
every n'th report step, and the first report step in every month and
every year.
Old style / new style
---------------------
All of the relevant keywords can be specified using a new style
based on string mneomnics and alternatively an old style represented
with a *strictly ordered* list of integers. For instance both of
these keywords request restart files written for every report step;
in addition to the fields required to actually restart the files
should contain the relative permeabilities KRO, KRW, KRG:
RPTRST
BASIC=2 KRG KRW KRO /
RPTRST
2 9*0 3*1 17*0
Integer controls and string mneomnics can not be mixed in the same
keyword, but they can be mixed in the same deck - and that is
actually quite common.
What is written to the restart file
-----------------------------------
The BASIC=n mneonics request the writing of a restart file which
should contain 'all properties required to restart', in addition you
can configure extra keywords to be added to the restart file. This
is configured by just adding a list as:
RPTRST
BASIC=2 KRG KRW KRO /
It is really *not clear* what is the correct persistence semantics
for these keywords, consider for insance the following series of keywords:
-- Request restart file at every report step, the restart files
-- should contain additional properties KRO, KRG and KRW.
RPTRST
BASIC=2 KRG KRW KRO /
-- Advance the simulator forward with TSTEP / DATES
TSTEP / DATES / WCONxxx
-- Turn writing of restart files OFF using integer controls.
RPTRST
0 /
-- Advance the simulator forward with TSTEP / DATES
TSTEP / DATES / WCONxxx
-- Turn writing of restart files ON using integer controls.
RPTRST
2 /
When writing of restart files is turned on again with the last
RPTRST keyword, should still the relative permeabilites KRO, KRW and
KRG be added to the restart files? The model we have implemented is:
- The list of keywords written to the restart file is persisted
independtly of the BASIC=n setting.
- Using string based mnonics you can *only add* kewyords to be
written to the files. To stop writing a keyword you must use an
integer control with value 0.
Based on this best guess heuristic the final restart files will
still contain KRO, KRW and KRG.
What is required to restart?
----------------------------
A restart capable files is requested with the 'BASIC' mneomnic, but
exactly which properties the 'BASIC' keyword is expanded to is the
responsability of the simulator; i.e. for a black oil simulation you
will at the very least need the expansion:
BASIC -> PRESSURE, SWAT, SGAS, RS, RV
But this class just carries the boolean information: Yes - restart
is requested - expanding as illustrated is the responsability of the
simulator.
What is not supported?
----------------------
The SAVE keyword is not supported in OPM at all, this implies that
the SAVE and SFREQ mneomics are not supported.
*/
namespace Opm {
template< typename > class DynamicState;
class Deck;
class DeckKeyword;
class GRIDSection;
class RUNSPECSection;
class SCHEDULESection;
class SOLUTIONSection;
class TimeMap;
class Schedule;
/*The IOConfig class holds data about input / ouput configurations
Amongst these configuration settings, a IOConfig object knows if
a restart file should be written for a specific report step
The write of restart files is governed by several eclipse keywords.
These keywords are all described in the eclipse manual, but some
of them are rather porly described there.
To have equal sets of restart files written from Eclipse and Flow for various
configurations, we have made a qualified guess on the behaviour
for some of the keywords (by running eclipse for different configurations,
and looked at which restart files that have been written).
------ RPTSOL RESTART (solution section) ------
If RPTSOL RESTART > 1 initial restart file is written.
------ RPTRST (solution section) ------
Eclipse manual states that the initial restart file is to be written
if RPTSOL RESTART > 1. But - due to that the initial restart file
is written from Eclipse for data where RPTSOL RESTART is not set, - we
have made a guess that when RPTRST is set in SOLUTION (no basic though...),
it means that the initial restart file should be written.
Running of eclipse with different settings have proven this to be a qualified guess.
------ RPTRST BASIC=0 (solution or schedule section) ------
No restart files are written
------ RPTRST BASIC=1 or RPTRST BASIC=2 (solution or schedule section) ------
Restart files are written for every timestep, from timestep 1 to number of timesteps.
(Write of inital timestep is governed by a separate setting)
Notice! Eclipse simulator RPTRST BASIC=1 writes restart files for every
report step, but only keeps the last one written. This functionality is
not supported in Flow; so to compare Eclipse results with Flow results
for every report step, set RPTRST BASIC=2 for the eclipse run
------ RPTRST BASIC=3 FREQ=n (solution or schedule section) ------
Restart files are created every nth report time. Default frequency is 1 (every report step)
If a frequency higher than 1 is given:
start_rs = report step the setting was given.
write report step rstep if (rstep >= start_rs) && ((rstep % frequency) == 0).
------ RPTRST BASIC=4 FREQ=n or RPTRST BASIC=5 FREQ=n (solution or schedule section) ------
For the settings BASIC 4 or BASIC 5, - first report step of every new year(4) or new month(5),
the first report step is compared with report step 0 (start), and then every report step is
compared with the previous one to see if year/month has changed.
This leaves us with a set of timesteps.
All timesteps in the set that are higher or equal to the timestep the RPTRST keyword was set on is written.
If in addition FREQUENCY is given (higher than 1), every n'the value of this set are to be written.
If the setting BASIC=4 or BASIC=5 is set on a timestep that is a member of the set "first timestep of
each year" / "First timestep of each month", then the timestep that is freq-1 timesteps (within the set) from
this start timestep will be written, and then every n'the timestep (within the set) from this one will be written.
If the setting BASIC=4 or BASIC=5 is set on a timestep that is not a member of the list "first timestep of
each year" / "First timestep of each month", then the list is searched for the closest timestep that are
larger than the timestep that introduced the setting, and then; same as above - the timestep that is freq-1
timesteps from this one (within the set) will be written, and then every n'the timestep (within the set) from
this one will be written.
------ RPTRST BASIC=6 (solution or schedule section) ------
Not supported in Flow
------ Default ------
If no keywords for config of writing restart files have been handled; no restart files are written.
*/
//namespace {
class RestartSchedule {
/*
The content of this struct is logically divided in two; either the
restart behaviour is governed by { timestep , basic , frequency }, or
alternatively by { rptshec_restart_set , rptsched_restart }.
The former triplet is mainly governed by the RPTRST keyword and the
latter pair by the RPTSCHED keyword.
*/
public:
RestartSchedule() = default;
RestartSchedule( size_t sched_restart);
RestartSchedule( size_t step, size_t b, size_t freq);
bool writeRestartFile( size_t timestep , const TimeMap& timemap) const;
bool operator!=(const RestartSchedule& rhs) const;
bool operator==( const RestartSchedule& rhs ) const;
//private:
size_t timestep = 0;
size_t basic = 0;
size_t frequency = 0;
bool rptsched_restart_set = false;
size_t rptsched_restart = 0;
};
// }
class RestartConfig {
public:
RestartConfig();
explicit RestartConfig( const Deck& );
RestartConfig( const SCHEDULESection& schedule,
const SOLUTIONSection& solution,
std::shared_ptr< const TimeMap > timemap);
int getFirstRestartStep() const;
bool getWriteRestartFile(size_t timestep) const;
const std::map< std::string, int >& getRestartKeywords( size_t timestep ) const;
int getKeyword( const std::string& keyword, size_t timeStep) const;
void overrideRestartWriteInterval(size_t interval);
void handleSolutionSection(const SOLUTIONSection& solutionSection);
void setWriteInitialRestartFile(bool writeInitialRestartFile);
boost::gregorian::date getTimestepDate(size_t reportStep) const {
auto time = (*m_timemap)[reportStep];
return time.date();
}
RestartSchedule getNode( size_t timestep ) const;
static std::string getRestartFileName(const std::string& restart_base, int report_step, bool unified, bool fmt_file);
private:
/// This method will internalize variables with information of
/// the first report step with restart and rft output
/// respectively. This information is important because right
/// at the first output step we must reset the files to size
/// zero, for subsequent output steps we should append.
void initFirstOutput( );
bool getWriteRestartFileFrequency(size_t timestep,
size_t start_timestep,
size_t frequency,
bool years = false,
bool months = false) const;
void handleRPTSOL( const DeckKeyword& keyword);
std::shared_ptr< const TimeMap > m_timemap;
int m_first_restart_step;
bool m_write_initial_RST_file = false;
void handleScheduleSection( const SCHEDULESection& schedule);
void update( size_t step, const RestartSchedule& rs);
static RestartSchedule rptsched( const DeckKeyword& );
DynamicState< RestartSchedule > restart_schedule;
DynamicState< std::map< std::string, int > > restart_keywords;
};
} //namespace Opm
#endif

View File

@ -1,2 +1,5 @@
opm_add_test(runIOConfigTests SOURCES IOConfigTest.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
opm_add_test(runRestartConfigTests SOURCES RestartConfigTests.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})

View File

@ -162,638 +162,11 @@ static DeckPtr createDeck(const std::string& input) {
BOOST_AUTO_TEST_CASE( RFT_TIME) {
DeckPtr deck = createDeck(deckStr_RFT);
EclipseState state( deck , Opm::ParseContext() );
std::shared_ptr<const IOConfig> ioConfig = state.getIOConfigConst();
EclipseState state( *deck , Opm::ParseContext() );
const IOConfig& ioConfig = state.cfg().io();
BOOST_CHECK_EQUAL( ioConfig->getFirstRFTStep() , 2 );
}
BOOST_AUTO_TEST_CASE(RPTRST_mixed_mnemonics_int_list) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 0 1 2\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"BASIC=1\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
BOOST_CHECK_THROW( IOConfig c( *deck ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE(RPTRST) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=2 RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"3 0 0 0 0 2\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
IOConfig ioConfig1( *deck1 );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 2 ) );
auto deck2 = parser.parseString( deckData2, ctx );
IOConfig ioConfig2( *deck2 );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 3 ) );
auto deck3 = parser.parseString( deckData3, ctx );
IOConfig ioConfig3( *deck3 );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(RPTSCHED) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"NOTHING RUBBISH\n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=1 RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"0 0 0 0 0 0 0 0\n"
"/\n";
Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
IOConfig ioConfig1( *deck1 );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig1.getWriteRestartFile( 3 ) );
auto deck2 = parser.parseString( deckData2, ctx );
IOConfig ioConfig2( *deck2 );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig2.getWriteRestartFile( 3 ) );
auto deck3 = parser.parseString( deckData3, ctx );
IOConfig ioConfig3( *deck3 );
//Older ECLIPSE 100 data set may use integer controls instead of mnemonics
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig3.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(RPTSCHED_and_RPTRST) {
const char *deckData =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck = parser.parseString( deckData, ctx );
IOConfig ioConfig( *deck );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 0 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 1 ) );
BOOST_CHECK( !ioConfig.getWriteRestartFile( 2 ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(NO_BASIC) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts = 0; ts < 4; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_1) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"BASIC=1\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts = 0; ts < 3; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_3) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
const size_t freq = 3;
/* BASIC=3, restart files are created every nth report time, n=3 */
for( size_t ts = 1; ts < 12; ++ts )
BOOST_CHECK_EQUAL( ts % freq == 0, ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
" 6 JAN 1983 14:56:45.123 /\n" // timestep 12
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* BASIC=4, restart file is written at the first report step of each year.
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 12 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4_FREQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* BASIC=4, restart file is written at the first report step of each year.
* Optionally, if the mnemonic FREQ is set >1 the restart is written only
* every n'th year.
*
* FREQ=2
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_5) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=5 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n" // write
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n" // write
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n" //write
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* BASIC=5, restart file is written at the first report step of each month.
*/
for( size_t ts : { 1, 2, 3, 4, 6, 7, 9, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 5, 8, 10 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=0 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_GT_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n" // BASIC >2, ignore RPTSCHED RESTART
"RESTART=3, FREQ=1\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_LEQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=1"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n"
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n"
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
IOConfig ioConfig( *deck );
BOOST_CHECK( ioConfig.getWriteRestartFile( 1 ) );
for( size_t ts = 2; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
BOOST_CHECK_EQUAL( ioConfig.getFirstRFTStep() , 2 );
}
BOOST_AUTO_TEST_CASE(DefaultProperties) {
@ -902,11 +275,15 @@ BOOST_AUTO_TEST_CASE(OutputPaths) {
BOOST_CHECK_EQUAL( output_dir2, config2.getOutputDir() );
BOOST_CHECK_EQUAL( "testString", config2.getBaseName() );
namespace fs = boost::filesystem;
Deck deck3;
deck3.setDataFile( "/path/to/testString.DATA" );
IOConfig config3( deck3 );
std::string output_dir3 = "/path/to";
config3.setOutputDir( output_dir3 );
auto testpath = fs::path( "/path/to/testString" ).make_preferred().string();
BOOST_CHECK_EQUAL( output_dir3, config3.getOutputDir() );
BOOST_CHECK_EQUAL( "testString", config3.getBaseName() );
BOOST_CHECK_EQUAL( testpath, config3.fullBasePath() );
}

View File

@ -0,0 +1,901 @@
/*
Copyright 2016 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE RestartConfigTests
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
inline std::string fst( const std::pair< std::string, int >& p ) {
return p.first;
}
using namespace Opm;
BOOST_AUTO_TEST_CASE(RPTSCHED_INTEGER) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SOLUTION\n"
"RPTRST -- PRES,DEN,PCOW,PCOG,RK,VELOCITY,COMPRESS\n"
" 6*0 1 0 1 9*0 1 7*0 1 0 3*1 /\n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"RPTRST -- RK,VELOCITY,COMPRESS\n"
" 18*0 0 8*0 /\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n";
Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
RestartConfig rstConfig1( *deck1 );
BOOST_CHECK( rstConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig1.getWriteRestartFile( 2 ) );
BOOST_CHECK( !rstConfig1.getWriteRestartFile( 3 ) );
std::vector< std::string > kw_list1;
for( const auto& pair : rstConfig1.getRestartKeywords( 0 ) )
if( pair.second != 0 ) kw_list1.push_back( pair.first );
const auto expected1 = {"BG","BO","BW","COMPRESS","DEN","KRG","KRO","KRW","PCOG","PCOW","PRES","RK","VELOCITY","VGAS","VOIL","VWAT"};
BOOST_CHECK_EQUAL_COLLECTIONS( expected1.begin(), expected1.end(),
kw_list1.begin(), kw_list1.end() );
// ACIP is a valid mneonic - but not in this deck.
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "ACIP" , 0) , 0 );
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "COMPRESS" , 0) , 1 );
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "PCOG", 0) , 1 );
BOOST_CHECK_THROW( rstConfig1.getKeyword( "UNKNOWN_KW", 0) , std::invalid_argument);
std::vector< std::string > kw_list2;
for( const auto& pair : rstConfig1.getRestartKeywords( 3 ) )
if( pair.second != 0 ) kw_list2.push_back( pair.first );
const auto expected2 = { "COMPRESS", "RESTART", "RK", "VELOCITY" };
BOOST_CHECK_EQUAL_COLLECTIONS( expected2.begin(), expected2.end(),
kw_list2.begin(), kw_list2.end() );
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "ALLPROPS" , 0 ) , 0);
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "ALLPROPS" , 3 ) , 0);
}
const std::string& deckStr = "RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"GRIDFILE\n"
" 0 1 /\n"
"\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"DATES\n"
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
" 7 JAN 1982 14:56:45.123 /\n" // timestep 12
" 8 JAN 1982 14:56:45.123 /\n" // timestep 13
" 9 JAN 1982 14:56:45.123 /\n" // timestep 14
" 10 JAN 1982 14:56:45.123 /\n" // timestep 15
" 11 JAN 1982 14:56:45.123 /\n" // timestep 16
" 1 JAN 1983 /\n" // timestep 17
" 2 JAN 1983 /\n" // timestep 18
" 3 JAN 1983 /\n" // timestep 19
" 1 JAN 1984 /\n" // timestep 20
" 2 JAN 1984 /\n" // timestep 21
" 1 JAN 1985 /\n" // timestep 22
" 3 JAN 1986 14:56:45.123 /\n" // timestep 23
" 4 JAN 1986 14:56:45.123 /\n" // timestep 24
" 5 JAN 1986 14:56:45.123 /\n" // timestep 25
" 1 JAN 1987 /\n" // timestep 26
" 1 JAN 1988 /\n" // timestep 27
" 2 JAN 1988 /\n" // timestep 28
" 3 JAN 1988 /\n" // timestep 29
" 1 JAN 1989 /\n" // timestep 30
" 2 JAN 1989 /\n" // timestep 31
" 2 JAN 1990 /\n" // timestep 32
" 2 JAN 1991 /\n" // timestep 33
" 3 JAN 1991 /\n" // timestep 34
" 4 JAN 1991 /\n" // timestep 35
" 1 JAN 1992 /\n" // timestep 36
" 1 FEB 1992 /\n" // timestep 37
" 1 MAR 1992 /\n" // timestep 38
" 2 MAR 1992 /\n" // timestep 39
" 3 MAR 1992 /\n" // timestep 40
" 4 MAR 1992 /\n" // timestep 41
" 1 APR 1992 /\n" // timestep 42
" 2 APR 1992 /\n" // timestep 43
" 1 MAY 1992 /\n" // timestep 44
" 2 MAY 1992 /\n" // timestep 45
" 3 MAY 1992 /\n" // timestep 46
" 3 JUN 1992 /\n" // timestep 47
" 3 JUL 1992 /\n" // timestep 48
" 3 AUG 1992 /\n" // timestep 49
" 4 AUG 1992 /\n" // timestep 50
" 5 AUG 1992 /\n" // timestep 51
" 6 AUG 1992 /\n" // timestep 52
" 7 AUG 1992 /\n" // timestep 53
" 8 AUG 1992 /\n" // timestep 54
" 9 AUG 1992 /\n" // timestep 55
" 10 AUG 1992 /\n" // timestep 56
" 11 AUG 1992 /\n" // timestep 57
" 12 AUG 1992 /\n" // timestep 58
" 13 AUG 1992 /\n" // timestep 59
" 14 AUG 1992 /\n" // timestep 60
" 15 AUG 1992 /\n" // timestep 61
"/\n"
"\n";
const std::string deckStr_RFT = "RUNSPEC\n"
"OIL\n"
"GAS\n"
"WATER\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DXV\n"
"10*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZV\n"
"10*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"\n"
"START -- 0 \n"
"1 NOV 1979 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 1 DES 1979/ \n"
"/\n"
"WELSPECS\n"
" 'OP_1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
" 'OP_2' 'OP' 4 4 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
"/\n"
"COMPDAT\n"
" 'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
" 'OP_1' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n"
" 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
" 'OP_2' 4 4 4 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
"/\n"
"DATES -- 2\n"
" 10 OKT 2008 / \n"
"/\n"
"WRFT \n"
"/ \n"
"WELOPEN\n"
" 'OP_1' OPEN / \n"
" 'OP_2' OPEN / \n"
"/\n"
"DATES -- 3\n"
" 10 NOV 2008 / \n"
"/\n";
BOOST_AUTO_TEST_CASE(RPTRST_mixed_mnemonics_int_list) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 0 1 2\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"BASIC=1\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
BOOST_CHECK_THROW( RestartConfig c( *deck ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE(RPTRST) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SOLUTION\n"
"RPTRST\n"
" ACIP KRG KRO KRW NORST SFREQ=10 ALLPROPS/\n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=2 FLOWS RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"3 0 0 0 0 2\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
RestartConfig rstConfig1( *deck1 );
// Observe that this is true due to some undocumented guessing that
// the initial restart file should be written if a RPTRST keyword is
// found in the SOLUTION section, irrespective of the content of that
// keyword.
BOOST_CHECK( rstConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig1.getWriteRestartFile( 2 ) );
std::vector<std::string> expected = { "ACIP","BASIC", "BG","BO","BW","DEN","KRG", "KRO", "KRW", "NORST", "SFREQ", "VGAS", "VOIL", "VWAT"};
const auto kw_list = fun::map( fst, rstConfig1.getRestartKeywords(2) );
BOOST_CHECK_EQUAL_COLLECTIONS( expected.begin() ,expected.end(),
kw_list.begin() , kw_list.end() );
BOOST_CHECK_EQUAL( rstConfig1.getKeyword( "ALLPROPS" , 2 ) , 0);
auto deck2 = parser.parseString( deckData2, ctx );
RestartConfig rstConfig2( *deck2 );
const auto expected2 = { "BASIC", "FLOWS", "FREQ" };
const auto kw_list2 = fun::map( fst, rstConfig2.getRestartKeywords( 2 ) );
BOOST_CHECK_EQUAL_COLLECTIONS( expected2.begin(), expected2.end(),
kw_list2.begin(), kw_list2.end() );
BOOST_CHECK( !rstConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( !rstConfig2.getWriteRestartFile( 3 ) );
auto deck3 = parser.parseString( deckData3, ctx );
RestartConfig rstConfig3( *deck3 );
BOOST_CHECK( !rstConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( !rstConfig3.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(RPTSCHED) {
const char *deckData1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n";
const char *deckData2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=3 FIP\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=4\n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"NOTHING RUBBISH\n"
"/\n";
const char *deckData3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SOLUTION\n"
"RPTSOL\n"
" RESTART=4 /\n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=1 RUBBISH=5\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"0 0 0 0 0 0 0 0\n"
"/\n";
Parser parser;
ParseContext ctx;
auto deck1 = parser.parseString( deckData1, ctx );
RestartConfig rstConfig1( *deck1 );
BOOST_CHECK( !rstConfig1.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig1.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig1.getWriteRestartFile( 2 ) );
BOOST_CHECK( rstConfig1.getWriteRestartFile( 3 ) );
auto deck2 = parser.parseString( deckData2, ctx );
RestartConfig rstConfig2( *deck2 );
BOOST_CHECK( !rstConfig2.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig2.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig2.getWriteRestartFile( 2 ) );
BOOST_CHECK( rstConfig2.getWriteRestartFile( 3 ) );
const auto expected2 = { "FIP", "RESTART" };
const auto kw_list2 = fun::map( fst, rstConfig2.getRestartKeywords( 2 ) );
BOOST_CHECK_EQUAL_COLLECTIONS( expected2.begin(), expected2.end(),
kw_list2.begin(), kw_list2.end() );
auto deck3 = parser.parseString( deckData3, ctx );
RestartConfig rstConfig3( *deck3 );
//Older ECLIPSE 100 data set may use integer controls instead of mnemonics
BOOST_CHECK( rstConfig3.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig3.getWriteRestartFile( 1 ) );
BOOST_CHECK( rstConfig3.getWriteRestartFile( 2 ) );
BOOST_CHECK( rstConfig3.getWriteRestartFile( 3 ) );
std::vector<std::string> expected3 = { "BASIC", "FREQ" };
const auto kw_list3 = fun::map( fst, rstConfig3.getRestartKeywords(2) );
BOOST_CHECK_EQUAL_COLLECTIONS( expected3.begin() , expected3.end() , kw_list3.begin() , kw_list3.end() );
}
BOOST_AUTO_TEST_CASE(RPTSCHED_and_RPTRST) {
const char *deckData =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3 BG BO\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n";
Opm::Parser parser;
ParseContext ctx;
auto deck = parser.parseString( deckData, ctx );
RestartConfig rstConfig( *deck );
BOOST_CHECK( !rstConfig.getWriteRestartFile( 0 ) );
BOOST_CHECK( !rstConfig.getWriteRestartFile( 1 ) );
BOOST_CHECK( !rstConfig.getWriteRestartFile( 2 ) );
BOOST_CHECK( rstConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(NO_BASIC) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
for( size_t ts = 0; ts < 4; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_1) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"DATES -- 1\n"
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 FEB 2010 / \n"
"/\n"
"RPTSCHED\n"
"BASIC=1\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
for( size_t ts = 0; ts < 3; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
BOOST_CHECK( ioConfig.getWriteRestartFile( 3 ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_3) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=3 FREQ=3\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
const size_t freq = 3;
/* BASIC=3, restart files are created every nth report time, n=3 */
for( size_t ts = 1; ts < 12; ++ts )
BOOST_CHECK_EQUAL( ts % freq == 0, ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n" // timestep 1
" 23 MAY 1981 /\n" // timestep 2
" 24 MAY 1981 /\n" // timestep 3
" 25 MAY 1981 /\n" // timestep 4
" 26 MAY 1981 /\n" // timestep 5
" 1 JAN 1982 /\n" // timestep 6
" 1 JAN 1982 13:55:44 /\n" // timestep 7
" 3 JAN 1982 14:56:45.123 /\n" // timestep 8
" 4 JAN 1982 14:56:45.123 /\n" // timestep 9
" 5 JAN 1982 14:56:45.123 /\n" // timestep 10
" 6 JAN 1982 14:56:45.123 /\n" // timestep 11
" 6 JAN 1983 14:56:45.123 /\n" // timestep 12
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
/* BASIC=4, restart file is written at the first report step of each year.
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 12 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_4_FREQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
/* BASIC=4, restart file is written at the first report step of each year.
* Optionally, if the mnemonic FREQ is set >1 the restart is written only
* every n'th year.
*
* FREQ=2
*/
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_5) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=5 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n" // write
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n" // write
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n" //write
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
/* BASIC=5, restart file is written at the first report step of each month.
*/
for( size_t ts : { 1, 2, 3, 4, 6, 7, 9, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 5, 8, 10 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(BASIC_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=0 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_EQ_0) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 1 JUN 1981 /\n"
" 1 JUL 1981 /\n"
" 1 JAN 1982 /\n"
" 2 JAN 1982 /\n"
" 1 FEB 1982 /\n"
" 1 MAR 1982 /\n"
" 1 APR 1983 /\n"
" 2 JUN 1983 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
/* RESTART=0, no restart file is written
*/
for( size_t ts = 0; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_GT_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=4 FREQ=2\n"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n" // BASIC >2, ignore RPTSCHED RESTART
"RESTART=3, FREQ=1\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n" // write
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n" // write
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
for( size_t ts : { 1, 2, 3, 4, 5, 7, 8, 10, 11 } )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
for( size_t ts : { 6, 9 } )
BOOST_CHECK( ioConfig.getWriteRestartFile( ts ) );
}
BOOST_AUTO_TEST_CASE(RESTART_BASIC_LEQ_2) {
const char* data = "RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"START\n"
" 21 MAY 1981 /\n"
"\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=1"
"/\n"
"DATES\n"
" 22 MAY 1981 /\n"
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"DATES\n"
" 23 MAY 1981 /\n"
" 24 MAY 1981 /\n"
" 23 MAY 1982 /\n"
" 24 MAY 1982 /\n"
" 24 MAY 1983 /\n"
" 25 MAY 1984 /\n"
" 26 MAY 1984 /\n"
" 26 MAY 1985 /\n"
" 27 MAY 1985 /\n"
" 1 JAN 1986 /\n"
"/\n";
auto deck = Parser().parseString( data, ParseContext() );
RestartConfig ioConfig( *deck );
BOOST_CHECK( ioConfig.getWriteRestartFile( 1 ) );
for( size_t ts = 2; ts < 11; ++ts )
BOOST_CHECK( !ioConfig.getWriteRestartFile( ts ) );
}

View File

@ -17,19 +17,24 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <cassert>
#include <vector>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
namespace Opm {
Completion::Completion(int i, int j , int k , WellCompletion::StateEnum state ,
Completion::Completion(int i, int j , int k ,
double depth,
WellCompletion::StateEnum state ,
const Value<double>& connectionTransmissibilityFactor,
const Value<double>& diameter,
const Value<double>& skinFactor,
@ -42,7 +47,7 @@ namespace Opm {
m_state(state),
m_direction(direction),
m_segment_number(-1),
m_center_depth(-1.e100)
m_center_depth( depth )
{}
Completion::Completion(std::shared_ptr<const Completion> oldCompletion, WellCompletion::StateEnum newStatus)
@ -136,12 +141,22 @@ namespace Opm {
disentangled, and each completion is returned separately.
*/
std::pair<std::string , std::vector<CompletionPtr> > Completion::completionsFromCOMPDATRecord( const DeckRecord& compdatRecord ) {
inline std::vector< CompletionPtr >
fromCOMPDAT( const EclipseGrid& grid, const DeckRecord& compdatRecord, const Well& well ) {
std::vector<CompletionPtr> completions;
std::string well = compdatRecord.getItem("WELL").getTrimmedString(0);
// We change from eclipse's 1 - n, to a 0 - n-1 solution
int I = compdatRecord.getItem("I").get< int >(0) - 1;
int J = compdatRecord.getItem("J").get< int >(0) - 1;
// I and J can be defaulted with 0 or *, in which case they are fetched
// from the well head
const auto& itemI = compdatRecord.getItem( "I" );
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
const int I = !defaulted_I ? itemI.get< int >( 0 ) - 1 : well.getHeadI();
const auto& itemJ = compdatRecord.getItem( "J" );
const auto defaulted_J = itemJ.defaultApplied( 0 ) || itemJ.get< int >( 0 ) == 0;
const int J = !defaulted_J ? itemJ.get< int >( 0 ) - 1 : well.getHeadJ();
int K1 = compdatRecord.getItem("K1").get< int >(0) - 1;
int K2 = compdatRecord.getItem("K2").get< int >(0) - 1;
WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( compdatRecord.getItem("STATE").getTrimmedString(0) );
@ -167,11 +182,12 @@ namespace Opm {
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnumFromString(compdatRecord.getItem("DIR").getTrimmedString(0));
for (int k = K1; k <= K2; k++) {
CompletionPtr completion(new Completion(I , J , k , state , connectionTransmissibilityFactor, diameter, skinFactor, direction ));
double depth = grid.getCellDepth( I,J,k );
CompletionPtr completion(new Completion(I , J , k , depth , state , connectionTransmissibilityFactor, diameter, skinFactor, direction ));
completions.push_back( completion );
}
return std::pair<std::string , std::vector<CompletionPtr> >( well , completions );
return completions;
}
/*
@ -184,25 +200,32 @@ namespace Opm {
}
*/
std::map< std::string, std::vector< CompletionPtr > >
Completion::fromCOMPDAT( const EclipseGrid& grid ,
const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& wells ) {
std::map<std::string , std::vector< CompletionPtr> > Completion::completionsFromCOMPDATKeyword( const DeckKeyword& compdatKeyword ) {
std::map<std::string , std::vector< CompletionPtr> > completionMapList;
for (size_t recordIndex = 0; recordIndex < compdatKeyword.size(); recordIndex++) {
std::pair<std::string , std::vector< CompletionPtr> > wellCompletionsPair = completionsFromCOMPDATRecord( compdatKeyword.getRecord( recordIndex ));
std::string well = wellCompletionsPair.first;
std::vector<CompletionPtr>& newCompletions = wellCompletionsPair.second;
std::map< std::string, std::vector< CompletionPtr > > res;
if (completionMapList.find(well) == completionMapList.end())
completionMapList[well] = std::vector<CompletionPtr>();
for( const auto& record : compdatKeyword ) {
{
std::vector<CompletionPtr>& currentCompletions = completionMapList.find(well)->second;
const auto wellname = record.getItem( "WELL" ).getTrimmedString( 0 );
const auto name_eq = [&]( const Well* w ) {
return w->name() == wellname;
};
for (size_t ic = 0; ic < newCompletions.size(); ic++)
currentCompletions.push_back( newCompletions[ic] );
}
auto well = std::find_if( wells.begin(), wells.end(), name_eq );
if( well == wells.end() ) continue;
auto completions = Opm::fromCOMPDAT( grid, record, **well );
res[ wellname ].insert( res[ wellname ].end(),
completions.begin(),
completions.end() );
}
return completionMapList;
return res;
}
void Completion::fixDefaultIJ(int wellHeadI , int wellHeadJ) {

View File

@ -34,10 +34,14 @@ namespace Opm {
class DeckKeyword;
class DeckRecord;
class Well;
class EclipseGrid;
class Completion {
public:
Completion(int i, int j , int k , WellCompletion::StateEnum state ,
Completion(int i, int j , int k ,
double depth,
WellCompletion::StateEnum state ,
const Value<double>& connectionTransmissibilityFactor,
const Value<double>& diameter,
const Value<double>& skinFactor,
@ -67,8 +71,10 @@ namespace Opm {
WellCompletion::DirectionEnum getDirection() const;
static std::map<std::string , std::vector<std::shared_ptr<Completion> > > completionsFromCOMPDATKeyword( const DeckKeyword& compdatKeyword );
static std::pair<std::string , std::vector<std::shared_ptr<Completion> > > completionsFromCOMPDATRecord( const DeckRecord& compdatRecord );
static std::map< std::string, std::vector< std::shared_ptr< Completion > > >
fromCOMPDAT( const EclipseGrid& grid,
const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& );
private:
int m_i, m_j, m_k;

View File

@ -94,7 +94,7 @@ namespace Opm {
void CompletionSet::orderCompletions(size_t well_i, size_t well_j, EclipseGridConstPtr grid)
void CompletionSet::orderCompletions(size_t well_i, size_t well_j)
{
if (m_completions.empty()) {
return;
@ -102,42 +102,42 @@ namespace Opm {
// Find the first completion and swap it into the 0-position.
const double surface_z = 0.0;
size_t first_index = findClosestCompletion(well_i, well_j, grid, surface_z, 0);
size_t first_index = findClosestCompletion(well_i, well_j, surface_z, 0);
std::swap(m_completions[first_index], m_completions[0]);
// Repeat for remaining completions.
// Note that since findClosestCompletion() is O(n) if n is the number of completions,
// this is an O(n^2) algorithm. However, it should be acceptable since the expected
// number of completions is fairly low (< 100).
//
// Note that since findClosestCompletion() is O(n), this is an
// O(n^2) algorithm. However, it should be acceptable since
// the expected number of completions is fairly low (< 100).
for (size_t pos = 1; pos < m_completions.size() - 1; ++pos) {
CompletionConstPtr prev = m_completions[pos - 1];
const double prevz = grid->getCellDepth(prev->getI(), prev->getJ(), prev->getK());
size_t next_index = findClosestCompletion(prev->getI(), prev->getJ(), grid, prevz, pos);
const double prevz = prev->getCenterDepth();
size_t next_index = findClosestCompletion(prev->getI(), prev->getJ(), prevz, pos);
std::swap(m_completions[next_index], m_completions[pos]);
}
}
size_t CompletionSet::findClosestCompletion(int oi, int oj, EclipseGridConstPtr grid,
double oz, size_t start_pos)
size_t CompletionSet::findClosestCompletion(int oi, int oj, double oz, size_t start_pos)
{
size_t closest = std::numeric_limits<size_t>::max();
int min_ijdist2 = std::numeric_limits<int>::max();
double min_zdiff = std::numeric_limits<double>::max();
for (size_t pos = start_pos; pos < m_completions.size(); ++pos) {
const double depth = m_completions[pos]->getCenterDepth();
const int ci = m_completions[pos]->getI();
const int cj = m_completions[pos]->getJ();
// Using square of distance to avoid non-integer arithmetics.
const int ijdist2 = (ci - oi) * (ci - oi) + (cj - oj) * (cj - oj);
if (ijdist2 < min_ijdist2) {
min_ijdist2 = ijdist2;
const int ck = m_completions[pos]->getK();
min_zdiff = std::abs(grid->getCellDepth(ci, cj, ck) - oz);
min_zdiff = std::abs(depth - oz);
closest = pos;
} else if (ijdist2 == min_ijdist2) {
const int ck = m_completions[pos]->getK();
const double zdiff = std::abs(grid->getCellDepth(ci, cj, ck) - oz);
const double zdiff = std::abs(depth - oz);
if (zdiff < min_zdiff) {
min_zdiff = zdiff;
closest = pos;

View File

@ -27,8 +27,6 @@
namespace Opm {
class EclipseGrid;
class CompletionSet {
public:
using const_iterator = std::vector< std::shared_ptr< const Completion > >::const_iterator;
@ -56,11 +54,10 @@ namespace Opm {
/// \param[in] well_i logical cartesian i-coordinate of well head
/// \param[in] well_j logical cartesian j-coordinate of well head
/// \param[in] grid EclipseGrid object, used for cell depths
void orderCompletions(size_t well_i, size_t well_j, std::shared_ptr< const EclipseGrid > grid);
void orderCompletions(size_t well_i, size_t well_j);
private:
std::vector<std::shared_ptr< const Completion >> m_completions;
size_t findClosestCompletion(int oi, int oj, std::shared_ptr< const EclipseGrid > grid,
double oz, size_t start_pos);
size_t findClosestCompletion(int oi, int oj, double oz, size_t start_pos);
};
typedef std::shared_ptr<CompletionSet> CompletionSetPtr;

View File

@ -68,6 +68,12 @@ namespace Opm {
}
const T& back() const {
if (m_data.size() > 0)
return m_data.back();
else
return m_initialValue;
}
const T& at(size_t index) const {
if (index >= m_timeMap->size())
@ -85,14 +91,8 @@ namespace Opm {
}
T get(size_t index) const {
if (index >= m_timeMap->size())
throw std::range_error("Index value is out range.");
if (index >= m_data.size())
return m_currentValue;
return m_data[index];
const T& get(size_t index) const {
return this->at( index );
}

Some files were not shown because too many files have changed in this diff Show More