Import opm-parser

This commit is contained in:
Arne Morten Kvarving
2018-03-05 10:30:29 +01:00
858 changed files with 82978 additions and 0 deletions

11
.gitignore vendored
View File

@@ -44,3 +44,14 @@ Testing/
# Build directory in source.
build/
.dir-locals.el
gmon.out
log.log
build
install
.cproject
.project
/testdata/statoil
.idea
/Debug/

108
ExtraTests.cmake Normal file
View File

@@ -0,0 +1,108 @@
# Libs to link tests against
set(TEST_LIBS opmparser ecl Boost::unit_test_framework)
set(EXTRA_TESTS)
# Generated source, needs to be here
opm_add_test(InlineKeywordTest
EXE_NAME inlinekw
SOURCES ${PROJECT_BINARY_DIR}/inlinekw.cpp
LIBRARIES ${TEST_LIBS})
list(APPEND EXTRA_TESTS inlinekw)
# Extra compile definitions and extra parameters
include(cmake/Modules/CheckCaseSensitiveFileSystem.cmake)
set(_testdir ${PROJECT_SOURCE_DIR}/lib/eclipse/tests/data)
opm_add_test(LoaderTest
SOURCES lib/eclipse/tests/KeywordLoaderTests.cpp
lib/eclipse/Generator/KeywordLoader.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/parser/keyword-generator/)
list(APPEND EXTRA_TESTS LoaderTest)
opm_add_test(ParserTests
SOURCES lib/eclipse/tests/ParserTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/)
list(APPEND EXTRA_TESTS ParserTests)
opm_add_test(ParserIncludeTests
SOURCES lib/eclipse/tests/ParserIncludeTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/parser/)
target_compile_definitions(ParserIncludeTests PRIVATE
-DHAVE_CASE_SENSITIVE_FILESYSTEM=${HAVE_CASE_SENSITIVE_FILESYSTEM})
list(APPEND EXTRA_TESTS ParserIncludeTests)
opm_add_test(PvtxTableTests
SOURCES lib/eclipse/tests/PvtxTableTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS PvtxTableTests)
opm_add_test(EclipseStateTests
SOURCES lib/eclipse/tests/EclipseStateTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS EclipseStateTests)
foreach (test BoxTest
CheckDeckValidity
CompletionsFromDeck
EclipseGridCreateFromDeck
IncludeTest
IntegrationTests
IOConfigIntegrationTest
NNCTests
ParseKEYWORD
ParseDATAWithDefault
Polymer
ResinsightTest
ScheduleCreateFromDeck
TransMultIntegrationTests)
opm_add_test(${test}
SOURCES lib/eclipse/tests/integration/${test}.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${_testdir}/integration_tests/)
list(APPEND EXTRA_TESTS ${test})
endforeach ()
# opm-data dependent tests
if(HAVE_OPM_DATA)
opm_add_test(parse_write ONLY_COMPILE
SOURCES lib/eclipse/tests/integration/parse_write.cpp
LIBRARIES ${TEST_LIBS})
list(APPEND EXTRA_TESTS parse_write)
foreach (deck ${OPM_DATA_ROOT}/norne/NORNE_ATW2013.DATA
${OPM_DATA_ROOT}/solvent_test_suite/SPE1CASE2_SOLVENT.DATA
${OPM_DATA_ROOT}/solvent_test_suite/SPE9_CP_SOLVENT_CO2.DATA
${OPM_DATA_ROOT}/spe5/SPE5CASE1.DATA
${OPM_DATA_ROOT}/polymer_simple2D/2D_THREEPHASE_POLY_HETER.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE1.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2_FAMII.DATA
${OPM_DATA_ROOT}/spe1/SPE1CASE2_SLGOF.DATA
${OPM_DATA_ROOT}/spe3/SPE3CASE1.DATA
${OPM_DATA_ROOT}/spe3/SPE3CASE2.DATA
${OPM_DATA_ROOT}/spe9/SPE9_CP.DATA
${OPM_DATA_ROOT}/spe9/SPE9_CP_GROUP.DATA
${OPM_DATA_ROOT}/spe9/SPE9.DATA
${OPM_DATA_ROOT}/spe10model1/SPE10_MODEL1.DATA
${OPM_DATA_ROOT}/spe10model2/SPE10_MODEL2.DATA
${OPM_DATA_ROOT}/msw_2d_h/2D_H__.DATA )
get_filename_component(test_name ${deck} NAME_WE)
opm_add_test(${test_name} NO_COMPILE
EXE_NAME parse_write
TEST_ARGS ${deck})
endforeach()
set_property(TEST NORNE_ATW2013
PROPERTY ENVIRONMENT "OPM_ERRORS_IGNORE=PARSE_RANDOM_SLASH")
endif()
# JSON tests
opm_add_test(jsonTests
SOURCES lib/json/tests/jsonTests.cpp
LIBRARIES ${TEST_LIBS}
TEST_ARGS ${PROJECT_SOURCE_DIR}/lib/json/tests/example1.json)
list(APPEND EXTRA_TESTS jsonTests)

46
GenerateKeywords.cmake Normal file
View File

@@ -0,0 +1,46 @@
set(genkw_SOURCES lib/json/JsonObject.cpp
lib/eclipse/Parser/createDefaultKeywordList.cpp
lib/eclipse/Deck/Deck.cpp
lib/eclipse/Deck/DeckItem.cpp
lib/eclipse/Deck/DeckKeyword.cpp
lib/eclipse/Deck/DeckRecord.cpp
lib/eclipse/Deck/DeckOutput.cpp
lib/eclipse/Generator/KeywordGenerator.cpp
lib/eclipse/Generator/KeywordLoader.cpp
lib/eclipse/Parser/MessageContainer.cpp
lib/eclipse/Parser/ParseContext.cpp
lib/eclipse/Parser/ParserEnums.cpp
lib/eclipse/Parser/ParserItem.cpp
lib/eclipse/Parser/ParserKeyword.cpp
lib/eclipse/Parser/ParserRecord.cpp
lib/eclipse/RawDeck/RawKeyword.cpp
lib/eclipse/RawDeck/RawRecord.cpp
lib/eclipse/RawDeck/StarToken.cpp
lib/eclipse/Units/Dimension.cpp
lib/eclipse/Units/UnitSystem.cpp
lib/eclipse/Utility/Stringview.cpp
)
if(NOT cjson_FOUND)
list(APPEND genkw_SOURCES external/cjson/cJSON.c)
endif()
add_executable(genkw ${genkw_SOURCES})
target_link_libraries(genkw ecl Boost::regex Boost::filesystem Boost::system)
target_include_directories(genkw PRIVATE lib/eclipse/include
lib/json/include)
# Generate keyword list
include(lib/eclipse/share/keywords/keyword_list.cmake)
string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/lib/eclipse/share/keywords/\\1" keyword_files "${keywords}")
configure_file(lib/eclipse/keyword_list.argv.in keyword_list.argv)
# Generate keyword source
add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/ParserKeywords.cpp ${PROJECT_BINARY_DIR}/inlinekw.cpp
COMMAND genkw keyword_list.argv
${PROJECT_BINARY_DIR}/ParserKeywords.cpp
${PROJECT_BINARY_DIR}/include/
opm/parser/eclipse/Parser/ParserKeywords
${PROJECT_BINARY_DIR}/inlinekw.cpp
DEPENDS genkw ${keyword_files} lib/eclipse/share/keywords/keyword_list.cmake
)

45
changelog.md Normal file
View File

@@ -0,0 +1,45 @@
# Changelog
A short month-by-month synopsis of change highlights. Most bugfixes won't make
it in here, only the bigger features and interface changes.
# 2016.12
* ZCORN adjustments improved, considers cell-cell relations
* Slightly more robust compilation - won't crash if locales are broken
* Accessing the PVTW table has a richer interface
* FAULTS face direction accepts X+, I+, Y+, J+, Z+ and K+
* WELOPEN can be controlled with completion numbers (last two parameters)
* COMPLUMP is now supported
* Don't crash on aquifer keywords
* GMWSET and FMWSET are expanded properly
* Don't crash on DEBUG
* Read support for COORDSYS, GRUPRIG, LGR, PRORDER, TRACERS, TUNINGDP,
WDFACCOR, WEFAC, and WORKLIM, no longer crashes.
* RS and RV support.
* Support for DENSITY, PVTW, and ROCK tables
* JFUNC is understood and exposed
# 2016.11
* A new class, Runspec, for the RUNSPEC section, has been introduced
* Nodes in the FIELD group are no longer added to the Summary config
* WCONHIST only adds phases present in the deck
* cJSON can now be installed externally
* DeckItem and ParserItem internals refactored
* Build time reduced by only giving necessary source files to the json compiler
* Support for OPERATE, WSEGITER and GCONPROD
* Internal shared_ptrs removed from Schedule and children; interface updated
* Schedule is now copyable with regular C++ copy semantics - no internal refs
* Well head I/J is now time step dependent
* Well reference depth is time step dependent
* Some ZCORN issues fixed
* gas/oil and oil/gas ratio unit fixed for FIELD units
# 2016.10
* Significant improvements in overall parser performance
* shared_ptr has largely been removed from all public interfaces
* JFUNC keyword can be parsed
* Boolean conversions are explicit
* The Units.hpp header from core is moved here, replacing ConversionFactors
* The ConstPtr and Ptr shared pointer aliases are removed
* UnitSystem, Eclipse3DProperties, and OilVaporizationProperties are default
constructible

View File

@@ -0,0 +1,49 @@
# make targets for boost if find module did not do the job
if(NOT TARGET Boost::system)
add_library(Boost::system UNKNOWN IMPORTED)
set_target_properties(Boost::system PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
IMPORTED_LOCATION "${Boost_SYSTEM_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_SYSTEM_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_SYSTEM_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::filesystem)
add_library(Boost::filesystem UNKNOWN IMPORTED)
set_target_properties(Boost::filesystem PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS BOOST_FILESYSTEM_VERSION=3
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_FILESYSTEM_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_FILESYSTEM_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_FILESYSTEM_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::regex)
add_library(Boost::regex UNKNOWN IMPORTED)
set_target_properties(Boost::regex PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_REGEX_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_REGEX_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_REGEX_LIBRARY_RELEASE}"
)
endif()
if(NOT TARGET Boost::unit_test_framework)
add_library(Boost::unit_test_framework UNKNOWN IMPORTED)
set_target_properties(Boost::unit_test_framework PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${boost_system}"
IMPORTED_LOCATION "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}"
IMPORTED_LOCATION_DEBUG "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}"
)
endif()

View File

@@ -0,0 +1,29 @@
#
# Module to check whether the file system is case sensitive or not
#
# Sets the following variable:
#
# HAVE_CASE_SENSITIVE_FILESYSTEM True if the file system honors the case of files
message(STATUS "Checking whether the file system is case-sensitive")
# create a file containing uppercase characters
file(WRITE "${CMAKE_BINARY_DIR}/UPPER" "Foo")
# check if the all-lowercase file with the same name can be opened
set(FooContents "")
if (EXISTS "${CMAKE_BINARY_DIR}/upper")
file(READ "${CMAKE_BINARY_DIR}/upper" FooContents)
endif()
# remove the file again in order not to have it dangling around...
file(REMOVE "${CMAKE_BINARY_DIR}/UPPER")
# check the contents of the file opened with lower-case. If it is
# empty, the file system is case sensitive.
if ("${FooContents}" STREQUAL "Foo")
message(STATUS "File system is not case-sensitive")
set(HAVE_CASE_SENSITIVE_FILESYSTEM 0)
else()
message(STATUS "File system is case-sensitive")
set(HAVE_CASE_SENSITIVE_FILESYSTEM 1)
endif()

336
docs/keywords.txt Normal file
View File

@@ -0,0 +1,336 @@
Keywords is the most important aspect of the ECLIPSE datafile
parser.
1. The structure of a keyword
-----------------------------
A keyword is the fundamental unit when parsing. Keywords are added to
the parser by schema definitions. The schema definition of the keywords
are given as Json files under the opm/share/keywords directory. Json
can be thought of as a lean alternative to XML, you will find it described
here: http://www.json.org/
As part of the build process these keyword definitions are compiled
to ParserKeyword instances.
1.1 Starting a keyword
----------------------
The keywords are defined as follows:
1. The keyword should start in column 0; everything beyond character
8 is ignored.
2. The keyword should start with a alphabet character, subsequent
characters should be alphanumeric or in the set [-,_,+].
3. We think ECLIPSE is case insensitive.
This is cehcked by the static method:
ParserKeyword::validDeckName(). An important part of the parsing of
keywords is to detect when the keyword specification is complete. For
most keywords we can detect that either by a terminating '/' or the
keywords have a predefined size, but for some odd keywords we can not
reliably detect the end-of-keyword condition and instead we terminate
keyword1 when we find a string which corresponds to the start of a new
keyword. Examples of such oddball keywords include: VFPPROD and
VFPINJ.
1.2 Records
-----------
The data content of a keyword comes as a collection of
records. Records are a collection of 'data', terminated by a '/'. Here
are three examples of records:
'METRES' /
1 'OFF' 100 '*' 24.0 /
0.26 0.27 0.26 0.78
0.82 0.66 0.27 0.78
0.76 0.56 0.23 0.67 /
From these examples we see that:
1. One record can contain a mix of integer, float and string values.
2. Records typically correspond to one line in the data-file, but
that is purely convention; the records can be sprinkled with
newlines.
3. Each record is terminated with a '/'
1.3 How many records in a keyword
---------------------------------
One of the first structural elements which must be configured into the
the parser keywords is the number of records in the different
keywords, this is closely related to how the keyboard is
terminated. Here comes some typical examples of keywords:
GRID
WCONHIST
... /
... /
... /
/
---\
EQLDIMS |
.... / |
|
EQUIL |
.... / |
.... / |
---/
VFPPROD
A .. /
B... /
.... /
.... /
PVGO
/
/
In the list above here the GRID keyword has zero records, i.e. no data
at all. The WCONHIST keyword has three records of data, the EQLDIMS
keyword has one record, the EQUIL keyword has two records and finally
the VFPPROD keyword has four records. The number of records, or how to
infer it, must be configured with the "size" attribute in the JSON
configuration. When it comes to the number of records and termination
we currently have five different categories:
1. Keywords with a fixed number of records. Both the GRID keyword
and the EQLDIMS keyword have a fixed number of records, zero and
one respectively. These keywords are therefor not explicitly
terminated in any way, and the "size" attribute has the numerical
explicitly:
{"name" : "EQLDIMS" , "size" : 1 , ....}
{"name" : "GRID" , "size" : 0, .... }
2. Keywords with a variable number of records like the
WCONHIST. Becase the number of records is not known in advance
this keyword must be explicitly terminated with a '/'. This is
the most common configuration and for keywords of this type it is
not necessary to specify a size attribute at all:
{"name" : "WCONHIST" , .... }
3. Keywords where the number of records is inferred from the content
of another keyword; this is the case with EQUIL which reads the
number of records from the xxx item of the EQLDIMS keyword. Since
the number of records is known in advance (indirectly through the
EQLDIMS keyword) the EQUIL keyword is not explicitly terminated
with a '/'. In the json file this is specified with the "size"
attribute being an object containing the name and item of keyword
which should be consulted to infer the size; so for the EQUIL
keyword the size attribute looks like:
{"name" : "EQUIL" ,
"size" : {"keyword" : "EQLDIMS" , "item" : "NTEQUL"} , ...
When parsing the EQUIL keyword the parser will consult the
already parsed content of the 'EQLDIMS' keyword (i.e. a
DeckKeyword instance) and get the numerical value of the 'NTEQUL'
item.
4. For some keywords the number of records should be calculated
run-time based based on the content of the first records in the
keyword - this at least applies to VFPPROD and VFPINJ. Since the
size of the keyword is deterministic - given the first few
records - the keyword is not slash terminated.
To infer the number of records in the keyword based on an
internal calculation is not supported, hence for these keywords
size is given as unkown, and the keywords are terminated when the
next valid keyword is found:
{"name" : "VFPPROD" , "size" : "UNKNOWN", ....
5. Tables PVTG and PVTO: The two tables PVTG and PVTO are special
cased. The special casing should probably be removed, and the
"size" : "UNKNOWN" could be used for these two keyword.
1.4 The content of a record: items
----------------------------------
A record consist of one or several items. An item can consist of one
or several values from the record, for items with more than one value
it is not possible to specify the exact number of values - the item
will just consume the remaining values in the input stream. An item
has a name, a data type and optionally a default value. For instance
the WCONHIST keyword has the the following items specification:
"items":
[{"name" : "WELL" , "value_type" : "STRING"},
{"name" : "STATUS" , "value_type" : "STRING" , "default" : "OPEN"},
{"name" : "CMODE" , "value_type" : "STRING"},
{"name" : "ORAT" , "value_type" : "DOUBLE", "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"},
{"name" : "WRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"},
{"name" : "GRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "GasSurfaceVolume/Time"},
{"name" : "VFPTable" , "value_type" : "INT" , "default" : 0.0 , "comment":"The default is a state variable"},
{"name" : "Lift" , "value_type" : "DOUBLE" , "default" : 0.0 , "comment":"The default is a state variable"},
{"name" : "THP" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Pressure"},
{"name" : "BHP" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "Pressure"},
{"name" : "NGLRAT" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "LiquidSurfaceVolume/Time"}]}
Here we can see the following:
1. The items can be of types string, integer and float, the type is
specified with the "value_type" attribute which must equal
"STRING", "DOUBLE" or "INT".
2. You can optionally specify a default value, see the discussion of
the parsing workflow below for the treatment of defaults.
3. For items of type double you can specify a dimension, see XXXX for
the available dimensions. For quantities with a dimension the
parser will convert to SI units, and the DeckDoubleItem class has
a getSIDouble() and getRawDouble() method.
Items consuming the rest of the record
--------------------------------------
Most of the items will consume exactly one value from the input deck,
but it is also possible that the last item consumes the remaining
items in the input deck, these typically correspond to table keywords
or lists of memnonics. In the input deck the PVTG keyword will
typically appear like this:
PVTG
200 0.15 0.15 10
0.20 0.20 12
0.25 0.20 15 /
250 0.05 0.05 20
0.15 0.10 40 /
...
In the manual this is described as two tables with three columns, one
with three rows and one with two rows. The leading values of 200 and
250 are the pressure values where the two tables apply. The visual
formatting in the deck, and also the written desciption in the manual,
strongly hints at a table structure - however from a parsing point of
view this corresponds to just two records of different length. Both
records start with a pressure value, and then follows 3n consecutive
values. The item configuration of PVTG looks like this:
"items" : [
{"name":"GAS_PRESSURE", "value_type" : "DOUBLE", "dimension":"Pressure" },
{"name":"DATA", "size_type" : "ALL" , "value_type":"DOUBLE" ,
"dimension" : ["OilDissolutionFactor","OilDissolutionFactor","Viscosity"]}
]
I.e. first we consume one value from the input deck and assign it to
the GAS_PRESSURE item, then the DATA item has "size_type" : "ALL" -
meaning that this item will consume the the rest of the values in the
input record. Also observe that for the "DATA" item the dimension is a
vector of three elements, when converting to SI the dimension applied
to element i is given as:
dim[i] = dimension[i % 3]
In addition to tables the grid property keywords use items which
consume the rest of the record. For instance the PORO keyword will
typcially look like this in the input deck:
PORO
0.14 0.15 0.0 0.10
0.16 0.25 0.1 0.11
0.14 0.15 0.0 0.09
...
0.21 0.07 0.1 0.13
/
From a parsing point of view this is one single record; which contains
one item consuming all of the values in the input deck. In the
configuration this could have been configured as:
"items" : [{"name" : "DATA",
"value_type" : "DOUBLE" ,
"size_type" : "ALL" ,
"default" : 0 ,
"dimension" : "1"}]
However, since keywords containing large data arrays, like e.g. COORD
and PERMX are quite common a shortcut has been created for such
keywords, for instance the PORO keyword is configures as:
{"name" : "PORO" , "sections" : ["GRID"],
"data" : {"value_type" : "DOUBLE" , "default" : 0 , "dimension":"1"}}
i.e. the "data" attribute is used as shorthand to configure a keyword
with one record and one item which consumes all the data of the input
deck.
Multirecord keyword configuration
---------------------------------
Units and dimensions
--------------------
The values given in the input dataset are generally dimensionfull, and
before the simulator can start we must convert to internal SI values
based on the unit system used in the input deck. In the input deck the
different physical quantities are generally expressed with
per-quantity units. The unit system is *not* based on selecting a unit
for the fundamental dimensions length, mass and time and then deriving
composite units based on the dimension of the composite quantity. As a
consequence the list of dimensions supported by the parser is long,
and growing. The current list can be found in the source file:
opm/parser/eclipse/Units/UnitSystem.cpp
Default values
--------------
Classes:
--------
The library contains classes along two dimensions:
+----------------+ +----------------+ +----------------+
| Parser | | RawDeck | | Deck |
+----------------+ +----------------+ +----------------+
+----------------+ +----------------+ +----------------+
| ParserKeyword | | Rawkeyword | | DeckKeyword |
+----------------+ +----------------+ +----------------+
+----------------+ +----------------+ +----------------+
| ParserRecord | | RawRecord | | DeckRecord |
+----------------+ +----------------+ +----------------+
+----------------+ +----------------+
| ParserItem | | DeckItem |
+----------------+ +----------------+

66
examples/opmi.cpp Normal file
View File

@@ -0,0 +1,66 @@
/*
Copyright 2013 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 <iostream>
#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>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
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::Parser parser;
std::cout << "Loading deck: " << deck_file << " ..... "; std::cout.flush();
auto deck = parser.parseFile(deck_file, parseContext);
std::cout << "parse complete - creating EclipseState .... "; std::cout.flush();
Opm::EclipseState state( deck, parseContext );
Opm::Schedule schedule( deck, state.getInputGrid(), state.get3DProperties(), state.runspec().phases(), parseContext);
Opm::SummaryConfig summary( deck, schedule, state.getTableManager( ), parseContext );
std::cout << "complete." << std::endl;
dumpMessages( deck.getMessageContainer() );
}
int main(int argc, char** argv) {
for (int iarg = 1; iarg < argc; iarg++)
loadDeck( argv[iarg] );
}

247
external/cjson/README vendored Normal file
View File

@@ -0,0 +1,247 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
Welcome to cJSON.
cJSON aims to be the dumbest possible parser that you can get your job done with.
It's a single file of C, and a single header file.
JSON is described best here: http://www.json.org/
It's like XML, but fat-free. You use it to move data around, store things, or just
generally represent your program's state.
First up, how do I build?
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
For example, to build the test app:
gcc cJSON.c test.c -o test -lm
./test
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
in one of two modes: Auto and Manual. Let's have a quick run-through.
I lifted some JSON from this page: http://www.json.org/fatfree.html
That page inspired me to write cJSON, which is a parser that tries to share the same
philosophy as JSON itself. Simple, dumb, out of the way.
Some JSON:
{
"name": "Jack (\"Bee\") Nimble",
"format": {
"type": "rect",
"width": 1920,
"height": 1080,
"interlace": false,
"frame rate": 24
}
}
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
you have a char * to it. Everything is a cJSON struct.
Get it parsed:
cJSON *root = cJSON_Parse(my_json_string);
This is an object. We're in C. We don't have objects. But we do have structs.
What's the framerate?
cJSON *format = cJSON_GetObjectItem(root,"format");
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
Want to change the framerate?
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
Back to disk?
char *rendered=cJSON_Print(root);
Finished? Delete the root (this takes care of everything else).
cJSON_Delete(root);
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
before you dereference them. If you want to see how you'd build this struct in code?
cJSON *root,*fmt;
root=cJSON_CreateObject();
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
cJSON_AddStringToObject(fmt,"type", "rect");
cJSON_AddNumberToObject(fmt,"width", 1920);
cJSON_AddNumberToObject(fmt,"height", 1080);
cJSON_AddFalseToObject (fmt,"interlace");
cJSON_AddNumberToObject(fmt,"frame rate", 24);
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
a few from elsewhere.
What about manual mode? First up you need some detail.
Let's cover how the cJSON objects represent the JSON data.
cJSON doesn't distinguish arrays from objects in handling; just type.
Each cJSON has, potentially, a child, siblings, value, a name.
The root object has: Object Type and a Child
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
Sibling has type Object, name "format", and a child.
That child has type String, name "type", value "rect", and a sibling:
Sibling has type Number, name "width", value 1920, and a sibling:
Sibling has type Number, name "height", value 1080, and a sibling:
Sibling hs type False, name "interlace", and a sibling:
Sibling has type Number, name "frame rate", value 24
Here's the structure:
typedef struct cJSON {
struct cJSON *next,*prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
} cJSON;
By default all values are 0 unless set by virtue of being meaningful.
next/prev is a doubly linked list of siblings. next takes you to your sibling,
prev takes you back from your sibling to you.
Only objects and arrays have a "child", and it's the head of the doubly linked list.
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
cJSON.h
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
valuedouble.
Any entry which is in the linked list which is the child of an object will have a "string"
which is the "name" of the entry. When I said "name" in the above example, that's "string".
"string" is the JSON name for the 'variable name' if you will.
Now you can trivially walk the lists, recursively, and parse as you please.
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
the root object, and traverse the structure (which is, formally, an N-tree),
and tokenise as you please. If you wanted to build a callback style parser, this is how
you'd do it (just an example, since these things are very specific):
void parse_and_callback(cJSON *item,const char *prefix)
{
while (item)
{
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
sprintf(newprefix,"%s/%s",prefix,item->name);
int dorecurse=callback(newprefix, item->type, item);
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
item=item->next;
free(newprefix);
}
}
The prefix process will build you a separated list, to simplify your callback handling.
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
let you invoke it per-item. For the item above, your callback might look like this:
int callback(const char *name,int type,cJSON *item)
{
if (!strcmp(name,"name")) { /* populate name */ }
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
else if (!strcmp(name,"format/width") { /* 800 */ }
else if (!strcmp(name,"format/height") { /* 600 */ }
else if (!strcmp(name,"format/interlace") { /* false */ }
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
return 1;
}
Alternatively, you might like to parse iteratively.
You'd use:
void parse_object(cJSON *item)
{
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
{
cJSON *subitem=cJSON_GetArrayItem(item,i);
// handle subitem.
}
}
Or, for PROPER manual mode:
void parse_object(cJSON *item)
{
cJSON *subitem=item->child;
while (subitem)
{
// handle subitem
if (subitem->child) parse_object(subitem->child);
subitem=subitem->next;
}
}
Of course, this should look familiar, since this is just a stripped-down version
of the callback-parser.
This should cover most uses you'll find for parsing. The rest should be possible
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
In terms of constructing JSON data, the example code above is the right way to do it.
You can, of course, hand your sub-objects to other functions to populate.
Also, if you find a use for it, you can manually build the objects.
For instance, suppose you wanted to build an array of objects?
cJSON *objects[24];
cJSON *Create_array_of_anything(cJSON **items,int num)
{
int i;cJSON *prev, *root=cJSON_CreateArray();
for (i=0;i<24;i++)
{
if (!i) root->child=objects[i];
else prev->next=objects[i], objects[i]->prev=prev;
prev=objects[i];
}
return root;
}
and simply: Create_array_of_anything(objects,24);
cJSON doesn't make any assumptions about what order you create things in.
You can attach the objects, as above, and later add children to each
of those objects.
As soon as you call cJSON_Print, it renders the structure to text.
The test.c code shows how to handle a bunch of typical cases. If you uncomment
the code, it'll load, parse and print a bunch of test files, also from json.org,
which are more complex than I'd care to try and stash into a const char array[].
Enjoy cJSON!
- Dave Gamble, Aug 2009

4
external/cjson/README.opm vendored Normal file
View File

@@ -0,0 +1,4 @@
This directory contains the cJSON package downloaded unchanged from:
http://sourceforge.net/projects/cjson/. The cJSON package is plain C,
the JsonObject class provides a minimal C++ wrapping of this.

569
external/cjson/cJSON.c vendored Normal file
View File

@@ -0,0 +1,569 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* cJSON */
/* JSON parser in C. */
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"
static const char *ep;
const char *cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
len = strlen(str) + 1;
if (!(copy = (char*)cJSON_malloc(len))) return 0;
memcpy(copy,str,len);
return copy;
}
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
return node;
}
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
/* Could use sscanf for this? */
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item)
{
char *str;
double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
sscanf(ptr+3,"%4x",&uc2);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
const char *end=0;
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value));
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); }
ep=value;return 0; /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt)
{
char *out=0;
if (!item) return 0;
switch ((item->type)&255)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item);break;
case cJSON_String: out=print_string(item);break;
case cJSON_Array: out=print_array(item,depth,fmt);break;
case cJSON_Object: out=print_object(item,depth,fmt);break;
}
return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */
item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}
if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt)
{
char **entries;
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
if (!numentries)
{
out=(char*)cJSON_malloc(3);
if (out) strcpy(out,"[]");
return out;
}
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+1,fmt);
entries[i++]=ret;
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
for (i=0;i<numentries;i++)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+1)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt)
{
char **entries=0,**names=0;
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
cJSON *child=item->child;
int numentries=0,fail=0;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Explicitly handle empty object case */
if (!numentries)
{
out=(char*)cJSON_malloc(fmt?depth+3:3);
if (!out) return 0;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
*ptr++='}';*ptr++=0;
return out;
}
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
/* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string);
entries[i++]=ret=print_value(child,depth,fmt);
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
{
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
}
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
cJSON *newitem,*cptr,*nptr=0,*newchild;
/* Bail on bad ptr */
if (!item) return 0;
/* Create new item */
newitem=cJSON_New_Item();
if (!newitem) return 0;
/* Copy over all vars */
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
/* If non-recursive, then we're done! */
if (!recurse) return newitem;
/* Walk the ->next chain for the child. */
cptr=item->child;
while (cptr)
{
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) {cJSON_Delete(newitem);return 0;}
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
cptr=cptr->next;
}
return newitem;
}

143
external/cjson/cJSON.h vendored Normal file
View File

@@ -0,0 +1,143 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#include <stdlib.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#ifdef __cplusplus
}
#endif
#endif

70
opm/json/JsonObject.hpp Normal file
View File

@@ -0,0 +1,70 @@
/*
Copyright 2013 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 JSON_OBJECT_HPP
#define JSON_OBJECT_HPP
#include <string>
#include <boost/filesystem/path.hpp>
struct cJSON;
namespace Json {
class JsonObject {
public:
explicit JsonObject(const boost::filesystem::path& jsonFile );
explicit JsonObject(const std::string& inline_json);
explicit JsonObject(const char * inline_json);
explicit JsonObject(cJSON * root);
~JsonObject();
bool has_item(const std::string& key) const;
JsonObject get_array_item( size_t index ) const;
JsonObject get_item(const std::string& key) const;
std::string to_string() const;
std::string get_string(const std::string& key) const;
std::string as_string() const;
bool is_string( ) const;
bool is_number( ) const;
int get_int(const std::string& key) const;
int as_int() const;
double get_double(const std::string& key) const;
double as_double() const;
bool is_array( ) const;
bool is_object( ) const;
size_t size() const;
private:
JsonObject get_scalar_object(const std::string& key) const;
void initialize(const std::string& inline_json);
cJSON * root;
bool owner;
};
}
#endif

View File

@@ -0,0 +1,164 @@
/*
Copyright 2013 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 DECK_HPP
#define DECK_HPP
#include <map>
#include <memory>
#include <ostream>
#include <vector>
#include <string>
#include <boost/filesystem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#ifdef OPM_PARSER_DECK_API_WARNING
#ifndef OPM_PARSER_DECK_API
#pragma message "\n\n" \
" ----------------------------------------------------------------------------------\n" \
" The current compilation unit includes the header Deck.hpp. Outside of opm-parser \n" \
" you are encouraged to use the EclipseState API instead of the low level Deck API. \n" \
" If use of the Deck API is absolutely necessary you can silence this warning with \n" \
" #define OPM_PARSER_DECK_API before including the Deck.hpp header. \n" \
" ----------------------------------------------------------------------------------\n" \
""
#endif
#endif
namespace Opm {
/*
* The Deck (container) class owns all memory given to it via .addX(), as
* do all inner objects. This means that the Deck object itself must stay
* alive as long as DeckItem (and friends) are needed, to avoid
* use-after-free.
*/
class DeckOutput;
class DeckView {
public:
typedef std::vector< DeckKeyword >::const_iterator const_iterator;
bool hasKeyword( const DeckKeyword& keyword ) const;
bool hasKeyword( const std::string& keyword ) const;
template< class Keyword >
bool hasKeyword() const {
return hasKeyword( Keyword::keywordName );
}
const DeckKeyword& getKeyword( const std::string& keyword, size_t index ) const;
const DeckKeyword& getKeyword( const std::string& keyword ) const;
const DeckKeyword& getKeyword( size_t index ) const;
DeckKeyword& getKeyword( size_t index );
template< class Keyword >
const DeckKeyword& getKeyword() const {
return getKeyword( Keyword::keywordName );
}
template< class Keyword >
const DeckKeyword& getKeyword( size_t index ) const {
return getKeyword( Keyword::keywordName, index );
}
const std::vector< const DeckKeyword* > getKeywordList( const std::string& keyword ) const;
template< class Keyword >
const std::vector< const DeckKeyword* > getKeywordList() const {
return getKeywordList( Keyword::keywordName );
}
size_t count(const std::string& keyword) const;
size_t size() const;
const_iterator begin() const;
const_iterator end() const;
protected:
void add( const DeckKeyword*, const_iterator, const_iterator );
const std::vector< size_t >& offsets( const std::string& ) const;
DeckView( const_iterator first, const_iterator last );
explicit DeckView( std::pair< const_iterator, const_iterator > );
void reinit( const_iterator, const_iterator );
private:
const_iterator first;
const_iterator last;
std::map< std::string, std::vector< size_t > > keywordMap;
};
class Deck : private DeckView {
public:
using DeckView::const_iterator;
using DeckView::hasKeyword;
using DeckView::getKeyword;
using DeckView::getKeywordList;
using DeckView::count;
using DeckView::size;
using DeckView::begin;
using DeckView::end;
using iterator = std::vector< DeckKeyword >::iterator;
Deck();
// cppcheck-suppress noExplicitConstructor
Deck( std::initializer_list< DeckKeyword > );
// cppcheck-suppress noExplicitConstructor
Deck( std::initializer_list< std::string > );
Deck( const Deck& );
void addKeyword( DeckKeyword&& keyword );
void addKeyword( const DeckKeyword& keyword );
DeckKeyword& getKeyword( size_t );
MessageContainer& getMessageContainer() const;
const UnitSystem& getDefaultUnitSystem() const;
const UnitSystem& getActiveUnitSystem() const;
UnitSystem& getActiveUnitSystem();
UnitSystem& getDefaultUnitSystem();
const std::string getDataFile() const;
void setDataFile(const std::string& dataFile);
iterator begin();
iterator end();
void write( DeckOutput& output ) const ;
friend std::ostream& operator<<(std::ostream& os, const Deck& deck);
private:
Deck( std::vector< DeckKeyword >&& );
std::vector< DeckKeyword > keywordList;
mutable MessageContainer m_messageContainer;
UnitSystem defaultUnits;
UnitSystem activeUnits;
std::string m_dataFile;
};
}
#endif /* DECK_HPP */

View File

@@ -0,0 +1,130 @@
/*
Copyright 2013 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 DECKITEM_HPP
#define DECKITEM_HPP
#include <string>
#include <vector>
#include <memory>
#include <ostream>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/Utility/Typetools.hpp>
namespace Opm {
class DeckOutput;
class DeckItem {
public:
DeckItem() = default;
explicit DeckItem( const std::string& );
DeckItem( const std::string&, int, size_t size_hint = 8 );
DeckItem( const std::string&, double, size_t size_hint = 8 );
DeckItem( const std::string&, std::string, size_t size_hint = 8 );
const std::string& name() const;
// return true if the default value was used for a given data point
bool defaultApplied( size_t ) const;
// Return true if the item has a value for the current index;
// does not differentiate between default values from the
// config and values which have been set in the deck.
bool hasValue( size_t ) const;
// if the number returned by this method is less than what is semantically
// expected (e.g. size() is less than the number of cells in the grid for
// keywords like e.g. SGL), then the remaining values are defaulted. The deck
// creates the defaulted items if all their sizes are fully specified by the
// keyword, though...
size_t size() const;
size_t out_size() const;
template< typename T > const T& get( size_t ) const;
double getSIDouble( size_t ) const;
std::string getTrimmedString( size_t ) const;
template< typename T > const std::vector< T >& getData() const;
const std::vector< double >& getSIDoubleData() const;
void push_back( int );
void push_back( double );
void push_back( std::string );
void push_back( int, size_t );
void push_back( double, size_t );
void push_back( std::string, size_t );
void push_backDefault( int );
void push_backDefault( double );
void push_backDefault( std::string );
// trying to access the data of a "dummy default item" will raise an exception
void push_backDummyDefault();
void push_backDimension( const Dimension& /* activeDimension */,
const Dimension& /* defaultDimension */);
type_tag getType() const;
void write(DeckOutput& writer) const;
friend std::ostream& operator<<(std::ostream& os, const DeckItem& item);
/*
The comparison can be adjusted with the cmp_default and
cmp_numeric flags. If cmp_default is set to true the
comparison will take the defaulted status of the items into
account, i.e. two items will compare differently if one is
defaulted and the other has the default value explicitly
set. The default behaviour is cmp_default == false -
i.e. only the actual values in the items will be compared,
itrespective of whether they have been set explicitly or
have been defaulted.
*/
bool equal(const DeckItem& other, bool cmp_default, bool cmp_numeric) const;
/*
The operator== is implemented based on the equal( ) method,
with the arguments cmp_default=false and cmp_numeric=true.
*/
bool operator==(const DeckItem& other) const;
bool operator!=(const DeckItem& other) const;
private:
std::vector< double > dval;
std::vector< int > ival;
std::vector< std::string > sval;
type_tag type = type_tag::unknown;
std::string item_name;
std::vector< bool > defaulted;
std::vector< Dimension > dimensions;
mutable std::vector< double > SIdata;
template< typename T > std::vector< T >& value_ref();
template< typename T > const std::vector< T >& value_ref() const;
template< typename T > void push( T );
template< typename T > void push( T, size_t );
template< typename T > void push_default( T );
template< typename T > void write_vector(DeckOutput& writer, const std::vector<T>& data) const;
};
}
#endif /* DECKITEM_HPP */

View File

@@ -0,0 +1,93 @@
/*
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 DECKKEYWORD_HPP
#define DECKKEYWORD_HPP
#include <string>
#include <vector>
#include <memory>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
namespace Opm {
class ParserKeyword;
class DeckOutput;
class DeckKeyword {
public:
typedef std::vector< DeckRecord >::const_iterator const_iterator;
explicit DeckKeyword(const std::string& keywordName);
DeckKeyword(const std::string& keywordName, bool knownKeyword);
const std::string& name() const;
void setFixedSize();
void setLocation(const std::string& fileName, int lineNumber);
const std::string& getFileName() const;
int getLineNumber() const;
size_t size() const;
void addRecord(DeckRecord&& record);
const DeckRecord& getRecord(size_t index) const;
DeckRecord& getRecord(size_t index);
const DeckRecord& getDataRecord() const;
void setDataKeyword(bool isDataKeyword = true);
bool isKnown() const;
bool isDataKeyword() const;
const std::vector<int>& getIntData() const;
const std::vector<double>& getRawDoubleData() const;
const std::vector<double>& getSIDoubleData() const;
const std::vector<std::string>& getStringData() const;
size_t getDataSize() const;
void write( DeckOutput& output ) const;
void write_data( DeckOutput& output ) const;
void write_TITLE( DeckOutput& output ) const;
template <class Keyword>
bool isKeyword() const {
if (Keyword::keywordName == m_keywordName)
return true;
else
return false;
}
const_iterator begin() const;
const_iterator end() const;
bool equal_data(const DeckKeyword& other, bool cmp_default = false, bool cmp_numeric = true) const;
bool equal(const DeckKeyword& other, bool cmp_default = false, bool cmp_numeric = true) const;
bool operator==(const DeckKeyword& other) const;
bool operator!=(const DeckKeyword& other) const;
friend std::ostream& operator<<(std::ostream& os, const DeckKeyword& keyword);
private:
std::string m_keywordName;
std::string m_fileName;
int m_lineNumber;
std::vector< DeckRecord > m_recordList;
bool m_knownKeyword;
bool m_isDataKeyword;
bool m_slashTerminated;
};
}
#endif /* DECKKEYWORD_HPP */

View File

@@ -0,0 +1,61 @@
/*
Copyright 2017 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 DECK_OUTPUT_HPP
#define DECK_OUTPUT_HPP
#include <ostream>
#include <string>
#include <cstddef>
namespace Opm {
class DeckOutput {
public:
explicit DeckOutput(std::ostream& s);
void stash_default( );
void start_record( );
void end_record( );
void split_record();
void start_keyword(const std::string& kw);
void end_keyword(bool add_slash);
void endl();
void write_string(const std::string& s);
template <typename T> void write(const T& value);
std::string item_sep = " "; // Separator between items on a row.
size_t columns = 16; // The maximum number of columns on a record.
std::string record_indent = " "; // The indentation when starting a new line.
std::string keyword_sep = "\n\n"; // The separation between keywords;
private:
std::ostream& os;
size_t default_count;
size_t row_count;
bool record_on;
template <typename T> void write_value(const T& value);
void write_sep( );
};
}
#endif

View File

@@ -0,0 +1,80 @@
/*
Copyright 2013 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 DECKRECORD_HPP
#define DECKRECORD_HPP
#include <string>
#include <vector>
#include <memory>
#include <ostream>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
namespace Opm {
class DeckRecord {
public:
typedef std::vector< DeckItem >::const_iterator const_iterator;
DeckRecord() = default;
DeckRecord( std::vector< DeckItem >&& );
size_t size() const;
void addItem( DeckItem deckItem );
DeckItem& getItem( size_t index );
DeckItem& getItem( const std::string& name );
DeckItem& getDataItem();
const DeckItem& getItem( size_t index ) const;
const DeckItem& getItem( const std::string& name ) const;
const DeckItem& getDataItem() const;
bool hasItem(const std::string& name) const;
template <class Item>
DeckItem& getItem() {
return getItem( Item::itemName );
}
template <class Item>
const DeckItem& getItem() const {
return getItem( Item::itemName );
}
const_iterator begin() const;
const_iterator end() const;
void write(DeckOutput& writer) const;
void write_data(DeckOutput& writer) const;
friend std::ostream& operator<<(std::ostream& os, const DeckRecord& record);
bool equal(const DeckRecord& other, bool cmp_default, bool cmp_numeric) const;
bool operator==(const DeckRecord& other) const;
bool operator!=(const DeckRecord& other) const;
private:
std::vector< DeckItem > m_items;
};
}
#endif /* DECKRECORD_HPP */

View File

@@ -0,0 +1,110 @@
/*
Copyright 2013 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 SECTION_HPP
#define SECTION_HPP
#include <string>
#include <opm/parser/eclipse/Deck/Deck.hpp>
namespace Opm {
class UnitSystem;
class Parser;
class Section : public DeckView {
public:
using DeckView::const_iterator;
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& );
static bool hasEDIT( const Deck& );
static bool hasPROPS( const Deck& );
static bool hasREGIONS( const Deck& );
static bool hasSOLUTION( const Deck& );
static bool hasSUMMARY( const Deck& );
static bool hasSCHEDULE( const Deck& );
// returns whether the deck has all mandatory sections and if all sections are in
// the right order
static bool checkSectionTopology(const Deck& deck,
const Parser&,
bool ensureKeywordSectionAffiliation = false);
private:
std::string section_name;
const UnitSystem& units;
};
class RUNSPECSection : public Section {
public:
using Section::const_iterator;
explicit RUNSPECSection(const Deck& deck) : Section(deck, "RUNSPEC") {}
};
class GRIDSection : public Section {
public:
using Section::const_iterator;
explicit GRIDSection(const Deck& deck) : Section(deck, "GRID") {}
};
class EDITSection : public Section {
public:
using Section::const_iterator;
explicit EDITSection(const Deck& deck) : Section(deck, "EDIT") {}
};
class PROPSSection : public Section {
public:
using Section::const_iterator;
explicit PROPSSection(const Deck& deck) : Section(deck, "PROPS") {}
};
class REGIONSSection : public Section {
public:
using Section::const_iterator;
explicit REGIONSSection(const Deck& deck) : Section(deck, "REGIONS") {}
};
class SOLUTIONSection : public Section {
public:
using Section::const_iterator;
explicit SOLUTIONSection(const Deck& deck) : Section(deck, "SOLUTION") {}
};
class SUMMARYSection : public Section {
public:
using Section::const_iterator;
explicit SUMMARYSection(const Deck& deck) : Section(deck, "SUMMARY") {}
};
class SCHEDULESection : public Section {
public:
using Section::const_iterator;
explicit SCHEDULESection(const Deck& deck) : Section(deck, "SCHEDULE") {}
};
}
#endif // SECTION_HPP

View File

@@ -0,0 +1,71 @@
/*
Copyright (C) 2017 TNO
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_AQUANCON_HPP
#define OPM_AQUANCON_HPP
/*
Aquancon is a data container object meant to hold the data from the AQUANCON keyword.
This also includes the logic for parsing and connections to grid cells. It is meant to be used by opm-grid and opm-simulators in order to
implement the analytical aquifer models in OPM Flow.
*/
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
namespace Opm {
namespace{
struct AquanconRecord;
}
class Aquancon {
public:
struct AquanconOutput{
int aquiferID;
std::vector<size_t> global_index;
std::vector<double> influx_coeff; // Size = size(global_index)
std::vector<double> influx_multiplier; // Size = size(global_index)
std::vector<int> reservoir_face_dir; // Size = size(global_index)
};
Aquancon(const EclipseGrid& grid, const Deck& deck);
const std::vector<Aquancon::AquanconOutput>& getAquOutput() const;
private:
void logic_application(std::vector<Aquancon::AquanconOutput>& output_vector);
void collate_function(std::vector<Aquancon::AquanconOutput>& output_vector,
std::vector<Opm::AquanconRecord>& m_aqurecord,
std::vector<int> m_aquiferID_per_record, int m_maxAquID);
void convert_record_id_to_aquifer_id(std::vector<int>& record_indices_matching_id, int i,
std::vector<int> m_aquiferID_per_record);
std::vector<Aquancon::AquanconOutput> m_aquoutput;
};
}
#endif

View File

@@ -0,0 +1,98 @@
/*
Copyright (C) 2017 TNO
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_AQUIFERCT_HPP
#define OPM_AQUIFERCT_HPP
/*
The AquiferCT which stands for AquiferCarterTracy is a data container object meant to hold the data for the aquifer carter tracy model.
This includes the logic for parsing as well as the associated tables. It is meant to be used by opm-grid and opm-simulators in order to
implement the Carter Tracy analytical aquifer model in OPM Flow.
*/
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/Aqudims.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp>
#include <boost/concept_check.hpp>
namespace Opm {
class AquiferCT {
public:
struct AQUCT_data{
// Aquifer ID
int aquiferID;
// Table IDs
int inftableID, pvttableID;
std::vector<int> cell_id;
// Variables constants
double phi_aq , //aquifer porosity
d0, //aquifer datum depth
C_t , //total compressibility
r_o , //aquifer inner radius
k_a , //aquifer permeability
c1, // 0.008527 (METRIC, PVT-M); 0.006328 (FIELD); 3.6 (LAB)
h , //aquifer thickness
theta , //angle subtended by the aquifer boundary
c2 ; //6.283 (METRIC, PVT-M); 1.1191 (FIELD); 6.283 (LAB).
std::vector<double> td, pi;
};
AquiferCT(const EclipseState& eclState, const Deck& deck);
const std::vector<AquiferCT::AQUCT_data>& getAquifers() const;
int getAqInflTabID(size_t aquiferIndex);
int getAqPvtTabID(size_t aquiferIndex);
private:
std::vector<AquiferCT::AQUCT_data> m_aquct;
//Set the default Pd v/s Td tables (constant terminal rate case for an infinite aquifer) as described in
//Van Everdingen, A. & Hurst, W., December, 1949.The Application of the Laplace Transformation to Flow Problems in Reservoirs.
//Petroleum Transactions, AIME.
inline void set_default_tables(std::vector<double>& td, std::vector<double>& pi)
{
std::vector<double> default_pressure_ = { 0.112, 0.229, 0.315, 0.376, 0.424, 0.469, 0.503, 0.564, 0.616, 0.659, 0.702, 0.735,
0.772, 0.802, 0.927, 1.02, 1.101, 1.169, 1.275, 1.362, 1.436, 1.5, 1.556, 1.604,
1.651, 1.829, 1.96, 2.067, 2.147, 2.282, 2.388, 2.476, 2.55, 2.615, 2.672, 2.723,
2.921, 3.064, 3.173, 3.263, 3.406, 3.516, 3.608, 3.684, 3.75, 3.809, 3.86 };
std::vector<double> default_time_ = { 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
1.5, 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60, 70,
80, 90, 100, 150, 200, 250, 300, 400, 500, 600, 700, 800, 900, 1000 };
td = default_time_;
pi = default_pressure_;
}
};
}
#endif

View File

@@ -0,0 +1,104 @@
/*
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_ECLIPSE_PROPERTIES_HPP
#define OPM_ECLIPSE_PROPERTIES_HPP
#include <vector>
#include <string>
#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/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
namespace Opm {
class Box;
class BoxManager;
class Deck;
class DeckItem;
class DeckKeyword;
class DeckRecord;
class EclipseGrid;
class Section;
class TableManager;
class UnitSystem;
/// Class representing properties on 3D grid for use in EclipseState.
class Eclipse3DProperties
{
public:
Eclipse3DProperties() = default;
Eclipse3DProperties(const Deck& deck,
const TableManager& tableManager,
const EclipseGrid& eclipseGrid);
std::vector< int > getRegions( const std::string& keyword ) const;
std::string getDefaultRegionKeyword() const;
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;
MessageContainer getMessageContainer();
private:
const GridProperty<int>& getRegion(const DeckItem& regionItem) const;
void processGridProperties(const Deck& deck,
const EclipseGrid& eclipseGrid);
void scanSection(const Section& section,
const EclipseGrid& eclipseGrid);
void handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleBOXKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleCOPYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleENDBOXKeyword( BoxManager& boxManager);
void handleEQUALSKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMAXVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMINVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMULTIPLYKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleADDREGKeyword( const DeckKeyword& deckKeyword );
void handleCOPYREGKeyword( const DeckKeyword& deckKeyword );
void handleEQUALREGKeyword(const DeckKeyword& deckKeyword );
void handleMULTIREGKeyword(const DeckKeyword& deckKeyword );
void handleOPERATEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void loadGridPropertyFromDeckKeyword(const Box& inputBox,
const DeckKeyword& deckKeyword);
std::string m_defaultRegion;
UnitSystem m_deckUnitSystem;
GridProperties<int> m_intGridProperties;
GridProperties<double> m_doubleGridProperties;
};
}
#endif // OPM_ECLIPSE_PROPERTIES_HPP

View File

@@ -0,0 +1,52 @@
/*
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_ECLIPSE_CONFIG_HPP
#define OPM_ECLIPSE_CONFIG_HPP
#include <memory>
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
namespace Opm {
class Deck;
class EclipseConfig
{
public:
EclipseConfig(const Deck& deck);
const InitConfig& init() const;
const IOConfig& io() const;
IOConfig& io();
const RestartConfig& restart() const;
const InitConfig& getInitConfig() const;
const RestartConfig& getRestartConfig() const;
private:
IOConfig m_ioConfig;
const InitConfig m_initConfig;
RestartConfig m_restartConfig;
};
}
#endif // OPM_ECLIPSE_CONFIG_HPP

View File

@@ -0,0 +1,138 @@
/*
Copyright 2013 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_ECLIPSE_STATE_HPP
#define OPM_ECLIPSE_STATE_HPP
#include <memory>
#include <vector>
#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/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
namespace Opm {
template< typename > class GridProperty;
template< typename > class GridProperties;
class Box;
class BoxManager;
class Deck;
class DeckItem;
class DeckKeyword;
class DeckRecord;
class EclipseGrid;
class InitConfig;
class IOConfig;
class ParseContext;
class RestartConfig;
class Section;
class SimulationConfig;
class TableManager;
class UnitSystem;
class EclipseState {
public:
enum EnabledTypes {
IntProperties = 0x01,
DoubleProperties = 0x02,
AllProperties = IntProperties | DoubleProperties
};
EclipseState(const Deck& deck , ParseContext parseContext = ParseContext());
const ParseContext& getParseContext() const;
const IOConfig& getIOConfig() const;
IOConfig& getIOConfig();
const InitConfig& getInitConfig() const;
const SimulationConfig& getSimulationConfig() const;
const RestartConfig& getRestartConfig() const;
RestartConfig& getRestartConfig();
const EclipseGrid& getInputGrid() const;
const FaultCollection& getFaults() const;
const TransMult& getTransMult() const;
/// non-neighboring connections
/// the non-standard adjacencies as specified in input deck
const NNC& getInputNNC() const;
bool hasInputNNC() const;
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
// units...
const UnitSystem& getDeckUnitSystem() const;
const UnitSystem& getUnits() const;
const MessageContainer& getMessageContainer() const;
MessageContainer& getMessageContainer();
std::string getTitle() const;
void applyModifierDeck(const Deck& deck);
const Runspec& runspec() const;
private:
void initIOConfigPostSchedule(const Deck& deck);
void initTransMult();
void initFaults(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;
Runspec m_runspec;
EclipseConfig m_eclipseConfig;
UnitSystem m_deckUnitSystem;
NNC m_inputNnc;
EclipseGrid m_inputGrid;
Eclipse3DProperties m_eclipseProperties;
const SimulationConfig m_simulationConfig;
TransMult m_transMult;
FaultCollection m_faults;
std::string m_title;
MessageContainer m_messageContainer;
};
}
#endif // OPM_ECLIPSE_STATE_HPP

View File

@@ -0,0 +1,56 @@
/*
Copyright 2017 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_ENDPOINTSCALING_HPP
#define OPM_ENDPOINTSCALING_HPP
#include <bitset>
namespace Opm {
class Deck;
class EndpointScaling {
public:
EndpointScaling() noexcept = default;
explicit EndpointScaling( const Deck& );
/* true if endpoint scaling is enabled, otherwise false */
operator bool() const noexcept;
bool directional() const noexcept;
bool nondirectional() const noexcept;
bool reversible() const noexcept;
bool irreversible() const noexcept;
bool twopoint() const noexcept;
bool threepoint() const noexcept;
private:
enum class option {
any = 0,
directional = 1,
reversible = 2,
threepoint = 3,
};
using ue = std::underlying_type< option >::type;
std::bitset< 4 > options;
};
}
#endif

View File

@@ -0,0 +1,68 @@
/*
Copyright 2014 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 BOX_HPP_
#define BOX_HPP_
#include <vector>
#include <cstddef>
namespace Opm {
class Box {
public:
Box() = default;
Box(int nx , int ny , int nz);
Box(const Box& globalBox , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); // Zero offset coordinates.
Box(int nx, int ny, int nz, int i1 , int i2 , int j1 , int j2 , int k1 , int k2);
size_t size() const;
bool isGlobal() const;
size_t getDim(size_t idim) const;
const std::vector<size_t>& getIndexList() const;
bool equal(const Box& other) const;
explicit operator bool() const;
std::vector<size_t>::const_iterator begin() const;
std::vector<size_t>::const_iterator end() const;
int I1() const;
int I2() const;
int J1() const;
int J2() const;
int K1() const;
int K2() const;
private:
void initIndexList();
size_t m_dims[3] = { 0, 0, 0 };
size_t m_offset[3];
size_t m_stride[3];
bool m_isGlobal;
std::vector<size_t> m_indexList;
int lower(int dim) const;
int upper(int dim) const;
};
}
#endif

View File

@@ -0,0 +1,78 @@
/*
Copyright 2014 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 BOXMANAGER_HPP_
#define BOXMANAGER_HPP_
#include <vector>
#include <memory>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
/*
This class implements a simple book keeping system for the current
input box. In general there are three different input boxes which
are relevant:
1. The global box give by the complete dimensions of the grid.
2. The input box given explicitly by the BOX keyword. That BOX will
apply to all following FIELD properties, and it will continue
to apply until either:
- ENDBOX
- A new BOX
- End of current section
is encountered.
3. Some keywords allow for a Box which applies only to the elements
of that keyword.
*/
namespace Opm {
class BoxManager {
public:
BoxManager(int nx , int ny , int nz);
void setInputBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
void setKeywordBox( int i1,int i2 , int j1 , int j2 , int k1 , int k2);
void endSection();
void endInputBox();
void endKeyword();
const Box& getActiveBox() const;
const Box& getGlobalBox() const;
const Box& getInputBox() const;
const Box& getKeywordBox() const;
private:
Box m_globalBox;
Box m_inputBox;
Box m_keywordBox;
};
}
#endif

View File

@@ -0,0 +1,286 @@
/*
Copyright 2014 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_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>
#include <ert/util/ert_unique_ptr.hpp>
#include <array>
#include <memory>
#include <vector>
namespace Opm {
class Deck;
class ZcornMapper;
/**
About cell information and dimension: The actual grid
information is held in a pointer to an ERT ecl_grid_type
instance. This pointer must be used for access to all cell
related properties, including:
- Size of cells
- Real world position of cells
- Active/inactive status of cells
*/
class EclipseGrid : public GridDims {
public:
explicit EclipseGrid(const std::string& filename);
/*
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.
EclipseGrid(const Deck& deck, const int * actnum = nullptr);
static bool hasCylindricalKeywords(const Deck& deck);
static bool hasCornerPointKeywords(const Deck&);
static bool hasCartesianKeywords(const Deck&);
size_t getNumActive( ) 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;
/*
For RADIAL grids you can *optionally* use the keyword
'CIRCLE' to denote that period boundary conditions should be
applied in the 'THETA' direction; this will only apply if
the theta keywords entered sum up to exactly 360 degrees!
*/
bool circle( ) const;
bool isPinchActive( ) const;
double getPinchThresholdThickness( ) const;
PinchMode::ModeEnum getPinchOption( ) const;
PinchMode::ModeEnum getMultzOption( ) const;
MinpvMode::ModeEnum getMinpvMode() const;
double getMinpvValue( ) 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;
}
}
/// 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;
std::array<double, 3> getCornerPos(size_t i,size_t j, size_t k, size_t corner_index) const;
double getCellVolume(size_t globalIndex) const;
double getCellVolume(size_t i , size_t j , size_t k) const;
double getCellThicknes(size_t globalIndex) const;
double getCellThicknes(size_t i , size_t j , size_t k) const;
std::array<double, 3> getCellDims(size_t i,size_t j, size_t k) const;
std::array<double, 3> getCellDims(size_t globalIndex) const;
bool cellActive( size_t globalIndex ) const;
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;
/*
The exportZCORN method will adjust the z coordinates to ensure that cells do not
overlap. The return value is the number of points which have been adjusted.
*/
size_t exportZCORN( std::vector<double>& zcorn) const;
void exportMAPAXES( std::vector<double>& mapaxes) const;
void exportCOORD( std::vector<double>& coord) const;
void exportACTNUM( std::vector<int>& actnum) const;
void resetACTNUM( const int * actnum);
bool equal(const EclipseGrid& other) const;
const ecl_grid_type * c_ptr() const;
const MessageContainer& getMessageContainer() const;
MessageContainer& getMessageContainer();
private:
MessageContainer m_messages;
double m_minpvValue;
MinpvMode::ModeEnum m_minpvMode;
Value<double> m_pinch;
PinchMode::ModeEnum m_pinchoutMode;
PinchMode::ModeEnum m_multzMode;
mutable std::vector< int > activeMap;
bool m_circle = false;
/*
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 initCornerPointGrid(const std::array<int,3>& dims ,
const std::vector<double>& coord ,
const std::vector<double>& zcorn ,
const int * actnum,
const double * mapaxes);
void initCylindricalGrid( const std::array<int, 3>&, const Deck&);
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&);
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::array<int, 3>& dims, const std::vector<double>& DZ,
const Deck&);
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::array<int, 3>& dims , size_t dim , const std::vector<double>& DV , std::vector<double>& D);
};
class CoordMapper {
public:
CoordMapper(size_t nx, size_t ny);
size_t size() const;
/*
dim = 0,1,2 for x, y and z coordinate respectively.
layer = 0,1 for k=0 and k=nz layers respectively.
*/
size_t index(size_t i, size_t j, size_t dim, size_t layer) const;
private:
size_t nx;
size_t ny;
};
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;
size_t size() const;
/*
The fixupZCORN method will take a zcorn vector as input and
run through it. If the following situation is detected:
/| /|
/ | / |
/ | / |
/ | / |
/ | ==> / |
/ | / |
---/------x /---------x
| /
|/
*/
size_t fixupZCORN( std::vector<double>& zcorn);
bool validZCORN( const std::vector<double>& zcorn) const;
private:
std::array<size_t,3> dims;
std::array<size_t,3> stride;
std::array<size_t,8> cell_shift;
};
}
#endif // OPM_PARSER_ECLIPSE_GRID_HPP

View File

@@ -0,0 +1,49 @@
/*
Copyright 2014 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_FACEDIR_HPP
#define OPM_FACEDIR_HPP
#include <string>
namespace Opm {
namespace FaceDir {
enum DirEnum {
XPlus = 1,
XMinus = 2,
YPlus = 4,
YMinus = 8,
ZPlus = 16,
ZMinus = 32
};
/**
The MULTREGTScanner will use these values as bitmaps;
i.e. it is essential they form a 2^n sequence.
*/
DirEnum FromString(const std::string& stringValue);
int FromMULTREGTString(const std::string& stringValue);
}
}
#endif

View File

@@ -0,0 +1,55 @@
/*
Copyright 2014 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 FAULT_HPP_
#define FAULT_HPP_
#include <string>
#include <memory>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp>
namespace Opm {
class FaultFace;
class Fault {
public:
explicit Fault(const std::string& faultName);
const std::string& getName() const;
void setTransMult(double transMult);
double getTransMult() const;
void addFace( FaultFace );
std::vector< FaultFace >::const_iterator begin() const;
std::vector< FaultFace >::const_iterator end() const;
bool operator==( const Fault& rhs ) const;
bool operator!=( const Fault& rhs ) const;
private:
std::string m_name;
double m_transMult;
std::vector< FaultFace > m_faceList;
};
}
#endif

View File

@@ -0,0 +1,60 @@
/*
Copyright 2014 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_FAULT_COLLECTION_HPP
#define OPM_PARSER_FAULT_COLLECTION_HPP
#include <cstddef>
#include <string>
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
namespace Opm {
class DeckRecord;
class GridDims;
class GRIDSection;
class FaultCollection {
public:
FaultCollection();
FaultCollection(const GRIDSection& gridSection, const GridDims& grid);
size_t size() const;
bool hasFault(const std::string& faultName) const;
Fault& getFault(const std::string& faultName);
const Fault& getFault(const std::string& faultName) const;
Fault& getFault(size_t faultIndex);
const Fault& getFault(size_t faultIndex) const;
/// we construct the fault based on faultName. To get the fault: getFault
void addFault(const std::string& faultName);
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 // OPM_PARSER_FAULT_COLLECTION_HPP

View File

@@ -0,0 +1,54 @@
/*
Copyright 2014 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_FAULT_FACE_HPP
#define OPM_PARSER_FAULT_FACE_HPP
#include <cstddef>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
namespace Opm {
class FaultFace {
public:
FaultFace(size_t nx , size_t ny , size_t nz,
size_t I1 , size_t I2,
size_t J1 , size_t J2,
size_t K1 , size_t K2,
FaceDir::DirEnum faceDir);
std::vector<size_t>::const_iterator begin() const;
std::vector<size_t>::const_iterator end() const;
FaceDir::DirEnum getDir() const;
bool operator==( const FaultFace& rhs ) const;
bool operator!=( const FaultFace& rhs ) const;
private:
static void checkCoord(size_t dim , size_t l1 , size_t l2);
FaceDir::DirEnum m_faceDir;
std::vector<size_t> m_indexList;
};
}
#endif // OPM_PARSER_FAULT_FACE_HPP

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:
explicit GridDims(std::array<int, 3> xyz);
GridDims(size_t nx, size_t ny, size_t nz);
explicit 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

@@ -0,0 +1,211 @@
/*
Copyright 2014 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 ECLIPSE_GRIDPROPERTIES_HPP_
#define ECLIPSE_GRIDPROPERTIES_HPP_
#include <set>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
/*
This class implements a container (std::unordered_map<std::string ,
Gridproperty<T>>) of Gridproperties. Usage is as follows:
1. Instantiate the class; passing the number of grid cells and the
supported keywords as a list of strings to the constructor.
2. Query the container with the supportsKeyword() and hasKeyword()
methods.
3. When you ask the container to get a keyword with the
getKeyword() method it will automatically create a new
GridProperty object if the container does not have this
property.
*/
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() = default;
GridProperties(const EclipseGrid& eclipseGrid,
const UnitSystem* deckUnitSystem,
std::vector< SupportedKeywordInfo >&& supportedKeywords);
explicit GridProperties(const EclipseGrid& eclipseGrid,
std::vector< SupportedKeywordInfo >&& supportedKeywords);
T convertInputValue( const GridProperty<T>& property , double doubleValue) const;
T convertInputValue( double doubleValue ) const;
bool supportsKeyword(const std::string& keyword) const;
bool isDefaultInitializable(const std::string& keyword) const;
/*
The difference between hasKeyword() and hasDeckKeyword( ) is
that hasDeckKeyword( ) will return false for keywords which
have only been auto created - and are not explicitly
mentioned in the deck.
*/
bool hasKeyword(const std::string& keyword) const;
bool hasDeckKeyword(const std::string& keyword) const;
size_t size() const;
void assertKeyword(const std::string& keyword) const;
/*
The getKeyword() method will auto create a keyword if
requested, the getDeckKeyword() method will onyl return a
keyword if it has been explicitly mentioned in the deck. The
getDeckKeyword( ) method will throw an exception instead of
auto creating the keyword.
*/
const GridProperty<T>& getKeyword(const std::string& keyword) const;
const GridProperty<T>& getDeckKeyword(const std::string& keyword) const;
bool addKeyword(const std::string& keywordName);
void copyKeyword(const std::string& srcField ,
const std::string& targetField ,
const Box& inputBox);
const MessageContainer& getMessageContainer() const;
MessageContainer& getMessageContainer();
template <class Keyword>
bool hasKeyword() const {
return hasKeyword( Keyword::keywordName );
}
template <class Keyword>
const GridProperty<T>& getKeyword() const {
return getKeyword( Keyword::keywordName );
}
template <class Keyword>
const GridProperty<T>& getInitializedKeyword() const {
return getInitializedKeyword( Keyword::keywordName );
}
GridProperty<T>& getOrCreateProperty(const std::string& name);
/**
The fine print of the manual says the ADD keyword should support
some state dependent semantics regarding endpoint scaling arrays
in the PROPS section. That is not supported.
*/
void handleADDRecord( const DeckRecord& record, BoxManager& boxManager);
void handleMAXVALUERecord( const DeckRecord& record, BoxManager& boxManager);
void handleMINVALUERecord( const DeckRecord& record, BoxManager& boxManager);
void handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager);
void handleCOPYRecord( const DeckRecord& record, BoxManager& boxManager);
void handleEQUALSRecord( const DeckRecord& record, BoxManager& boxManager);
void handleEQUALREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleADDREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleOPERATERecord( const DeckRecord& record , BoxManager& boxManager);
/*
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() );
}
/*
* storage MUST ensure that std::addressof(storage.at( key )) is valid.
*/
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
void postAddKeyword(const std::string& name,
const T defaultValue,
std::function< void( std::vector< T >& ) > postProcessor,
const std::string& dimString,
const bool defaultInitializable );
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
size_t nx = 0;
size_t ny = 0;
size_t nz = 0;
const UnitSystem * m_deckUnitSystem = nullptr;
MessageContainer m_messages;
mutable std::unordered_map<std::string, SupportedKeywordInfo> m_supportedKeywords;
mutable storage m_properties;
mutable std::set<std::string> m_autoGeneratedProperties;
};
}
#endif // ECLIPSE_GRIDPROPERTIES_HPP_

View File

@@ -0,0 +1,205 @@
/*
Copyright 2014 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 ECLIPSE_GRIDPROPERTY_HPP_
#define ECLIPSE_GRIDPROPERTY_HPP_
#include <functional>
#include <string>
#include <vector>
/*
This class implemenents a class representing properties which are
define over an ECLIPSE grid, i.e. with one value for each logical
cartesian cell in the grid.
*/
namespace Opm {
class Box;
class DeckItem;
class DeckKeyword;
class EclipseGrid;
class TableManager;
template< typename > class GridProperties;
template< typename T >
class GridPropertySupportedKeywordInfo {
public:
GridPropertySupportedKeywordInfo() = default;
using init = std::function< std::vector< T >( size_t ) >;
using post = std::function< void( std::vector< T >& ) >;
GridPropertySupportedKeywordInfo(
const std::string& name,
init initializer,
post postProcessor,
const std::string& dimString,
bool m_defaultInitializable = false );
GridPropertySupportedKeywordInfo(
const std::string& name,
init initializer,
const std::string& dimString,
bool m_defaultInitializable = false );
/* this is a convenience constructor which can be used if the default
* value for the grid property is just a constant.
*/
GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
const std::string& dimString,
bool m_defaultInitializable = false );
GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
post postProcessor,
const std::string& dimString,
bool m_defaultInitializable = false );
const std::string& getKeywordName() const;
const std::string& getDimensionString() const;
const init& initializer() const;
const post& postProcessor() const;
bool isDefaultInitializable() const;
private:
std::string m_keywordName;
init m_initializer;
post m_postProcessor;
std::string m_dimensionString;
bool m_defaultInitializable;
};
template< typename T >
class GridProperty {
public:
typedef GridPropertySupportedKeywordInfo<T> SupportedKeywordInfo;
GridProperty( size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo& kwInfo );
size_t getCartesianSize() const;
size_t getNX() const;
size_t getNY() const;
size_t getNZ() const;
T iget(size_t index) const;
T iget(size_t i , size_t j , size_t k) const;
void iset(size_t index, T value);
void iset(size_t i , size_t j , size_t k , T value);
const std::vector<T>& getData() const;
std::vector<T>& getData();
bool containsNaN() const;
const std::string& getDimensionString() const;
void multiplyWith( const GridProperty<T>& );
void multiplyValueAtIndex( size_t index, T factor );
void maskedSet( T value, const std::vector< bool >& mask );
void maskedMultiply( T value, const std::vector< bool >& mask );
void maskedAdd( T value, const std::vector< bool >& mask );
void maskedCopy( const GridProperty< T >& other, const std::vector< bool >& mask );
void initMask( T value, std::vector<bool>& mask ) const;
/**
Due to the convention where it is only necessary to supply the
top layer of the petrophysical properties we can unfortunately
not enforce that the number of elements elements in the
DeckKeyword equals nx*ny*nz.
*/
void loadFromDeckKeyword( const DeckKeyword& );
void loadFromDeckKeyword( const Box&, const DeckKeyword& );
void copyFrom( const GridProperty< T >&, const Box& );
void scale( T scaleFactor, const Box& );
void maxvalue( T value, const Box& );
void minvalue( T value, const Box& );
void add( T shiftValue, const Box& );
void setScalar( T value, const Box& );
const std::string& getKeywordName() const;
const SupportedKeywordInfo& getKeywordInfo() const;
/**
Will check that all elements in the property are in the closed
interval [min,max].
*/
void checkLimits( T min, T max ) const;
/*
The runPostProcessor() method is public; and it is no harm in
calling it from arbitrary locations. But the intention is that
should only be called from the Eclipse3DProperties class
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);
size_t m_nx, m_ny, m_nz;
SupportedKeywordInfo m_kwInfo;
std::vector<T> m_data;
bool m_hasRunPostProcessor = false;
};
// initialize the TEMPI grid property using the temperature vs depth
// table (stemming from the TEMPVD or the RTEMPVD keyword)
std::vector< double > temperature_lookup( size_t,
const TableManager*,
const EclipseGrid*,
const GridProperties<int>* );
}
#endif

View File

@@ -0,0 +1,87 @@
/*
Copyright 2014 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_MULTREGTSCANNER_HPP
#define OPM_PARSER_MULTREGTSCANNER_HPP
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
namespace Opm {
template< typename > class GridProperties;
class DeckRecord;
class DeckKeyword;
namespace MULTREGT {
enum NNCBehaviourEnum {
NNC = 1,
NONNC = 2,
ALL = 3,
NOAQUNNC = 4
};
std::string RegionNameFromDeckValue(const std::string& stringValue);
NNCBehaviourEnum NNCBehaviourFromString(const std::string& stringValue);
}
class MULTREGTRecord {
public:
MULTREGTRecord(const DeckRecord& deckRecord , const std::string& defaultRegion);
Value<int> m_srcRegion;
Value<int> m_targetRegion;
double m_transMultiplier;
int m_directions;
MULTREGT::NNCBehaviourEnum m_nncBehaviour;
Value<std::string> m_region;
};
typedef std::map< std::pair<int , int> , const MULTREGTRecord * > MULTREGTSearchMap;
typedef std::tuple<size_t , FaceDir::DirEnum , double> MULTREGTConnection;
class MULTREGTScanner {
public:
MULTREGTScanner(const Eclipse3DProperties& e3DProps,
const std::vector< const DeckKeyword* >& keywords);
double getRegionMultiplier(size_t globalCellIdx1, size_t globalCellIdx2, FaceDir::DirEnum faceDir) const;
private:
void addKeyword( const DeckKeyword& deckKeyword, const std::string& defaultRegion);
void assertKeywordSupported(const DeckKeyword& deckKeyword, const std::string& defaultRegion);
std::vector< MULTREGTRecord > m_records;
std::map<std::string , MULTREGTSearchMap> m_searchMap;
const Eclipse3DProperties& m_e3DProps;
};
}
#endif // OPM_PARSER_MULTREGTSCANNER_HPP

View File

@@ -0,0 +1,36 @@
/*
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_MINPVMODE_HPP
#define OPM_MINPVMODE_HPP
#include <string>
namespace Opm {
namespace MinpvMode {
enum ModeEnum {
Inactive = 1,
EclSTD = 2,
OpmFIL = 3
};
}
}
#endif

View File

@@ -0,0 +1,61 @@
/*
Copyright 2015 IRIS
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_NNC_HPP
#define OPM_PARSER_NNC_HPP
#include <cstddef>
#include <memory>
#include <vector>
namespace Opm
{
struct NNCdata {
size_t cell1;
size_t cell2;
double trans;
};
class Deck;
/// Represents non-neighboring connections (non-standard adjacencies).
/// This class is essentially a directed weighted graph.
class NNC
{
public:
NNC() = default;
/// Construct from input deck.
explicit NNC(const Deck& deck);
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;
bool hasNNC() const;
private:
std::vector<NNCdata> m_nnc;
};
} // namespace Opm
#endif // OPM_PARSER_NNC_HPP

View File

@@ -0,0 +1,40 @@
/*
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_PINCHMODE_HPP
#define OPM_PINCHMODE_HPP
#include <string>
namespace Opm {
namespace PinchMode {
enum ModeEnum {
ALL = 1,
TOPBOT = 2,
TOP = 3
};
const std::string PinchMode2String(const ModeEnum enumValue);
ModeEnum PinchModeFromString(const std::string& stringValue);
}
}
#endif // _PINCHMODE_

View File

@@ -0,0 +1,202 @@
/*
Copyright 2014 Andreas Lauser
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 ECLIPSE_SATFUNCPROPERTY_INITIALIZERS_HPP
#define ECLIPSE_SATFUNCPROPERTY_INITIALIZERS_HPP
#include <vector>
#include <string>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
namespace Opm {
class EclipseGrid;
class TableManager;
std::vector<double> SGLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SGUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGUEndpoint(size_t, const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SOWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISOWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SOGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISOGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> PCWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IPCWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> PCGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IPCGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRWREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRWREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KROEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKROEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRORWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRORWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRORGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRORGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRGREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRGREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
}
#endif // ECLIPSE_SATFUNCPROPERTY_INITIALIZERS_HPP

View File

@@ -0,0 +1,74 @@
/*
Copyright 2014 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/>.
*/
/**
This class implements a small container which holds the
transmissibility mulitpliers for all the faces in the grid. The
multipliers in this class are built up from the transmissibility
modifier keywords:
{MULTX , MULTX- , MULTY , MULTY- , MULTZ , MULTZ-, MULTFLT , MULTREGT}
*/
#ifndef OPM_PARSER_TRANSMULT_HPP
#define OPM_PARSER_TRANSMULT_HPP
#include <cstddef>
#include <map>
#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 Eclipse3DProperties;
class DeckKeyword;
class TransMult {
public:
TransMult(const GridDims& dims, const Deck& deck, const Eclipse3DProperties& props);
double getMultiplier(size_t globalIndex, FaceDir::DirEnum faceDir) const;
double getMultiplier(size_t i , size_t j , size_t k, FaceDir::DirEnum faceDir) const;
double getRegionMultiplier( size_t globalCellIndex1, size_t globalCellIndex2, FaceDir::DirEnum faceDir) const;
void applyMULT(const GridProperty<double>& srcMultProp, FaceDir::DirEnum faceDir);
void applyMULTFLT(const FaultCollection& faults);
void applyMULTFLT(const Fault& fault);
private:
size_t getGlobalIndex(size_t i , size_t j , size_t k) const;
void assertIJK(size_t i , size_t j , size_t k) const;
double getMultiplier__(size_t globalIndex , FaceDir::DirEnum faceDir) const;
void insertNewProperty(FaceDir::DirEnum faceDir);
bool hasDirectionProperty(FaceDir::DirEnum faceDir) const;
GridProperty<double>& getDirectionProperty(FaceDir::DirEnum faceDir);
size_t m_nx , m_ny , m_nz;
std::map<FaceDir::DirEnum , GridProperty<double> > m_trans;
std::map<FaceDir::DirEnum , std::string> m_names;
MULTREGTScanner m_multregtScanner;
};
}
#endif // OPM_PARSER_TRANSMULT_HPP

View File

@@ -0,0 +1,180 @@
/*
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_IO_CONFIG_HPP
#define OPM_IO_CONFIG_HPP
#include <boost/date_time/gregorian/gregorian_types.hpp>
namespace Opm {
class Deck;
class GRIDSection;
class RUNSPECSection;
/*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.
*/
class IOConfig {
public:
IOConfig() = default;
explicit IOConfig( const Deck& );
explicit IOConfig( const std::string& input_path );
bool getWriteEGRIDFile() const;
bool getWriteINITFile() const;
bool getUNIFOUT() const;
bool getUNIFIN() const;
bool getFMTIN() const;
bool getFMTOUT() const;
const std::string& getEclipseInputPath() const;
void overrideNOSIM(bool nosim);
std::string getRestartFileName(const std::string& restart_base, int report_step, bool output) const;
bool getOutputEnabled() const;
void setOutputEnabled(bool enabled);
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;
// 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:
bool m_write_INIT_file = false;
bool m_write_EGRID_file = true;
bool m_UNIFIN = false;
bool m_UNIFOUT = false;
bool m_FMTIN = false;
bool m_FMTOUT = false;
int m_first_restart_step;
std::string m_deck_filename;
bool m_output_enabled = true;
std::string m_output_dir;
std::string m_base_name;
bool m_nosim;
IOConfig( const GRIDSection&,
const RUNSPECSection&,
bool nosim,
const std::string& input_path );
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,370 @@
/*
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;
explicit 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,
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);
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);
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

@@ -0,0 +1,60 @@
#ifndef OPM_EQUIL_HPP
#define OPM_EQUIL_HPP
#include <vector>
namespace Opm {
class DeckKeyword;
class DeckRecord;
class EquilRecord {
public:
explicit EquilRecord( const DeckRecord& );
double datumDepth() const;
double datumDepthPressure() const;
double waterOilContactDepth() const;
double waterOilContactCapillaryPressure() const;
double gasOilContactDepth() const;
double gasOilContactCapillaryPressure() const;
bool liveOilInitConstantRs() const;
bool wetGasInitConstantRv() const;
int initializationTargetAccuracy() const;
private:
double datum_depth;
double datum_depth_ps;
double water_oil_contact_depth;
double water_oil_contact_capillary_pressure;
double gas_oil_contact_depth;
double gas_oil_contact_capillary_pressure;
bool live_oil_init_proc;
bool wet_gas_init_proc;
int init_target_accuracy;
};
class Equil {
public:
using const_iterator = std::vector< EquilRecord >::const_iterator;
Equil() = default;
explicit Equil( const DeckKeyword& );
const EquilRecord& getRecord( size_t id ) const;
size_t size() const;
bool empty() const;
const_iterator begin() const;
const_iterator end() const;
private:
std::vector< EquilRecord > records;
};
}
#endif //OPM_EQUIL_HPP

View File

@@ -0,0 +1,52 @@
/*
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_INIT_CONFIG_HPP
#define OPM_INIT_CONFIG_HPP
#include <opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp>
namespace Opm {
class Deck;
class InitConfig {
public:
explicit InitConfig(const Deck& deck);
void setRestart( const std::string& root, int step);
bool restartRequested() const;
int getRestartStep() const;
const std::string& getRestartRootName() const;
bool hasEquil() const;
const Equil& getEquil() const;
private:
bool m_restartRequested = false;
int m_restartStep = 0;
std::string m_restartRootName;
Equil equil;
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,74 @@
/*
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_RUNSPEC_HPP
#define OPM_RUNSPEC_HPP
#include <iosfwd>
#include <string>
#include <opm/parser/eclipse/EclipseState/Tables/Tabdims.hpp>
#include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp>
namespace Opm {
class Deck;
enum class Phase {
OIL = 0,
GAS = 1,
WATER = 2,
SOLVENT = 3,
POLYMER = 4,
ENERGY = 5,
};
Phase get_phase( const std::string& );
std::ostream& operator<<( std::ostream&, const Phase& );
class Phases {
public:
Phases() noexcept = default;
Phases( bool oil, bool gas, bool wat, bool solvent = false, bool polymer = false, bool energy = false ) noexcept;
bool active( Phase ) const noexcept;
size_t size() const noexcept;
private:
std::bitset< 6 > bits;
};
class Runspec {
public:
explicit Runspec( const Deck& );
const Phases& phases() const noexcept;
const Tabdims& tabdims() const noexcept;
const EndpointScaling& endpointScaling() const noexcept;
int eclPhaseMask( ) const noexcept;
private:
Phases active_phases;
Tabdims m_tabdims;
EndpointScaling endscale;
};
}
#endif // OPM_RUNSPEC_HPP

View File

@@ -0,0 +1,110 @@
/*
Copyright 2013 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 COMPLETION_HPP_
#define COMPLETION_HPP_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
namespace Opm {
class DeckKeyword;
class DeckRecord;
class Well;
class EclipseGrid;
class Eclipse3DProperties;
class Completion {
public:
Completion(int i, int j , int k ,
int complnum,
double depth,
WellCompletion::StateEnum state ,
const Value<double>& connectionTransmissibilityFactor,
const Value<double>& diameter,
const Value<double>& skinFactor,
const int satTableId,
const WellCompletion::DirectionEnum direction = WellCompletion::DirectionEnum::Z);
Completion(const Completion&, WellCompletion::StateEnum newStatus);
Completion(const Completion&, double wellPi);
Completion(const Completion&, int complnum );
Completion(const Completion& completion_initial, int segment_number, double center_depth);
bool sameCoordinate(const Completion& other) const;
bool sameCoordinate(const int i, const int j, const int k) const;
int getI() const;
int getJ() const;
int getK() const;
int complnum() const;
WellCompletion::StateEnum getState() const;
double getConnectionTransmissibilityFactor() const;
double getWellPi() const;
const Value<double>& getConnectionTransmissibilityFactorAsValueObject() const;
double getDiameter() const;
double getSkinFactor() const;
int getSatTableId() const;
void fixDefaultIJ(int wellHeadI , int wellHeadJ);
void shift_complnum( int );
int getSegmentNumber() const;
double getCenterDepth() const;
bool attachedToSegment() const;
WellCompletion::DirectionEnum getDirection() const;
static std::map< std::string, std::vector< Completion > >
fromCOMPDAT( const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties,
const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& );
bool operator==( const Completion& ) const;
bool operator!=( const Completion& ) const;
private:
int m_i, m_j, m_k;
int m_complnum;
Value<double> m_diameter;
Value<double> m_connectionTransmissibilityFactor;
double m_wellPi;
Value<double> m_skinFactor;
int m_satTableId;
WellCompletion::StateEnum m_state;
WellCompletion::DirectionEnum m_direction;
Value<double> getDiameterAsValueObject() const;
Value<double> getSkinFactorAsValueObject() const;
// related segment number
// -1 means the completion is not related to segment
int m_segment_number = -1;
double m_center_depth;
};
}
#endif /* COMPLETION_HPP_ */

View File

@@ -0,0 +1,71 @@
/*
Copyright 2013 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 COMPLETIONSET_HPP_
#define COMPLETIONSET_HPP_
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
namespace Opm {
class EclipseGrid;
class CompletionSet {
public:
CompletionSet() = default;
// cppcheck-suppress noExplicitConstructor
CompletionSet( std::initializer_list< Completion > );
using const_iterator = std::vector< Completion >::const_iterator;
void add( Completion );
size_t size() const;
const Completion& get(size_t index) const;
const Completion& getFromIJK(const int i, const int j, const int k) const;
const_iterator begin() const { return this->m_completions.begin(); }
const_iterator end() const { return this->m_completions.end(); }
void filter(const EclipseGrid& grid);
bool allCompletionsShut() const;
/// Order completions irrespective of input order.
/// The algorithm used is the following:
/// 1. The completion nearest to the given (well_i, well_j)
/// coordinates in terms of the completion's (i, j) is chosen
/// to be the first completion. If non-unique, choose one with
/// lowest z-depth (shallowest).
/// 2. Choose next completion to be nearest to current in (i, j) sense.
/// If non-unique choose closest in z-depth (not logical cartesian k).
///
/// \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);
bool operator==( const CompletionSet& ) const;
bool operator!=( const CompletionSet& ) const;
private:
std::vector< Completion > m_completions;
size_t findClosestCompletion(int oi, int oj, double oz, size_t start_pos);
};
}
#endif

View File

@@ -0,0 +1,145 @@
/*
Copyright 2013 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 DYNAMICSTATE_HPP_
#define DYNAMICSTATE_HPP_
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
namespace Opm {
/**
The DynamicState<T> class is designed to hold information about
properties with the following semantics:
1. The property can be updated repeatedly at different
timesteps; observe that the class does not support
operator[] - only updates with weakly increasing timesteps
are supported.
2. At any point in the time the previous last set value
applies.
The class is very much tailored to support the Schedule file of
Eclipse where a control applied at time T will apply
indefinitely, or until explicitly set to a different value.
The update() method returns true if the updated value is
different from the current value, this implies that the
class<T> must support operator!=
*/
template< class T >
class DynamicState {
public:
typedef typename std::vector< T >::iterator iterator;
DynamicState( const TimeMap& timeMap, T initial ) :
m_data( timeMap.size(), initial ),
initial_range( timeMap.size() )
{}
void globalReset( T value ) {
this->m_data.assign( this->m_data.size(), value );
}
const T& back() const {
return m_data.back();
}
const T& at( size_t index ) const {
return this->m_data.at( index );
}
const T& operator[](size_t index) const {
return this->at( index );
}
const T& get(size_t index) const {
return this->at( index );
}
void updateInitial( T initial ) {
std::fill_n( this->m_data.begin(), this->initial_range, initial );
}
/**
If the current value has been changed the method will
return true, otherwise it will return false.
*/
bool update( size_t index, T value ) {
if( this->initial_range == this->m_data.size() )
this->initial_range = index;
const bool change = (value != this->m_data.at( index ));
if( !change ) return false;
std::fill( this->m_data.begin() + index,
this->m_data.end(),
value );
return true;
}
void update_elm( size_t index, const T& value ) {
if (this->m_data.size() <= index)
throw std::out_of_range("Invalid index for update_elm()");
this->m_data[index] = value;
}
/// Will return the index of the first occurence of @value, or
/// -1 if @value is not found.
int find(const T& value) const {
auto iter = std::find( m_data.begin() , m_data.end() , value);
if( iter == this->m_data.end() ) return -1;
return std::distance( m_data.begin() , iter );
}
iterator begin() {
return this->m_data.begin();
}
iterator end() {
return this->m_data.end();
}
private:
std::vector< T > m_data;
size_t initial_range;
};
}
#endif

View File

@@ -0,0 +1,66 @@
/*
Copyright 2013 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 DYNAMICVECTOR_HPP_
#define DYNAMICVECTOR_HPP_
#include <stdexcept>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
namespace Opm {
/*
The DynamicVector<T> class is a thin wrapper around
std::vector<T> with the following twists:
- Default-sized to the size of a time map, pre-populated by the default
value.
*/
template <class T>
class DynamicVector {
public:
DynamicVector(const TimeMap& timeMap, T defaultValue) :
m_data( timeMap.size(), defaultValue )
{}
const T& operator[](size_t index) const {
return this->m_data.at( index );
}
const T& iget(size_t index) const {
return (*this)[index];
}
T& operator[](size_t index) {
return this->m_data.at( index );
}
void iset(size_t index, T value) {
(*this)[index] = std::move( value );
}
private:
std::vector<T> m_data;
};
}
#endif

View File

@@ -0,0 +1,121 @@
/*
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 SCHEDULE_EVENTS_HPP
#define SCHEDULE_EVENTS_HPP
#include <cstdint>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>
namespace Opm
{
namespace ScheduleEvents {
// These values are used as bitmask - 2^n structure is essential.
enum Events {
/*
The NEW_WELL event is triggered by the WELSPECS
keyword. For wells the event is triggered the first
time the well is mentioned in the WELSPECS keyword, for
the Schedule object the NEW_WELL event is triggered
every time a WELSPECS keyword is encountered.
*/
NEW_WELL = 1,
/*
WHen the well data is updated with the WELSPECS keyword
this event is triggered. Only applies to individual
wells, and not the global Schedule object.
*/
WELL_WELSPECS_UPDATE = 2,
WELL_POLYMER_UPDATE = 4,
/*
The NEW_GROUP event is triggered by the WELSPECS and
GRUPTREE keywords.
*/
NEW_GROUP = 8,
/*
The PRODUCTION_UPDATE event is triggered by the
WCONPROD and WCONHIST keywords. The event will be
triggered if *any* of the elements in one of keywords
is changed. Quite simlar for INJECTION_UPDATE and
POLYMER_UPDATE.
*/
PRODUCTION_UPDATE = 16,
INJECTION_UPDATE = 32,
POLYMER_UPDATES = 64,
/*
This event is triggered if the well status is changed
between {OPEN,SHUT,STOP,AUTO}. There are many keywords
which can trigger a well status change.
*/
WELL_STATUS_CHANGE = 128,
/*
COMPDAT and WELOPEN
*/
COMPLETION_CHANGE = 256,
/*
The well group topolyg has changed.
*/
GROUP_CHANGE = 512,
/*
Geology modifier.
*/
GEO_MODIFIER = 1024,
/*
TUNING has changed
*/
TUNING_CHANGE = 2048
};
}
/*
This class implements a simple system for recording when various
events happen in the Schedule file. The purpose of the class is
that downstream code can query this system whether a certain a
event has taken place, and then perform potentially expensive
calculations conditionally:
auto events = schedule->getEvents();
if (events.hasEvent(SchedulEvents::NEW_WELL , reportStep))
// Perform expensive calculation which must be performed
// when a new well is introduced.
...
*/
class Events {
public:
explicit Events(const TimeMap& timeMap);
void addEvent(ScheduleEvents::Events event, size_t reportStep);
bool hasEvent(uint64_t eventMask, size_t reportStep) const;
private:
DynamicVector<uint64_t> m_events;
};
}
#endif

View File

@@ -0,0 +1,148 @@
/*
Copyright 2013 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 GROUP_HPP_
#define GROUP_HPP_
#include <memory>
#include <set>
#include <string>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
namespace Opm {
class TimeMap;
class Well;
namespace GroupInjection {
struct InjectionData {
explicit InjectionData( const TimeMap& );
DynamicState< Phase > phase;
DynamicState< GroupInjection::ControlEnum > controlMode;
DynamicState< double > rate;
DynamicState< double > surfaceFlowMaxRate;
DynamicState< double > reservoirFlowMaxRate;
DynamicState< double > targetReinjectFraction;
DynamicState< double > targetVoidReplacementFraction;
};
}
namespace GroupProduction {
struct ProductionData {
explicit ProductionData( const TimeMap& );
DynamicState< GroupProduction::ControlEnum > controlMode;
DynamicState< GroupProductionExceedLimit::ActionEnum > exceedAction;
DynamicState< double > oilTarget;
DynamicState< double > waterTarget;
DynamicState< double > gasTarget;
DynamicState< double > liquidTarget;
DynamicState< double > reservoirVolumeTarget;
};
}
class Group {
public:
Group(const std::string& name, const TimeMap& timeMap , size_t creationTimeStep);
bool hasBeenDefined(size_t timeStep) const;
const std::string& name() const;
bool isProductionGroup(size_t timeStep) const;
bool isInjectionGroup(size_t timeStep) const;
void setProductionGroup(size_t timeStep, bool isProductionGroup);
void setInjectionGroup(size_t timeStep, bool isInjectionGroup_);
/******************************************************************/
void setInjectionPhase(size_t time_step, Phase);
Phase getInjectionPhase(size_t time_step) const;
void setInjectionControlMode(size_t time_step , GroupInjection::ControlEnum ControlMode);
GroupInjection::ControlEnum getInjectionControlMode( size_t time_step) const;
void setInjectionRate(size_t time_step , double rate);
double getInjectionRate( size_t time_step) const;
void setSurfaceMaxRate( size_t time_step , double rate);
double getSurfaceMaxRate( size_t time_step ) const;
void setReservoirMaxRate( size_t time_step , double rate);
double getReservoirMaxRate( size_t time_step ) const;
void setTargetReinjectFraction( size_t time_step , double rate);
double getTargetReinjectFraction( size_t time_step ) const;
void setTargetVoidReplacementFraction( size_t time_step , double rate);
double getTargetVoidReplacementFraction( size_t time_step ) const;
/******************************************************************/
void setProductionControlMode( size_t time_step , GroupProduction::ControlEnum controlMode);
GroupProduction::ControlEnum getProductionControlMode( size_t time_step ) const;
GroupProductionExceedLimit::ActionEnum getProductionExceedLimitAction(size_t time_step) const;
void setProductionExceedLimitAction(size_t time_step , GroupProductionExceedLimit::ActionEnum action);
void setOilTargetRate(size_t time_step , double oilTargetRate);
double getOilTargetRate(size_t time_step) const;
void setGasTargetRate(size_t time_step , double gasTargetRate);
double getGasTargetRate(size_t time_step) const;
void setWaterTargetRate(size_t time_step , double waterTargetRate);
double getWaterTargetRate(size_t time_step) const;
void setLiquidTargetRate(size_t time_step , double liquidTargetRate);
double getLiquidTargetRate(size_t time_step) const;
void setReservoirVolumeTargetRate(size_t time_step , double reservoirVolumeTargetRate);
double getReservoirVolumeTargetRate(size_t time_step) const;
void setGroupEfficiencyFactor(size_t time_step, double factor);
double getGroupEfficiencyFactor(size_t time_step) const;
void setTransferGroupEfficiencyFactor(size_t time_step, bool transfer);
bool getTransferGroupEfficiencyFactor(size_t time_step) const;
void setGroupNetVFPTable(size_t time_step, int table);
int getGroupNetVFPTable(size_t time_step) const;
/*****************************************************************/
bool hasWell(const std::string& wellName , size_t time_step) const;
const std::set< std::string >& getWells( size_t time_step ) const;
size_t numWells(size_t time_step) const;
void addWell(size_t time_step, const Well* well);
void delWell(size_t time_step, const std::string& wellName );
private:
size_t m_creationTimeStep;
std::string m_name;
GroupInjection::InjectionData m_injection;
GroupProduction::ProductionData m_production;
DynamicState< std::set< std::string > > m_wells;
DynamicState<int> m_isProductionGroup;
DynamicState<int> m_isInjectionGroup;
DynamicState<double> m_efficiencyFactor;
DynamicState<int> m_transferEfficiencyFactor;
DynamicState<int> m_groupNetVFPTable;
};
}
#endif /* GROUP_HPP_ */

View File

@@ -0,0 +1,61 @@
/*
Copyright 2013 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 GROUPTREE_HPP
#define GROUPTREE_HPP
#include <string>
#include <vector>
namespace Opm {
class GroupTree {
public:
void update( const std::string& name );
void update( const std::string& name, const std::string& parent );
bool exists( const std::string& group ) const;
const std::string& parent( const std::string& name ) const;
std::vector< std::string > children( const std::string& parent ) const;
bool operator==( const GroupTree& ) const;
bool operator!=( const GroupTree& ) const;
private:
struct group {
std::string name;
std::string parent;
bool operator<( const group& rhs ) const;
bool operator==( const std::string& name ) const;
bool operator!=( const std::string& name ) const;
bool operator<( const std::string& name ) const;
bool operator==( const group& rhs ) const;
bool operator!=( const group& rhs ) const;
};
std::vector< group > groups = { group { "FIELD", "" } };
friend bool operator<( const std::string&, const group& );
std::vector< group >::iterator find( const std::string& );
};
}
#endif /* GROUPTREE_HPP */

View File

@@ -0,0 +1,113 @@
/*
Copyright 2015 SINTEF ICT, Applied Mathematics.
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 SEGMENT_HPP_HEADER_INCLUDED
#define SEGMENT_HPP_HEADER_INCLUDED
#include <memory>
#include <vector>
namespace Opm {
class Segment {
public:
Segment();
Segment(int segment_number_in, int branch_in, int outlet_segment_in, double length_in, double depth_in,
double internal_diameter_in, double roughness_in, double cross_area_in, double volume_in, bool data_ready_in);
int segmentNumber() const;
int branchNumber() const;
int outletSegment() const;
double totalLength() const;
double depth() const;
double internalDiameter() const;
double roughness() const;
double crossArea() const;
double volume() const;
bool dataReady() const;
void setVolume(const double volume_in);
void setDepthAndLength(const double depth_in, const double length_in);
const std::vector<int>& inletSegments() const;
void addInletSegment(const int segment_number);
static double invalidValue();
bool operator==( const Segment& ) const;
bool operator!=( const Segment& ) const;
private:
// segment number
// it should work as a ID.
int m_segment_number;
// branch number
// for top segment, it should always be 1
int m_branch;
// the outlet junction segment
// for top segment, it should be -1
int m_outlet_segment;
// the segments whose outlet segments are the current segment
std::vector<int> m_inlet_segments;
// length of the segment node to the bhp reference point.
// when reading in from deck, with 'INC',
// it will be incremental length before processing.
// After processing and in the class Well, it always stores the 'ABS' value.
// which means the total_length
double m_total_length;
// depth of the nodes to the bhp reference point
// when reading in from deck, with 'INC',
// it will be the incremental depth before processing.
// in the class Well, it always stores the 'ABS' value.
// TODO: to check if it is good to use 'ABS' always.
double m_depth;
// tubing internal diameter
// or the equivalent diameter for annular cross-sections
// for top segment, it is UNDEFINED
// we use invalid_value for the top segment
double m_internal_diameter;
// effective roughness of the tubing
// used to calculate the Fanning friction factor
// for top segment, it is UNDEFINED
// we use invalid_value for the top segment
double m_roughness;
// cross-sectional area for fluid flow
// not defined for the top segment,
// we use invalid_value for the top segment.
double m_cross_area;
// valume of the segment;
// it is defined for top segment.
// TODO: to check if the definition is the same with other segments.
double m_volume;
// indicate if the data related to 'INC' or 'ABS' is ready
// the volume will be updated at a final step.
bool m_data_ready;
static constexpr double invalid_value = -1.e100;
// We are not handling the length of segment projected onto the X-axis and Y-axis.
// They are not used in the simulations and we are not supporting the plotting.
// There are other three properties for segment related to thermal conduction,
// while they are not supported by the keyword at the moment.
};
}
#endif

View File

@@ -0,0 +1,98 @@
/*
Copyright 2015 SINTEF ICT, Applied Mathematics.
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 SEGMENTSET_HPP_HEADER_INCLUDED
#define SEGMENTSET_HPP_HEADER_INCLUDED
#include <vector>
#include <map>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/Segment.hpp>
namespace Opm {
class DeckKeyword;
class SegmentSet {
public:
SegmentSet() = default;
std::string wellName() const;
int numberBranch() const;
int numberSegment() const;
double depthTopSegment() const;
double lengthTopSegment() const;
double volumeTopSegment() const;
WellSegment::LengthDepthEnum lengthDepthType() const;
WellSegment::CompPressureDropEnum compPressureDrop() const;
WellSegment::MultiPhaseModelEnum multiPhaseModel() const;
// mapping the segment number to the index in the vector of segments
int segmentNumberToIndex(const int segment_number) const;
void addSegment(Segment new_segment);
void segmentsFromWELSEGSKeyword( const DeckKeyword& welsegsKeyword);
const Segment& getFromSegmentNumber(const int segment_number) const;
const Segment& operator[](size_t idx) const;
void orderSegments();
void processABS();
void processINC(const bool first_time);
bool operator==( const SegmentSet& ) const;
bool operator!=( const SegmentSet& ) const;
private:
// name of the well
std::string m_well_name;
// number of the branches
int m_number_branch;
// depth of the nodal point of the top segment
// it is taken as the BHP reference depth of the well
// BHP reference depth data from elsewhere will be ignored for multi-segmented wells
double m_depth_top;
// length down the tubing to the nodal point of the top segment
double m_length_top;
// effective wellbore volume of the top segment
double m_volume_top;
// type of the tubing length and depth information
WellSegment::LengthDepthEnum m_length_depth_type;
// components of the pressure drop to be included
WellSegment::CompPressureDropEnum m_comp_pressure_drop;
// multi-phase flow model
WellSegment::MultiPhaseModelEnum m_multiphase_model;
// There are X and Y cooridnate of the nodal point of the top segment
// Since they are not used for simulations and we are not supporting plotting,
// we are not handling them at the moment.
// There are other three properties for segment related to thermal conduction,
// while they are not supported by the keyword at the moment.
std::vector< Segment > m_segments;
// the mapping from the segment number to the
// storage index in the vector
std::map<int, int> m_segment_number_to_index;
};
}
#endif

View File

@@ -0,0 +1,32 @@
/*
Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
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 UPDATING_COMPLETIONS_WITH_SEGMENTS
#define UPDATING_COMPLETIONS_WITH_SEGMENTS
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/SegmentSet.hpp>
namespace Opm {
CompletionSet updatingCompletionsWithSegments(const DeckKeyword& compsegs, const CompletionSet& input_completions, const SegmentSet& segments);
}
#endif

View File

@@ -0,0 +1,112 @@
/*
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_MESSAGES_HPP
#define OPM_MESSAGES_HPP
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/M.hpp>
namespace Opm {
class TimeMap;
struct MLimits {
int message_print_limit = ParserKeywords::MESSAGES::MESSAGE_PRINT_LIMIT::defaultValue;
int comment_print_limit = ParserKeywords::MESSAGES::COMMENT_PRINT_LIMIT::defaultValue;
int warning_print_limit = ParserKeywords::MESSAGES::WARNING_PRINT_LIMIT::defaultValue;
int problem_print_limit = ParserKeywords::MESSAGES::PROBLEM_PRINT_LIMIT::defaultValue;
int error_print_limit = ParserKeywords::MESSAGES::ERROR_PRINT_LIMIT::defaultValue;
int bug_print_limit = ParserKeywords::MESSAGES::BUG_PRINT_LIMIT::defaultValue;
int message_stop_limit = ParserKeywords::MESSAGES::MESSAGE_STOP_LIMIT::defaultValue;
int comment_stop_limit = ParserKeywords::MESSAGES::COMMENT_STOP_LIMIT::defaultValue;
int warning_stop_limit = ParserKeywords::MESSAGES::WARNING_STOP_LIMIT::defaultValue;
int problem_stop_limit = ParserKeywords::MESSAGES::PROBLEM_STOP_LIMIT::defaultValue;
int error_stop_limit = ParserKeywords::MESSAGES::ERROR_STOP_LIMIT::defaultValue;
int bug_stop_limit = ParserKeywords::MESSAGES::BUG_STOP_LIMIT::defaultValue;
bool operator==(const MLimits& other) const {
return ((this->message_print_limit == other.message_print_limit) &&
(this->comment_print_limit == other.comment_print_limit) &&
(this->warning_print_limit == other.warning_print_limit) &&
(this->problem_print_limit == other.problem_print_limit) &&
(this->error_print_limit == other.error_print_limit ) &&
(this->bug_print_limit == other.bug_print_limit ) &&
(this->message_stop_limit == other.message_stop_limit ) &&
(this->comment_stop_limit == other.comment_stop_limit ) &&
(this->warning_stop_limit == other.warning_stop_limit ) &&
(this->problem_stop_limit == other.problem_stop_limit ) &&
(this->error_stop_limit == other.error_stop_limit ) &&
(this->bug_stop_limit == other.bug_stop_limit ));
}
bool operator!=(const MLimits& other) const {
return !(*this == other);
}
};
class MessageLimits {
public:
/*
This constructor will create a new Messages object which is
a copy of the input argument, and then all items explicitly
set in the record are modified.
*/
explicit MessageLimits( const TimeMap& );
///Get all the value from MESSAGES keyword.
int getMessagePrintLimit(size_t timestep) const;
int getCommentPrintLimit(size_t timestep) const;
int getWarningPrintLimit(size_t timestep) const;
int getProblemPrintLimit(size_t timestep) const;
int getErrorPrintLimit(size_t timestep) const;
int getBugPrintLimit(size_t timestep) const;
void setMessagePrintLimit(size_t timestep, int value);
void setCommentPrintLimit(size_t timestep, int value);
void setWarningPrintLimit(size_t timestep, int value);
void setProblemPrintLimit(size_t timestep, int value);
void setErrorPrintLimit(size_t timestep, int value);
void setBugPrintLimit(size_t timestep, int value);
int getMessageStopLimit(size_t timestep) const;
int getCommentStopLimit(size_t timestep) const;
int getWarningStopLimit(size_t timestep) const;
int getProblemStopLimit(size_t timestep) const;
int getErrorStopLimit(size_t timestep) const;
int getBugStopLimit(size_t timestep) const;
void setMessageStopLimit(size_t timestep, int value);
void setCommentStopLimit(size_t timestep, int value);
void setWarningStopLimit(size_t timestep, int value);
void setProblemStopLimit(size_t timestep, int value);
void setErrorStopLimit(size_t timestep, int value);
void setBugStopLimit(size_t timestep, int value);
private:
void update(size_t timestep, const MLimits& value);
DynamicState<MLimits> limits;
};
}
#endif

View File

@@ -0,0 +1,66 @@
/*
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 DRSDT_HPP
#define DRSDT_HPP
#include <string>
#include <memory>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
namespace Opm
{
/*
* The OilVaporizationProperties class
* This classe is used to store the values from {VAPPARS, DRSDT, DRVDT} the behavior of the keywords are mutal exclusive.
* Any one of the three keywords {VAPPARS, DRSDT, DRVDT} will cancel previous settings of the other keywords.
* Ask for type first and the ask for the correct values for this type, asking for values not valid for the current type will throw a logic exception.
*/
class OilVaporizationProperties {
public:
OilVaporizationProperties() = default;
static OilVaporizationProperties createDRSDT(double maxDRSDT, const std::string& option);
static OilVaporizationProperties createDRVDT(double maxDRVDT);
static OilVaporizationProperties createVAPPARS(double vap1, double vap2);
Opm::OilVaporizationEnum getType() const;
double getVap1() const;
double getVap2() const;
double getMaxDRSDT() const;
double getMaxDRVDT() const;
bool getOption() const;
bool defined() const;
/*
* if either argument was default constructed == will always be false
* and != will always be true
*/
bool operator==( const OilVaporizationProperties& ) const;
bool operator!=( const OilVaporizationProperties& ) const;
private:
Opm::OilVaporizationEnum m_type = OilVaporizationEnum::UNDEF;
double m_vap1;
double m_vap2;
double m_maxDRSDT;
double m_maxDRVDT;
bool m_maxDRSDT_allCells;
};
}
#endif // DRSDT_H

View File

@@ -0,0 +1,187 @@
/*
Copyright 2013 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 SCHEDULE_HPP
#define SCHEDULE_HPP
#include <map>
#include <memory>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/GroupTree.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/OilVaporizationProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Util/OrderedMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
namespace Opm
{
class Deck;
class DeckKeyword;
class DeckRecord;
class EclipseGrid;
class Eclipse3DProperties;
class SCHEDULESection;
class TimeMap;
class UnitSystem;
class EclipseState;
class Schedule {
public:
Schedule(const Deck& deck,
const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties,
const Phases &phases,
const ParseContext& parseContext = ParseContext());
Schedule(const Deck& deck,
const EclipseState& es,
const ParseContext& parseContext = ParseContext());
/*
* If the input deck does not specify a start time, Eclipse's 1. Jan
* 1983 is defaulted
*/
time_t getStartTime() const;
time_t posixStartTime() const;
time_t posixEndTime() const;
const TimeMap& getTimeMap() const;
size_t numWells() const;
size_t numWells(size_t timestep) const;
size_t getMaxNumCompletionsForWells(size_t timestep) const;
bool hasWell(const std::string& wellName) const;
const Well* getWell(const std::string& wellName) const;
std::vector< const Well* > getOpenWells(size_t timeStep) const;
std::vector< const Well* > getWells() const;
std::vector< const Well* > getWells(size_t timeStep) const;
/*
The overload with a group name argument will return all
wells beneath that particular group; i.e.
getWells("FIELD",t);
is an inefficient way to get all the wells defined at time
't'.
*/
std::vector< const Well* > getWells(const std::string& group, size_t timeStep) const;
std::vector< const Well* > getWellsMatching( const std::string& ) const;
const OilVaporizationProperties& getOilVaporizationProperties(size_t timestep) const;
const GroupTree& getGroupTree(size_t t) const;
size_t numGroups() const;
bool hasGroup(const std::string& groupName) const;
const Group& getGroup(const std::string& groupName) const;
std::vector< const Group* > getGroups() const;
const Tuning& getTuning() const;
const MessageLimits& getMessageLimits() const;
const Events& getEvents() const;
const Deck& getModifierDeck(size_t timeStep) const;
bool hasOilVaporizationProperties() const;
const MessageContainer& getMessageContainer() const;
MessageContainer& getMessageContainer();
/*
Will remove all completions which are connected to cell which is not
active. Will scan through all wells and all timesteps.
*/
void filterCompletions(const EclipseGrid& grid);
private:
TimeMap m_timeMap;
OrderedMap< Well > m_wells;
std::map<std::string, Group > m_groups;
DynamicState< GroupTree > m_rootGroupTree;
DynamicState< OilVaporizationProperties > m_oilvaporizationproperties;
Events m_events;
DynamicVector< Deck > m_modifierDeck;
Tuning m_tuning;
MessageLimits m_messageLimits;
Phases m_phases;
MessageContainer m_messages;
WellProducer::ControlModeEnum m_controlModeWHISTCTL;
std::vector< Well* > getWells(const std::string& wellNamePattern);
void updateWellStatus( Well& well, size_t reportStep , WellCommon::StatusEnum status);
void addWellToGroup( Group& newGroup , Well& well , size_t timeStep);
void iterateScheduleSection(const ParseContext& parseContext , const SCHEDULESection& , const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties);
bool handleGroupFromWELSPECS(const std::string& groupName, GroupTree& newTree) const;
void addGroup(const std::string& groupName , size_t timeStep);
void addWell(const std::string& wellName, const DeckRecord& record, size_t timeStep, WellCompletion::CompletionOrderEnum wellCompletionOrder);
void handleCOMPORD(const ParseContext& parseContext, const DeckKeyword& compordKeyword, size_t currentStep);
void handleWELSPECS( const SCHEDULESection&, size_t, size_t );
void handleWCONProducer( const DeckKeyword& keyword, size_t currentStep, bool isPredictionMode);
void handleWCONHIST( const DeckKeyword& keyword, size_t currentStep);
void handleWCONPROD( const DeckKeyword& keyword, size_t currentStep);
void handleWGRUPCON( const DeckKeyword& keyword, size_t currentStep);
void handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
void handleCOMPLUMP( const DeckKeyword& keyword, size_t currentStep );
void handleWELSEGS( const DeckKeyword& keyword, size_t currentStep);
void handleCOMPSEGS( const DeckKeyword& keyword, size_t currentStep);
void handleWCONINJE( const SCHEDULESection&, const DeckKeyword& keyword, size_t currentStep);
void handleWPOLYMER( const DeckKeyword& keyword, size_t currentStep);
void handleWSOLVENT( const DeckKeyword& keyword, size_t currentStep);
void handleWTEMP( const DeckKeyword& keyword, size_t currentStep);
void handleWCONINJH( const SCHEDULESection&, const DeckKeyword& keyword, size_t currentStep);
void handleWELOPEN( const DeckKeyword& keyword, size_t currentStep );
void handleWELTARG( const SCHEDULESection&, const DeckKeyword& keyword, size_t currentStep);
void handleGCONINJE( const SCHEDULESection&, const DeckKeyword& keyword, size_t currentStep);
void handleGCONPROD( const DeckKeyword& keyword, size_t currentStep);
void handleGEFAC( const DeckKeyword& keyword, size_t currentStep);
void handleWEFAC( const DeckKeyword& keyword, size_t currentStep);
void handleTUNING( const DeckKeyword& keyword, size_t currentStep);
void handleGRUPTREE( const DeckKeyword& keyword, size_t currentStep);
void handleGRUPNET( const DeckKeyword& keyword, size_t currentStep);
void handleWRFT( const DeckKeyword& keyword, size_t currentStep);
void handleWRFTPLT( const DeckKeyword& keyword, size_t currentStep);
void handleWPIMULT( const DeckKeyword& keyword, size_t currentStep);
void handleDRSDT( const DeckKeyword& keyword, size_t currentStep);
void handleDRVDT( const DeckKeyword& keyword, size_t currentStep);
void handleVAPPARS( const DeckKeyword& keyword, size_t currentStep);
void handleWECON( const DeckKeyword& keyword, size_t currentStep);
void handleWHISTCTL(const ParseContext& parseContext, const DeckKeyword& keyword);
void handleMESSAGES(const DeckKeyword& keyword, size_t currentStep);
void checkUnhandledKeywords( const SCHEDULESection& ) const;
void checkIfAllConnectionsIsShut(size_t currentStep);
static double convertInjectionRateToSI(double rawRate, WellInjector::TypeEnum wellType, const Opm::UnitSystem &unitSystem);
static double convertInjectionRateToSI(double rawRate, Phase wellPhase, const Opm::UnitSystem &unitSystem);
static bool convertEclipseStringToBool(const std::string& eclipseString);
};
}
#endif

View File

@@ -0,0 +1,291 @@
/*
Copyright 2013 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 SCHEDULE_ENUMS_H
#define SCHEDULE_ENUMS_H
#include <string>
namespace Opm {
namespace WellCommon {
enum StatusEnum {
OPEN = 1,
STOP = 2,
SHUT = 3,
AUTO = 4
};
const std::string Status2String(StatusEnum enumValue);
StatusEnum StatusFromString(const std::string& stringValue);
}
namespace WellCompletion {
enum StateEnum {
OPEN = 1,
SHUT = 2,
AUTO = 3
};
enum DirectionEnum {
X = 1,
Y = 2,
Z = 3
};
enum CompletionOrderEnum{
DEPTH,
INPUT,
TRACK
};
std::string DirectionEnum2String(const DirectionEnum enumValue);
DirectionEnum DirectionEnumFromString(const std::string& stringValue);
const std::string StateEnum2String( StateEnum enumValue );
StateEnum StateEnumFromString( const std::string& stringValue );
const std::string CompletionOrderEnum2String( CompletionOrderEnum enumValue );
CompletionOrderEnum CompletionOrderEnumFromString(const std::string& comporderStringValue);
}
namespace WellInjector {
enum TypeEnum {
WATER = 1,
GAS = 2,
OIL = 3,
MULTI = 4
};
enum ControlModeEnum {
RATE = 1 ,
RESV = 2 ,
BHP = 4 ,
THP = 8 ,
GRUP = 16 ,
CMODE_UNDEFINED = 512
};
/*
The elements in this enum are used as bitmasks to keep track
of which controls are present, i.e. the 2^n structure must
be intact.
*/
const std::string ControlMode2String( ControlModeEnum enumValue );
ControlModeEnum ControlModeFromString( const std::string& stringValue );
const std::string Type2String( TypeEnum enumValue );
TypeEnum TypeFromString( const std::string& stringValue );
}
namespace WellProducer {
enum ControlModeEnum {
NONE = 0,
ORAT = 1,
WRAT = 2,
GRAT = 4,
LRAT = 8,
CRAT = 16,
RESV = 32,
BHP = 64,
THP = 128,
GRUP = 256,
CMODE_UNDEFINED = 1024
};
/*
The items BHP, THP and GRUP only apply in prediction mode:
WCONPROD. The elements in this enum are used as bitmasks to
keep track of which controls are present, i.e. the 2^n
structure must be intact.The NONE item is only used in WHISTCTL
to cancel its effect.
The properties are initialized with the CMODE_UNDEFINED
value, but the undefined value is never assigned apart from
that; and it is not part of the string conversion routines.
*/
const std::string ControlMode2String( ControlModeEnum enumValue );
ControlModeEnum ControlModeFromString( const std::string& stringValue );
}
namespace GroupInjection {
enum ControlEnum {
NONE = 0,
RATE = 1,
RESV = 2,
REIN = 3,
VREP = 4,
FLD = 5
};
const std::string ControlEnum2String( ControlEnum enumValue );
ControlEnum ControlEnumFromString( const std::string& stringValue );
}
namespace GroupProductionExceedLimit {
enum ActionEnum {
NONE = 0,
CON = 1,
CON_PLUS = 2, // String: "+CON"
WELL = 3,
PLUG = 4,
RATE = 5
};
const std::string ActionEnum2String( ActionEnum enumValue );
ActionEnum ActionEnumFromString( const std::string& stringValue );
}
namespace GroupProduction {
enum ControlEnum {
NONE = 0,
ORAT = 1,
WRAT = 2,
GRAT = 3,
LRAT = 4,
CRAT = 5,
RESV = 6,
PRBL = 7,
FLD = 8
};
const std::string ControlEnum2String( GroupProduction::ControlEnum enumValue );
GroupProduction::ControlEnum ControlEnumFromString( const std::string& stringValue );
}
namespace GuideRate {
enum GuideRatePhaseEnum {
OIL = 0,
WAT = 1,
GAS = 2,
LIQ = 3,
COMB = 4,
WGA = 5,
CVAL = 6,
RAT = 7,
RES = 8,
UNDEFINED = 9
};
const std::string GuideRatePhaseEnum2String( GuideRatePhaseEnum enumValue );
GuideRatePhaseEnum GuideRatePhaseEnumFromString( const std::string& stringValue );
}
namespace RFTConnections {
enum RFTEnum {
YES = 1,
REPT = 2,
TIMESTEP = 3,
FOPN = 4,
NO = 5
};
const std::string RFTEnum2String(RFTEnum enumValue);
RFTEnum RFTEnumFromString(const std::string &stringValue);
}
namespace PLTConnections{
enum PLTEnum{
YES = 1,
REPT = 2,
TIMESTEP = 3,
NO = 4
};
const std::string PLTEnum2String( PLTEnum enumValue);
PLTEnum PLTEnumFromString( const std::string& stringValue);
}
enum OilVaporizationEnum{
UNDEF = 0,
VAPPARS = 1,
DRSDT = 2,
DRVDT = 3
};
namespace WellSegment{
enum LengthDepthEnum {
INC = 0,
ABS = 1
};
const std::string LengthDepthEnumToString(LengthDepthEnum enumValue);
LengthDepthEnum LengthDepthEnumFromString(const std::string& stringValue);
enum CompPressureDropEnum {
HFA = 0,
HF_ = 1,
H__ = 2
};
const std::string CompPressureDropEnumToString(CompPressureDropEnum enumValue);
CompPressureDropEnum CompPressureDropEnumFromString(const std::string& stringValue);
enum MultiPhaseModelEnum {
HO = 0,
DF = 1
};
const std::string MultiPhaseModelEnumToString(MultiPhaseModelEnum enumValue);
MultiPhaseModelEnum MultiPhaseModelEnumFromString(const std::string& stringValue);
}
namespace WellEcon {
enum WorkoverEnum {
NONE = 0,
CON = 1, // CON
CONP = 2, // +CON
WELL = 3,
PLUG = 4,
// the following two only related to workover action
// on exceeding secondary water cut limit
LAST = 5,
RED = 6
};
const std::string WorkoverEnumToString(WorkoverEnum enumValue);
WorkoverEnum WorkoverEnumFromString(const std::string& stringValue);
enum QuantityLimitEnum {
RATE = 0,
POTN = 1
};
const std::string QuantityLimitEnumToString(QuantityLimitEnum enumValue);
QuantityLimitEnum QuantityLimitEnumFromString(const std::string& stringValue);
}
}
#endif

View File

@@ -0,0 +1,85 @@
/*
Copyright 2013 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 TIMEMAP_HPP_
#define TIMEMAP_HPP_
#include <vector>
#include <ctime>
#include <map>
namespace Opm {
class Deck;
class DeckKeyword;
class DeckRecord;
class TimeMap {
public:
explicit TimeMap(std::time_t startTime);
explicit TimeMap( const Deck& deck);
void addTime(std::time_t newTime);
void addTStep(int64_t step);
void addFromDATESKeyword( const DeckKeyword& DATESKeyword );
void addFromTSTEPKeyword( const DeckKeyword& TSTEPKeyword );
size_t size() const;
size_t last() const;
size_t numTimesteps() const;
double getTotalTime() const;
std::time_t operator[] (size_t index) const;
/// Return the date and time where a given time step starts.
std::time_t getStartTime(size_t tStepIdx) const;
std::time_t getEndTime() const;
/// Return the period of time in seconds which passed between the start of the simulation and a given point in time.
double getTimePassedUntil(size_t tLevelIdx) const;
/// Return the length of a given time step in seconds.
double getTimeStepLength(size_t tStepIdx) const;
/// Return true if the given timestep is the first one of a new month or year, or if frequency > 1,
/// return true for every n'th timestep of every first new month or first new year timesteps,
/// starting from start_timestep-1.
bool isTimestepInFirstOfMonthsYearsSequence(size_t timestep, bool years = true, size_t start_timestep = 1, size_t frequency = 1) const;
static std::time_t timeFromEclipse(const DeckRecord &dateRecord);
static std::time_t forward(std::time_t t0, int64_t hours, int64_t minutes, int64_t seconds);
static std::time_t forward(std::time_t t0, int64_t seconds);
static std::time_t mkdate(int year, int month, int day);
static std::time_t mkdatetime(int year, int month, int day, int hour, int minute, int second);
private:
static const std::map<std::string, int>& eclipseMonthIndices();
std::vector<std::time_t> m_timeList;
const std::vector<size_t>& getFirstTimestepMonths() const;
const std::vector<size_t>& getFirstTimestepYears() const;
bool isTimestepInFreqSequence (size_t timestep, size_t start_timestep, size_t frequency, bool years) const;
size_t closest(const std::vector<size_t> & vec, size_t value) const;
std::vector<size_t> m_first_timestep_years; // A list of the first timestep of every year
std::vector<size_t> m_first_timestep_months; // A list of the first timestep of every month
};
}
#endif /* TIMEMAP_HPP_ */

View File

@@ -0,0 +1,175 @@
/*
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_TUNING_HPP
#define OPM_TUNING_HPP
namespace Opm {
template< typename > class DynamicState;
class TimeMap;
class Tuning {
/*
When the TUNING keyword has occured in the Schedule section and
has been handled by the Schedule::handleTUNING() method,
the value for each TUNING keyword item is either
set from the keyword occurence or a default is set if specified in
the keyword description. Items that do not have a specified default
has got a separate <itemname>hasValue() method.
Before any TUNING keyword has occured in the Schedule section,
the different TUNING keyword items has got hardcoded default values
(See Tuning constructor)
Hardcoded values are set as the same as specified in the keyword description,
or 0 if no default is specified in the description.
*/
public:
explicit Tuning(const TimeMap& timemap);
void setTuningInitialValue(const std::string& tuningItem, double value,bool resetVector);
void setTuningInitialValue(const std::string& tuningItem, int value, bool resetVector);
void getTuningItemValue(const std::string& tuningItem, size_t timestep, double& value);
void getTuningItemValue(const std::string& tuningItem, size_t timestep, int& value);
/* Record 1 */
double getTSINIT(size_t timestep) const;
double getTSMAXZ(size_t timestep) const;
double getTSMINZ(size_t timestep) const;
double getTSMCHP(size_t timestep) const;
double getTSFMAX(size_t timestep) const;
double getTSFMIN(size_t timestep) const;
double getTSFCNV(size_t timestep) const;
double getTFDIFF(size_t timestep) const;
double getTHRUPT(size_t timestep) const;
double getTMAXWC(size_t timestep) const;
bool getTMAXWChasValue(size_t timestep) const;
void setTSINIT(size_t timestep, double TSINIT);
void setTSMAXZ(size_t timestep, double TSMAXZ);
void setTSMINZ(size_t timestep, double TSMINZ);
void setTSMCHP(size_t timestep, double TSMCHP);
void setTSFMAX(size_t timestep, double TSFMAX);
void setTSFMIN(size_t timestep, double TSFMIN);
void setTSFCNV(size_t timestep, double TSFCNV);
void setTFDIFF(size_t timestep, double TFDIFF);
void setTHRUPT(size_t timestep, double THRUPT);
void setTMAXWC(size_t timestep, double TMAXWC);
/* Record 2 */
double getTRGTTE(size_t timestep) const;
double getTRGCNV(size_t timestep) const;
double getTRGMBE(size_t timestep) const;
double getTRGLCV(size_t timestep) const;
double getXXXTTE(size_t timestep) const;
double getXXXCNV(size_t timestep) const;
double getXXXMBE(size_t timestep) const;
double getXXXLCV(size_t timestep) const;
double getXXXWFL(size_t timestep) const;
double getTRGFIP(size_t timestep) const;
double getTRGSFT(size_t timestep) const;
bool getTRGSFThasValue(size_t timestep) const;
double getTHIONX(size_t timestep) const;
int getTRWGHT(size_t timestep) const;
void setTRGTTE(size_t timestep, double TRGTTE);
void setTRGCNV(size_t timestep, double TRGCNV);
void setTRGMBE(size_t timestep, double TRGMBE);
void setTRGLCV(size_t timestep, double TRGLCV);
void setXXXTTE(size_t timestep, double XXXTTE);
void setXXXCNV(size_t timestep, double XXXCNV);
void setXXXMBE(size_t timestep, double XXXMBE);
void setXXXLCV(size_t timestep, double XXXLCV);
void setXXXWFL(size_t timestep, double XXXWFL);
void setTRGFIP(size_t timestep, double TRGFIP);
void setTRGSFT(size_t timestep, double TRGFIP);
void setTHIONX(size_t timestep, double THIONX);
void setTRWGHT(size_t timestep, int TRWGHT);
/* Record 3 */
int getNEWTMX(size_t timestep) const;
int getNEWTMN(size_t timestep) const;
int getLITMAX(size_t timestep) const;
int getLITMIN(size_t timestep) const;
int getMXWSIT(size_t timestep) const;
int getMXWPIT(size_t timestep) const;
double getDDPLIM(size_t timestep) const;
double getDDSLIM(size_t timestep) const;
double getTRGDPR(size_t timestep) const;
double getXXXDPR(size_t timestep) const;
bool getXXXDPRhasValue(size_t timestep) const;
void setNEWTMX(size_t timestep, int NEWTMX);
void setNEWTMN(size_t timestep, int NEWTMN);
void setLITMAX(size_t timestep, int LITMAX);
void setLITMIN(size_t timestep, int LITMIN);
void setMXWSIT(size_t timestep, int MXWSIT);
void setMXWPIT(size_t timestep, int MXWPIT);
void setDDPLIM(size_t timestep, double DDPLIM);
void setDDSLIM(size_t timestep, double DDSLIM);
void setTRGDPR(size_t timestep, double TRGDPR);
void setXXXDPR(size_t timestep, double XXXDPR);
private:
/* Record1 */
DynamicState<double> m_TSINIT;
DynamicState<double> m_TSMAXZ;
DynamicState<double> m_TSMINZ;
DynamicState<double> m_TSMCHP;
DynamicState<double> m_TSFMAX;
DynamicState<double> m_TSFMIN;
DynamicState<double> m_TSFCNV;
DynamicState<double> m_TFDIFF;
DynamicState<double> m_THRUPT;
DynamicState<double> m_TMAXWC;
DynamicState<int> m_TMAXWC_has_value;
/* Record 2 */
DynamicState<double> m_TRGTTE;
DynamicState<double> m_TRGCNV;
DynamicState<double> m_TRGMBE;
DynamicState<double> m_TRGLCV;
DynamicState<double> m_XXXTTE;
DynamicState<double> m_XXXCNV;
DynamicState<double> m_XXXMBE;
DynamicState<double> m_XXXLCV;
DynamicState<double> m_XXXWFL;
DynamicState<double> m_TRGFIP;
DynamicState<double> m_TRGSFT;
DynamicState<int> m_TRGSFT_has_value;
DynamicState<double> m_THIONX;
DynamicState<int> m_TRWGHT;
/* Record 3 */
DynamicState<int> m_NEWTMX;
DynamicState<int> m_NEWTMN;
DynamicState<int> m_LITMAX;
DynamicState<int> m_LITMIN;
DynamicState<int> m_MXWSIT;
DynamicState<int> m_MXWPIT;
DynamicState<double> m_DDPLIM;
DynamicState<double> m_DDSLIM;
DynamicState<double> m_TRGDPR;
DynamicState<double> m_XXXDPR;
DynamicState<int> m_XXXDPR_has_value;
std::map<std::string, bool> m_ResetValue;
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,216 @@
/*
Copyright 2013 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 WELL_HPP_
#define WELL_HPP_
#include <memory>
#include <string>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellEconProductionLimits.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/SegmentSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
namespace Opm {
template< typename > class DynamicState;
class Completion;
class CompletionSet;
class Segment;
class SegmentSet;
class TimeMap;
class EclipseGrid;
class Well {
public:
Well(const std::string& name, int headI,
int headJ, double refDepth, Phase preferredPhase,
const TimeMap& timeMap, size_t creationTimeStep,
WellCompletion::CompletionOrderEnum completionOrdering = WellCompletion::TRACK,
bool allowCrossFlow = true, bool automaticShutIn = true);
const std::string& name() const;
bool hasBeenDefined(size_t timeStep) const;
const std::string getGroupName(size_t timeStep) const;
void setGroupName(size_t timeStep , const std::string& groupName);
WellCommon::StatusEnum getStatus(size_t timeStep) const;
bool setStatus(size_t timeStep, WellCommon::StatusEnum Status);
int getHeadI() const;
int getHeadJ() const;
int getHeadI( size_t timestep ) const;
int getHeadJ( size_t timestep ) const;
void setHeadI( size_t timestep, int I );
void setHeadJ( size_t timestep, int J );
double getRefDepth() const;
double getRefDepth( size_t timestep ) const;
void setRefDepth( size_t timestep, double );
Phase getPreferredPhase() const;
bool isAvailableForGroupControl(size_t timeStep) const;
void setAvailableForGroupControl(size_t timeStep, bool isAvailableForGroupControl);
double getGuideRate(size_t timeStep) const;
void setGuideRate(size_t timeStep, double guideRate);
GuideRate::GuideRatePhaseEnum getGuideRatePhase(size_t timeStep) const;
void setGuideRatePhase(size_t timeStep, GuideRate::GuideRatePhaseEnum phase);
double getGuideRateScalingFactor(size_t timeStep) const;
void setGuideRateScalingFactor(size_t timeStep, double scalingFactor);
void setEfficiencyFactor (size_t timestep, double efficiencyFactor);
double getEfficiencyFactor (size_t timestep) const;
void switchToInjector( size_t timeStep);
void switchToProducer( size_t timeStep);
bool isProducer(size_t timeStep) const;
bool isInjector(size_t timeStep) const;
void addWELSPECS(const DeckRecord& deckRecord);
void addCompletions(size_t time_step, const std::vector< Completion >& );
void addCompletionSet(size_t time_step, CompletionSet );
const CompletionSet& getCompletions(size_t timeStep) const;
const CompletionSet& getCompletions() const;
/* The rate of a given phase under the following assumptions:
* * Returns zero if production is requested for an injector (and vice
* versa)
* * If this is an injector and something else than the
* requested phase is injected, returns 0, i.e.
* water_injector.injection_rate( gas ) == 0
* * Mixed injection is not supported and always returns 0.
*/
double production_rate( Phase phase, size_t timestep ) const;
double injection_rate( Phase phase, size_t timestep ) const;
bool operator==(const Well&) const;
bool operator!=(const Well&) const;
bool setProductionProperties(size_t timeStep , const WellProductionProperties& properties);
WellProductionProperties getProductionPropertiesCopy(size_t timeStep) const;
const WellProductionProperties& getProductionProperties(size_t timeStep) const;
bool setInjectionProperties(size_t timeStep , const WellInjectionProperties& properties);
WellInjectionProperties getInjectionPropertiesCopy(size_t timeStep) const;
const WellInjectionProperties& getInjectionProperties(size_t timeStep) const;
bool setPolymerProperties(size_t timeStep , const WellPolymerProperties& properties);
WellPolymerProperties getPolymerPropertiesCopy(size_t timeStep) const;
const WellPolymerProperties& getPolymerProperties(size_t timeStep) const;
bool setSolventFraction(size_t timeStep , const double fraction);
const double& getSolventFraction(size_t timeStep) const;
bool setEconProductionLimits(const size_t timeStep, const WellEconProductionLimits& productionlimits);
const WellEconProductionLimits& getEconProductionLimits(const size_t timeStep) const;
int firstRFTOutput( ) const;
bool getRFTActive(size_t time_step) const;
void updateRFTActive(size_t time_step, RFTConnections::RFTEnum mode);
bool getPLTActive(size_t time_step) const;
void updatePLTActive(size_t time_step, PLTConnections::PLTEnum mode);
int findWellFirstOpen(int startTimeStep) const;
/*
Will return the report step when the well is created with
WELSPECS, actually opening the well might be later.
*/
size_t firstTimeStep( ) const;
void setRFTForWellWhenFirstOpen(size_t currentStep);
static bool wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern);
WellCompletion::CompletionOrderEnum getWellCompletionOrdering() const;
bool getAllowCrossFlow() const;
bool getAutomaticShutIn() const;
bool canOpen(size_t time_step) const;
// for multi-segment wells
bool isMultiSegment(size_t time_step) const;
const SegmentSet& getSegmentSet(size_t time_step) const;
void addSegmentSet(size_t time_step, SegmentSet new_segmentset);
const MessageContainer& getMessageContainer() const;
const Events& getEvents() const;
void addEvent(ScheduleEvents::Events event, size_t reportStep);
bool hasEvent(uint64_t eventMask, size_t reportStep) const;
/*
Will remove all completions which are attached to inactive cells. Will
scan through all timesteps.
*/
void filterCompletions(const EclipseGrid& grid);
private:
size_t m_creationTimeStep;
std::string m_name;
DynamicState< WellCommon::StatusEnum > m_status;
DynamicState< int > m_isAvailableForGroupControl;
DynamicState< double > m_guideRate;
DynamicState< GuideRate::GuideRatePhaseEnum > m_guideRatePhase;
DynamicState< double > m_guideRateScalingFactor;
DynamicState< double > m_efficiencyFactors;
DynamicState< int > m_isProducer;
DynamicState< CompletionSet > m_completions;
DynamicState< WellProductionProperties > m_productionProperties;
DynamicState< WellInjectionProperties > m_injectionProperties;
DynamicState< WellPolymerProperties > m_polymerProperties;
DynamicState< WellEconProductionLimits > m_econproductionlimits;
DynamicState< double > m_solventFraction;
DynamicState< std::string > m_groupName;
DynamicState< int > m_rft;
DynamicState< int > m_plt;
DynamicState< int > m_headI;
DynamicState< int > m_headJ;
DynamicState< double > m_refDepth;
Phase m_preferredPhase;
WellCompletion::CompletionOrderEnum m_comporder;
bool m_allowCrossFlow;
bool m_automaticShutIn;
MessageContainer m_messages;
// WELSEGS DATA - for mutli-segment wells
// flag indicating if the well is a multi-segment well
DynamicState< SegmentSet > m_segmentset;
size_t timesteps;
Events events;
};
}
#endif /* WELL_HPP_ */

View File

@@ -0,0 +1,169 @@
/*
Copyright 2016 SINTEF ICT, Applied Mathematics.
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 WELLECONPRODUCTIONLIMITS_HPP_HEADER_INCLUDED
#define WELLECONPRODUCTIONLIMITS_HPP_HEADER_INCLUDED
#include <string>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
namespace Opm {
class DeckRecord;
class WellEconProductionLimits{
public:
explicit WellEconProductionLimits(const DeckRecord& record);
WellEconProductionLimits();
// TODO: not handling things related to m_secondary_max_water_cut
// for the moment.
// limit switch on?
bool onAnyEffectiveLimit() const {
return (onAnyRatioLimit() ||
onAnyRateLimit());
};
bool onAnyRatioLimit() const {
return (onMaxWaterCut() ||
onMaxGasOilRatio() ||
onMaxWaterGasRatio() ||
onMaxGasLiquidRatio());
};
bool onAnyRateLimit() const {
return (onMinOilRate() ||
onMinGasRate() ||
onMinLiquidRate() ||
onMinReservoirFluidRate());
};
bool onMinOilRate() const {
return (m_min_oil_rate > 0.0);
};
bool onMinGasRate() const {
return (m_min_gas_rate > 0.0);
};
bool onMaxWaterCut() const {
return (m_max_water_cut > 0.0);
};
bool onMaxGasOilRatio() const {
return (m_max_gas_oil_ratio > 0.0);
};
bool onMaxWaterGasRatio() const {
return (m_max_water_gas_ratio > 0.0);
};
bool onSecondaryMaxWaterCut() const {
return (m_secondary_max_water_cut > 0.0);
};
bool onMaxGasLiquidRatio() const {
return (m_max_gas_oil_ratio > 0.0);
};
// assuming Celsius temperature is used internally
bool onMaxTemperature() const {
return (m_max_temperature > -273.15);
};
bool onMinLiquidRate() const {
return (m_min_liquid_rate > 0.0);
};
bool onMinReservoirFluidRate() const {
return (m_min_reservoir_fluid_rate > 0.0);
};
// not sure what will happen if the followon well is a well does not exist.
bool validFollowonWell() const {
return (m_followon_well != "'");
};
bool requireWorkover() const {
return (m_workover != WellEcon::NONE);
};
bool requireSecondaryWorkover() const {
return (m_workover_secondary != WellEcon::NONE);
}
bool endRun() const {
return m_end_run;
}
double minOilRate() const { return m_min_oil_rate; };
double minGasRate() const { return m_min_gas_rate; };
double maxWaterCut() const { return m_max_water_cut; };
double maxGasOilRatio() const { return m_max_gas_oil_ratio; };
double maxWaterGasRatio() const { return m_max_water_gas_ratio; };
WellEcon::WorkoverEnum workover() const { return m_workover; };
const std::string& followonWell() const { return m_followon_well; };
WellEcon::QuantityLimitEnum quantityLimit() const {return m_quantity_limit; };
double maxSecondaryMaxWaterCut() const { return m_secondary_max_water_cut; };
WellEcon::WorkoverEnum workoverSecondary() const { return m_workover_secondary; };
double maxGasLiquidRatio() const { return m_max_gas_liquid_ratio; };
double minLiquidRate() const { return m_min_liquid_rate; };
double maxTemperature() const { return m_max_temperature; };
double minReservoirFluidRate() const { return m_min_reservoir_fluid_rate; };
bool operator==(const WellEconProductionLimits& other) const;
bool operator!=(const WellEconProductionLimits& other) const;
private:
double m_min_oil_rate;
double m_min_gas_rate;
double m_max_water_cut;
double m_max_gas_oil_ratio;
double m_max_water_gas_ratio;
WellEcon::WorkoverEnum m_workover;
bool m_end_run;
std::string m_followon_well;
WellEcon::QuantityLimitEnum m_quantity_limit;
double m_secondary_max_water_cut;
WellEcon::WorkoverEnum m_workover_secondary;
double m_max_gas_liquid_ratio;
double m_min_liquid_rate;
double m_max_temperature;
double m_min_reservoir_fluid_rate;
};
} // namespace Opm
#endif // WELLECONPRODUCTIONLIMITS_HPP_HEADER_INCLUDED

View File

@@ -0,0 +1,68 @@
/*
Copyright 2014 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 WELLINJECTIONPROPERTIES_HPP_HEADER_INCLUDED
#define WELLINJECTIONPROPERTIES_HPP_HEADER_INCLUDED
#include <iosfwd>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
namespace Opm {
struct WellInjectionProperties {
double surfaceInjectionRate;
double reservoirInjectionRate;
double temperature;
double BHPLimit;
double THPLimit;
double BHPH;
double THPH;
int VFPTableNumber;
bool predictionMode;
int injectionControls;
WellInjector::TypeEnum injectorType;
WellInjector::ControlModeEnum controlMode;
bool operator==(const WellInjectionProperties& other) const;
bool operator!=(const WellInjectionProperties& other) const;
WellInjectionProperties();
bool hasInjectionControl(WellInjector::ControlModeEnum controlModeArg) const {
if (injectionControls & controlModeArg)
return true;
else
return false;
}
void dropInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) != 0)
injectionControls -= controlModeArg;
}
void addInjectionControl(WellInjector::ControlModeEnum controlModeArg) {
if ((injectionControls & controlModeArg) == 0)
injectionControls += controlModeArg;
}
};
std::ostream& operator<<( std::ostream&, const WellInjectionProperties& );
}
#endif

View File

@@ -0,0 +1,36 @@
/*
Copyright 2014 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 WELLPOLYMERPROPERTIES_HPP_HEADER_INCLUDED
#define WELLPOLYMERPROPERTIES_HPP_HEADER_INCLUDED
namespace Opm {
struct WellPolymerProperties {
double m_polymerConcentration;
double m_saltConcentration;
bool operator==(const WellPolymerProperties& other) const;
bool operator!=(const WellPolymerProperties& other) const;
WellPolymerProperties();
};
}
#endif

View File

@@ -0,0 +1,85 @@
/*
Copyright 2013 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 WELLPRODUCTIONPROPERTIES_HPP_HEADER_INCLUDED
#define WELLPRODUCTIONPROPERTIES_HPP_HEADER_INCLUDED
#include <iosfwd>
#include <memory>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
namespace Opm {
class DeckRecord;
class WellProductionProperties {
public:
// the rates serve as limits under prediction mode
// while they are observed rates under historical mode
double OilRate = 0.0;
double WaterRate = 0.0;
double GasRate = 0.0;
double LiquidRate = 0.0;
double ResVRate = 0.0;
// BHP and THP limit
double BHPLimit = 0.0;
double THPLimit = 0.0;
// historical BHP and THP under historical mode
double BHPH = 0.0;
double THPH = 0.0;
int VFPTableNumber = 0;
double ALQValue = 0.0;
bool predictionMode = false;
WellProducer::ControlModeEnum controlMode = WellProducer::CMODE_UNDEFINED;
bool operator==(const WellProductionProperties& other) const;
bool operator!=(const WellProductionProperties& other) const;
WellProductionProperties();
static WellProductionProperties history(double BHPLimit, const DeckRecord& record);
static WellProductionProperties prediction( const DeckRecord& record, bool addGroupProductionControl );
bool hasProductionControl(WellProducer::ControlModeEnum controlModeArg) const {
return (m_productionControls & controlModeArg) != 0;
}
void dropProductionControl(WellProducer::ControlModeEnum controlModeArg) {
if (hasProductionControl(controlModeArg))
m_productionControls -= controlModeArg;
}
void addProductionControl(WellProducer::ControlModeEnum controlModeArg) {
if (! hasProductionControl(controlModeArg))
m_productionControls += controlModeArg;
}
private:
int m_productionControls = 0;
WellProductionProperties(const DeckRecord& record);
};
std::ostream& operator<<( std::ostream&, const WellProductionProperties& );
} // namespace Opm
#endif // WELLPRODUCTIONPROPERTIES_HPP_HEADER_INCLUDED

View File

@@ -0,0 +1,54 @@
/*
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_SIMULATION_CONFIG_HPP
#define OPM_SIMULATION_CONFIG_HPP
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>
namespace Opm {
class Deck;
class Eclipse3DProperties;
class SimulationConfig {
public:
SimulationConfig(const Deck& deck,
const Eclipse3DProperties& gridProperties);
const ThresholdPressure& getThresholdPressure() const;
bool hasThresholdPressure() const;
bool useCPR() const;
bool hasDISGAS() const;
bool hasVAPOIL() const;
private:
ThresholdPressure m_ThresholdPressure;
bool m_useCPR;
bool m_DISGAS;
bool m_VAPOIL;
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,78 @@
/*
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_TRESHOLD_PRESSURES_HPP
#define OPM_TRESHOLD_PRESSURES_HPP
#include <map>
#include <vector>
namespace Opm {
class Deck;
class Eclipse3DProperties;
class ThresholdPressure {
public:
ThresholdPressure(const Deck& deck,
const Eclipse3DProperties& eclipseProperties);
/*
The hasRegionBarrier() method checks if a threshold pressure
has been configured between the equilibration regions r1 and
r2; i.e. if the deck contains a THPRES record with regions
r1 and r2.
*/
bool hasRegionBarrier(int r1 , int r2) const;
/*
Checks if a threshold presssure has been configured between
the equilibration regions r1 and r2; the function will
return false either if no THPRES record with r1 and r2 has
been configured - or if THPRES record with ra and r2 has
defaulted pressure.
*/
bool hasThresholdPressure(int r1 , int r2) const;
/*
Will return the threshold pressure between equilibration
regions r1 and r2; if the pressure has been defaulted the
function will raise the error
INTERNAL_ERROR_UNINITIALIZED_THPRES - check with
hasThresholdPressure(r1,r2) first to be safe.
*/
double getThresholdPressure(int r1 , int r2) const;
size_t size() const;
private:
static std::pair<int,int> makeIndex(int r1 , int r2);
void addPair(int r1 , int r2 , const std::pair<bool , double>& valuePair);
void addBarrier(int r1 , int r2);
void addBarrier(int r1 , int r2 , double p);
std::vector<std::pair<bool,double>> m_thresholdPressureTable;
std::map<std::pair<int,int> , std::pair<bool , double> > m_pressureTable;
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,90 @@
/*
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_SUMMARY_CONFIG_HPP
#define OPM_SUMMARY_CONFIG_HPP
#include <array>
#include <vector>
#include <set>
#include <ert/ecl/Smspec.hpp>
namespace Opm {
class Deck;
class TableManager;
class EclipseState;
class ParserKeyword;
class Schedule;
class ParseContext;
class GridDims;
class SummaryConfig {
public:
typedef std::vector< ERT::smspec_node >::const_iterator const_iterator;
SummaryConfig( const Deck&, const Schedule&,
const TableManager&, const ParseContext&);
const_iterator begin() const;
const_iterator end() const;
SummaryConfig& merge( const SummaryConfig& );
SummaryConfig& merge( SummaryConfig&& );
/*
The hasKeyword() method will consult the internal set
'short_keywords', i.e. the query should be based on pure
keywords like 'WWCT' and 'BPR' - and *not* fully
identifiers like 'WWCT:OPX' and 'BPR:10,12,3'.
*/
bool hasKeyword( const std::string& keyword ) const;
/*
The hasSummaryKey() method will look for fully
qualified keys like 'RPR:3' and 'BPR:10,15,20.
*/
bool hasSummaryKey(const std::string& keyword ) const;
/*
Can be used to query if a certain 3D field, e.g. PRESSURE,
is required to calculate the summary variables.
*/
bool require3DField( const std::string& keyword) const;
bool requireFIPNUM( ) const;
private:
SummaryConfig( const Deck& deck,
const Schedule& schedule,
const TableManager& tables,
const ParseContext& parseContext,
const GridDims& dims);
/*
The short_keywords set contains only the pure keyword
part, e.g. "WWCT", and not the qualification with
well/group name or a numerical value.
*/
std::vector< ERT::smspec_node > keywords;
std::set<std::string> short_keywords;
std::set<std::string> summary_keywords;
};
} //namespace Opm
#endif

View File

@@ -0,0 +1,112 @@
/*
Copyright (C) 2017 TNO
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 AQUDIMS_HPP
#define AQUDIMS_HPP
/*
The Aqudims class is a small utility class designed to hold on to
the values from the AQUDIMS keyword.
*/
#include <opm/parser/eclipse/Parser/ParserKeywords/A.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
namespace Opm {
class Aqudims {
public:
Aqudims() :
m_mxnaqn( ParserKeywords::AQUDIMS::MXNAQN::defaultValue ),
m_mxnaqc( ParserKeywords::AQUDIMS::MXNAQC::defaultValue ),
m_niftbl( ParserKeywords::AQUDIMS::NIFTBL::defaultValue ),
m_nriftb( ParserKeywords::AQUDIMS::NRIFTB::defaultValue ),
m_nanaqu( ParserKeywords::AQUDIMS::NANAQU::defaultValue ),
m_ncamax( ParserKeywords::AQUDIMS::NCAMAX::defaultValue ),
m_mxnali( ParserKeywords::AQUDIMS::MXNALI::defaultValue ),
m_mxaaql( ParserKeywords::AQUDIMS::MXAAQL::defaultValue )
{ }
explicit Aqudims(const Deck& deck) :
Aqudims()
{
if (deck.hasKeyword("AQUDIMS")) {
const auto& record = deck.getKeyword( "AQUDIMS" , 0 ).getRecord( 0 );
m_mxnaqn = record.getItem("MXNAQN").get<int>(0);
m_mxnaqc = record.getItem("MXNAQC").get<int>(0);
m_niftbl = record.getItem("NIFTBL").get<int>(0);
m_nriftb = record.getItem("NRIFTB").get<int>(0);
m_nanaqu = record.getItem("NANAQU").get<int>(0);
m_ncamax = record.getItem("NCAMAX").get<int>(0);
m_mxnali = record.getItem("MXNALI").get<int>(0);
m_mxaaql = record.getItem("MXAAQL").get<int>(0);
}
}
size_t getNumAqunum() const
{
return m_mxnaqn;
}
size_t getNumConnectionNumericalAquifer() const
{
return m_mxnaqc;
}
size_t getNumInfluenceTablesCT() const
{
return m_niftbl;
}
size_t getNumRowsInfluenceTable() const
{
return m_nriftb;
}
size_t getNumAnalyticAquifers() const
{
return m_nanaqu;
}
size_t getNumRowsAquancon() const
{
return m_ncamax;
}
size_t getNumAquiferLists() const
{
return m_mxnali;
}
size_t getNumAnalyticAquifersSingleList() const
{
return m_mxaaql;
}
private:
size_t m_mxnaqn , m_mxnaqc , m_niftbl , m_nriftb , m_nanaqu , m_ncamax , m_mxnali , m_mxaaql;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2017 TNO
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_AQUTAB_TABLE_HPP
#define OPM_PARSER_AQUTAB_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class AqutabTable : public SimpleTable {
public:
AqutabTable( const DeckItem& item );
const TableColumn& getTimeColumn() const;
const TableColumn& getPressureColumn() const;
};
}
#endif

View File

@@ -0,0 +1,52 @@
/*
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_COLUMN_SCHEMA_HPP
#define OPM_COLUMN_SCHEMA_HPP
#include <string>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Tables/TableEnums.hpp>
namespace Opm {
class ColumnSchema {
public:
ColumnSchema(const std::string& name , Table::ColumnOrderEnum order, Table::DefaultAction defaultAction);
ColumnSchema(const std::string& name , Table::ColumnOrderEnum order, double defaultValue);
const std::string& name() const;
bool validOrder( double value1 , double value2) const;
bool lookupValid( ) const;
bool acceptsDefault( ) const;
bool isIncreasing( ) const;
bool isDecreasing( ) const;
Table::DefaultAction getDefaultMode( ) const;
double getDefaultValue( ) const;
private:
std::string m_name;
Table::ColumnOrderEnum m_order;
Table::DefaultAction m_defaultAction;
double m_defaultValue;
};
}
#endif

View File

@@ -0,0 +1,81 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_ENKRVD_TABLE_HPP
#define OPM_PARSER_ENKRVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class EnkrvdTable : public SimpleTable {
public:
EnkrvdTable( const DeckItem& item );
// using this method is strongly discouraged but the current endpoint scaling
// code makes it hard to avoid
using SimpleTable::getColumn;
/*!
* \brief The datum depth for the remaining columns
*/
const TableColumn& getDepthColumn() const;
/*!
* \brief Maximum relative permeability of water
*/
const TableColumn& getKrwmaxColumn() const;
/*!
* \brief Maximum relative permeability of gas
*/
const TableColumn& getKrgmaxColumn() const;
/*!
* \brief Maximum relative permeability of oil
*/
const TableColumn& getKromaxColumn() const;
/*!
* \brief Relative permeability of water at the critical oil (or gas) saturation
*/
const TableColumn& getKrwcritColumn() const;
/*!
* \brief Relative permeability of gas at the critical oil (or water) saturation
*/
const TableColumn& getKrgcritColumn() const;
/*!
* \brief Oil relative permeability of oil at the critical gas saturation
*/
const TableColumn& getKrocritgColumn() const;
/*!
* \brief Oil relative permeability of oil at the critical water saturation
*/
const TableColumn& getKrocritwColumn() const;
};
}
#endif

View File

@@ -0,0 +1,81 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_ENPTVD_TABLE_HPP
#define OPM_PARSER_ENPTVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class EnptvdTable : public SimpleTable {
public:
EnptvdTable( const DeckItem& item );
// using this method is strongly discouraged but the current endpoint scaling
// code makes it hard to avoid
using SimpleTable::getColumn;
const TableColumn& getDepthColumn() const;
/*!
* \brief Connate water saturation
*/
const TableColumn& getSwcoColumn() const;
/*!
* \brief Critical water saturation
*/
const TableColumn& getSwcritColumn() const;
/*!
* \brief Maximum water saturation
*/
const TableColumn& getSwmaxColumn() const;
/*!
* \brief Connate gas saturation
*/
const TableColumn& getSgcoColumn() const;
/*!
* \brief Critical gas saturation
*/
const TableColumn& getSgcritColumn() const;
/*!
* \brief Maximum gas saturation
*/
const TableColumn& getSgmaxColumn() const;
/*!
* \brief Critical oil-in-water saturation
*/
const TableColumn& getSowcritColumn() const;
/*!
* \brief Critical oil-in-gas saturation
*/
const TableColumn& getSogcritColumn() const;
};
}
#endif

View File

@@ -0,0 +1,83 @@
/*
Copyright (C) 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 EQLDIMS_HPP
#define EQLDIMS_HPP
/*
The Eqldims class is a small utility class designed to hold on to
the values from the EQLDIMS keyword.
*/
#include <opm/parser/eclipse/Parser/ParserKeywords/E.hpp>
namespace Opm {
class Eqldims {
public:
Eqldims() :
m_ntequl( ParserKeywords::EQLDIMS::NTEQUL::defaultValue ),
m_depth_nodes_p( ParserKeywords::EQLDIMS::DEPTH_NODES_P::defaultValue ),
m_depth_nodes_tab( ParserKeywords::EQLDIMS::DEPTH_NODES_TAB::defaultValue ),
m_nttrvd( ParserKeywords::EQLDIMS::NTTRVD::defaultValue ),
m_nstrvd( ParserKeywords::EQLDIMS::NSTRVD::defaultValue )
{ }
Eqldims( size_t ntequl , size_t depth_nodes_p , size_t depth_nodes_tab , size_t nttrvd , size_t nstrvd) :
m_ntequl( ntequl ),
m_depth_nodes_p( depth_nodes_p ),
m_depth_nodes_tab( depth_nodes_tab ),
m_nttrvd( nttrvd ),
m_nstrvd( nstrvd )
{ }
size_t getNumEquilRegions() const
{
return m_ntequl;
}
size_t getNumDepthNodesP() const
{
return m_depth_nodes_p;
}
size_t getNumDepthNodesTable() const
{
return m_depth_nodes_tab;
}
size_t getNumTracerTables() const
{
return m_nttrvd;
}
size_t getNumDepthNodesTracer() const
{
return m_nstrvd;
}
private:
size_t m_ntequl , m_depth_nodes_p , m_depth_nodes_tab , m_nttrvd , m_nstrvd;
};
}
#endif

View File

@@ -0,0 +1,90 @@
#ifndef OPM_FLAT_TABLE_HPP
#define OPM_FLAT_TABLE_HPP
namespace Opm {
class DeckKeyword;
template< typename T >
struct FlatTable : public std::vector< T > {
FlatTable() = default;
explicit FlatTable( const DeckKeyword& );
};
struct DENSITYRecord {
static constexpr std::size_t size = 3;
double oil;
double water;
double gas;
};
struct DensityTable : public FlatTable< DENSITYRecord > {
using FlatTable< DENSITYRecord >::FlatTable;
};
struct PVTWRecord {
static constexpr std::size_t size = 5;
double reference_pressure;
double volume_factor;
double compressibility;
double viscosity;
double viscosibility;
};
struct PvtwTable : public FlatTable< PVTWRecord > {
using FlatTable< PVTWRecord >::FlatTable;
};
struct ROCKRecord {
static constexpr std::size_t size = 2;
double reference_pressure;
double compressibility;
};
struct RockTable : public FlatTable< ROCKRecord > {
using FlatTable< ROCKRecord >::FlatTable;
};
struct PVCDORecord {
static constexpr std::size_t size = 5;
double reference_pressure;
double volume_factor;
double compressibility;
double viscosity;
double viscosibility;
};
struct PvcdoTable : public FlatTable< PVCDORecord > {
using FlatTable< PVCDORecord >::FlatTable;
};
struct VISCREFRecord {
static constexpr std::size_t size = 2;
double reference_pressure;
double reference_rs;
};
struct ViscrefTable : public FlatTable< VISCREFRecord > {
using FlatTable< VISCREFRecord >::FlatTable;
};
struct WATDENTRecord {
static constexpr std::size_t size = 3;
double reference_temperature;
double first_coefficient;
double second_coefficient;
};
struct WatdentTable : public FlatTable< WATDENTRecord > {
using FlatTable< WATDENTRecord >::FlatTable;
};
}
#endif //OPM_FLAT_TABLE_HPP

View File

@@ -0,0 +1,39 @@
/*
Copyright (C) 2015 by Andreas Lauser
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_GASVISCT_TABLE_HPP
#define OPM_PARSER_GASVISCT_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class Deck;
class DeckItem;
class GasvisctTable : public SimpleTable {
public:
GasvisctTable( const Deck& deck, const DeckItem& deckItem );
const TableColumn& getTemperatureColumn() const;
const TableColumn& getGasViscosityColumn(size_t compIdx) const;
};
}
#endif

View File

@@ -0,0 +1,74 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_IMKRVD_TABLE_HPP
#define OPM_PARSER_IMKRVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class ImkrvdTable : public SimpleTable {
public:
ImkrvdTable( const DeckItem& item );
/*!
* \brief The datum depth for the remaining columns
*/
const TableColumn& getDepthColumn() const;
/*!
* \brief Maximum relative permeability of water
*/
const TableColumn& getKrwmaxColumn() const;
/*!
* \brief Maximum relative permeability of gas
*/
const TableColumn& getKrgmaxColumn() const;
/*!
* \brief Maximum relative permeability of oil
*/
const TableColumn& getKromaxColumn() const;
/*!
* \brief Relative permeability of water at the critical oil (or gas) saturation
*/
const TableColumn& getKrwcritColumn() const;
/*!
* \brief Relative permeability of gas at the critical oil (or water) saturation
*/
const TableColumn& getKrgcritColumn() const;
/*!
* \brief Oil relative permeability of oil at the critical gas saturation
*/
const TableColumn& getKrocritgColumn() const;
/*!
* \brief Oil relative permeability of oil at the critical water saturation
*/
const TableColumn& getKrocritwColumn() const;
};
}
#endif

View File

@@ -0,0 +1,80 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_IMPTVD_TABLE_HPP
#define OPM_PARSER_IMPTVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class ImptvdTable : public SimpleTable {
public:
ImptvdTable( const DeckItem& item );
const TableColumn& getDepthColumn() const;
/*!
* \brief Connate water saturation
*/
const TableColumn& getSwcoColumn() const;
/*!
* \brief Critical water saturation
*/
const TableColumn& getSwcritColumn() const;
/*!
* \brief Maximum water saturation
*/
const TableColumn& getSwmaxColumn() const;
/*!
* \brief Connate gas saturation
*/
const TableColumn& getSgcoColumn() const;
/*!
* \brief Critical gas saturation
*/
const TableColumn& getSgcritColumn() const;
/*!
* \brief Maximum gas saturation
*/
const TableColumn& getSgmaxColumn() const;
/*!
* \brief Critical oil-in-water saturation
*/
const TableColumn& getSowcritColumn() const;
/*!
* \brief Critical oil-in-gas saturation
*/
const TableColumn& getSogcritColumn() const;
};
}
#endif

View File

@@ -0,0 +1,55 @@
/*
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_JFUNC_HPP_
#define OPM_JFUNC_HPP_
#include <opm/parser/eclipse/Deck/Deck.hpp>
namespace Opm {
class JFunc
{
public:
enum class Flag { BOTH, WATER, GAS };
enum class Direction { XY, X, Y, Z };
explicit JFunc(const Deck& deck);
double alphaFactor() const;
double betaFactor() const;
double goSurfaceTension() const;
double owSurfaceTension() const;
const Flag& flag() const;
const Direction& direction() const;
operator bool() const { return m_exists; }
private:
Flag m_flag; // JFUNC flag: WATER, GAS, or BOTH. Default BOTH
double m_owSurfaceTension; // oil-wat surface tension. Required if flag is BOTH or WATER
double m_goSurfaceTension; // gas-oil surface tension. Required if flag is BOTH or GAS
double m_alphaFactor; // alternative porosity term. Default 0.5
double m_betaFactor; // alternative permeability term. Default 0.5
Direction m_direction; // XY, X, Y, Z. Default XY
const bool m_exists; // will be true if JFunc is specified in the deck
};
} // Opm::
#endif /* OPM_JFUNC_HPP_ */

View File

@@ -0,0 +1,39 @@
/*
Copyright (C) 2015 Statoil ASA.
2015 IRIS AS
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_MISC_TABLE_HPP
#define OPM_PARSER_MISC_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class MiscTable : public SimpleTable {
public:
explicit MiscTable( const DeckItem& item );
const TableColumn& getSolventFractionColumn() const;
const TableColumn& getMiscibilityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,40 @@
/*
Copyright (C) 2015 Statoil ASA.
2015 IRIS AS
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_MSFN_TABLE_HPP
#define OPM_PARSER_MSFN_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class MsfnTable : public SimpleTable {
public:
explicit MsfnTable( const DeckItem& item );
const TableColumn& getGasPhaseFractionColumn() const;
const TableColumn& getGasSolventRelpermMultiplierColumn() const;
const TableColumn& getOilRelpermMultiplierColumn() const;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2015 by Andreas Lauser
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_OILVISCT_TABLE_HPP
#define OPM_PARSER_OILVISCT_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class OilvisctTable : public SimpleTable {
public:
OilvisctTable( const DeckItem& item );
const TableColumn& getTemperatureColumn() const;
const TableColumn& getOilViscosityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2018 by IRIS
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_PBVD_TABLE_HPP
#define OPM_PARSER_PBVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PbvdTable : public SimpleTable {
public:
PbvdTable( const DeckItem& item );
const TableColumn& getDepthColumn() const;
const TableColumn& getPbubColumn() const;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2018 by IRIS
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_PDVD_TABLE_HPP
#define OPM_PARSER_PDVD_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PdvdTable : public SimpleTable {
public:
PdvdTable( const DeckItem& item );
const TableColumn& getDepthColumn() const;
const TableColumn& getPdewColumn() const;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PLYADS_TABLE_HPP
#define OPM_PARSER_PLYADS_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PlyadsTable : public SimpleTable {
public:
PlyadsTable( const DeckItem& item );
const TableColumn& getPolymerConcentrationColumn() const;
const TableColumn& getAdsorbedPolymerColumn() const;
};
}
#endif

View File

@@ -0,0 +1,38 @@
/*
Copyright (C) 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_PARSER_PLYDHFLF_TABLE_HPP
#define OPM_PARSER_PLYDHFLF_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PlydhflfTable : public SimpleTable {
public:
PlydhflfTable( const DeckItem& item );
const TableColumn& getTemperatureColumn() const;
const TableColumn& getPolymerHalflifeColumn() const;
};
}
#endif

View File

@@ -0,0 +1,38 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PLYMAX_TABLE_HPP
#define OPM_PARSER_PLYMAX_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckRecord;
class PlymaxTable : public SimpleTable {
public:
PlymaxTable( const DeckRecord& record );
const TableColumn& getPolymerConcentrationColumn() const;
const TableColumn& getMaxPolymerConcentrationColumn() const;
};
}
#endif

View File

@@ -0,0 +1,54 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PLYROCK_TABLE_HPP
#define OPM_PARSER_PLYROCK_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PlyrockTable : public SimpleTable {
public:
// This is not really a table; every column has only one element.
PlyrockTable( const DeckRecord& record );
// since this keyword is not necessarily monotonic, it cannot be evaluated!
//using SimpleTable::evaluate;
const TableColumn& getDeadPoreVolumeColumn() const;
const TableColumn& getResidualResistanceFactorColumn() const;
const TableColumn& getRockDensityFactorColumn() const;
// is column is actually an integer, but this is not yet
// supported by opm-parser (yet?) as it would require quite a
// few changes in the table support classes (read: it would
// probably require a lot of template vodoo) and some in the
// JSON-to-C conversion code. In the meantime, the index is
// just a double which can be converted to an integer in the
// calling code. (Make sure, that you don't interpolate
// indices, though!)
const TableColumn& getAdsorbtionIndexColumn() const;
const TableColumn& getMaxAdsorbtionColumn() const;
};
}
#endif

View File

@@ -0,0 +1,60 @@
/*
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_PARSER_PLYSHLOG_TABLE_HPP
#define OPM_PARSER_PLYSHLOG_TABLE_HPP
#include <opm/parser/eclipse/Parser/ParserKeywords/P.hpp>
#include "SimpleTable.hpp"
namespace Opm {
class DeckRecord;
class TableManager;
class PlyshlogTable : public SimpleTable {
public:
friend class TableManager;
PlyshlogTable(const DeckRecord& indexRecord, const DeckRecord& dataRecord);
double getRefPolymerConcentration() const;
double getRefSalinity() const;
double getRefTemperature() const;
void setRefPolymerConcentration(const double refPlymerConcentration);
void setRefSalinity(const double refSalinity);
void setRefTemperature(const double refTemperature);
bool hasRefSalinity() const;
bool hasRefTemperature() const;
void setHasRefSalinity(const bool has);
void setHasRefTemperature(const bool has);
const TableColumn& getWaterVelocityColumn() const;
const TableColumn& getShearMultiplierColumn() const;
private:
double m_refPolymerConcentration;
double m_refSalinity;
double m_refTemperature;
bool m_hasRefSalinity;
bool m_hasRefTemperature;
};
}
#endif

View File

@@ -0,0 +1,37 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PLYVISC_TABLE_HPP
#define OPM_PARSER_PLYVISC_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PlyviscTable : public SimpleTable {
public:
PlyviscTable( const DeckItem& item );
const TableColumn& getPolymerConcentrationColumn() const;
const TableColumn& getViscosityMultiplierColumn() const;
};
}
#endif

View File

@@ -0,0 +1,40 @@
/*
Copyright (C) 2015 Statoil ASA.
2015 IRIS AS
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_PMISC_TABLE_HPP
#define OPM_PARSER_PMISC_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PmiscTable : public SimpleTable {
public:
explicit PmiscTable( const DeckItem& item );
const TableColumn& getOilPhasePressureColumn() const;
const TableColumn& getMiscibilityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,38 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PVDG_TABLE_HPP
#define OPM_PARSER_PVDG_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PvdgTable : public SimpleTable {
public:
PvdgTable( const DeckItem& item );
const TableColumn& getPressureColumn() const;
const TableColumn& getFormationFactorColumn() const;
const TableColumn& getViscosityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,39 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PVDO_TABLE_HPP
#define OPM_PARSER_PVDO_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PvdoTable : public SimpleTable {
public:
PvdoTable( const DeckItem& item );
const TableColumn& getPressureColumn() const;
const TableColumn& getFormationFactorColumn() const;
const TableColumn& getViscosityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,39 @@
/*
Copyright 2015 IRIS AS
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_PVDS_TABLE_HPP
#define OPM_PARSER_PVDS_TABLE_HPP
#include "SimpleTable.hpp"
namespace Opm {
class DeckItem;
class PvdsTable : public SimpleTable {
public:
PvdsTable( const DeckItem& item );
const TableColumn& getPressureColumn() const;
const TableColumn& getFormationFactorColumn() const;
const TableColumn& getViscosityColumn() const;
};
}
#endif

View File

@@ -0,0 +1,34 @@
/*
Copyright (C) 2013 by Andreas Lauser
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_PVTG_TABLE_HPP
#define OPM_PARSER_PVTG_TABLE_HPP
#include <opm/parser/eclipse/EclipseState/Tables/PvtxTable.hpp>
namespace Opm {
class DeckKeyword;
class PvtgTable : public PvtxTable {
public:
PvtgTable( const DeckKeyword& keyword, size_t tableIdx);
};
}
#endif

View File

@@ -0,0 +1,34 @@
/*
Copyright (C) 2014 by Andreas Lauser
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_PVTO_TABLE_HPP
#define OPM_PARSER_PVTO_TABLE_HPP
#include <opm/parser/eclipse/EclipseState/Tables/PvtxTable.hpp>
namespace Opm {
class DeckKeyword;
class PvtoTable : public PvtxTable {
public:
PvtoTable(const DeckKeyword& keyword, size_t tableIdx);
};
}
#endif

View File

@@ -0,0 +1,141 @@
/*
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_PARSER_PVTX_TABLE_HPP
#define OPM_PARSER_PVTX_TABLE_HPP
#include <vector>
#include <opm/parser/eclipse/EclipseState/Tables/ColumnSchema.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableColumn.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableSchema.hpp>
/*
This class is a common base class for the PVTG and PVTO tables. The
PVTO and PVTG keywords have a quite complex structure. The structure
consists of alternating records of saturated data and corresponding
undersaturated tables, this structure is again repeated for the
different satnum regions.
PVTO
-- RSO PRESSURE B-OIL VISCOSITY
-- (BAR) (CP)
[ 20.59 { 50.00 1.10615 1.180 } ] \
{ 75.00 1.10164 1.247 } |
{ 100.00 1.09744 1.315 } |
{ 125.00 1.09351 1.384 } |
{ 150.00 1.08984 1.453 }/ |
|
[ 28.19 { 70.00 1.12522 1.066 } ] |
{ 95.00 1.12047 1.124 } |
{ 120.00 1.11604 1.182 } |-- Satnum region 1
{ 145.00 1.11191 1.241 } |
{ 170.00 1.10804 1.300 }/ |
|
[ 36.01 { 90.00 1.14458 0.964 } ] |
{ 115.00 1.13959 1.014 } |
{ 140.00 1.13494 1.064 } |
{ 165.00 1.13060 1.115 } |
{ 190.00 1.12653 1.166 }/ |
/ /
404.60 594.29 1.97527 0.21564 \
619.29 1.96301 0.21981 |
644.29 1.95143 0.22393 |-- Satnum region 2
669.29 1.94046 0.22801 |
694.29 1.93005 0.23204 / |
/ /
404.60 594.29 1.97527 0.21564 \
619.29 1.96301 0.21981 |
644.29 1.95143 0.22393 |
669.29 1.94046 0.22801 |
694.29 1.93005 0.23204 / |-- Satnum region 3
404.60 594.29 1.97527 0.21564 |
619.29 1.96301 0.21981 |
644.29 1.95143 0.22393 |
669.29 1.94046 0.22801 |
694.29 1.93005 0.23204 / /
/
In satnum region1 the saturated records are marked with [ ... ], and
the corresponding undersaturated tables are marked with { ... }. So
for satnum region1 the table of saturated properties looks like:
RSO PRESSURE B-OIL VISCOSITY
20.59 50.00 1.10615 1.180
28.19 70.00 1.12522 1.066
36.01 90.00 1.14458 0.964
In the PvtxTable class this table is available as the method
getSaturatedTable( ). For each RS value there is a table of
undersaturated properties; since the saturated table for region1 has
three rows there are three such tables, these tables are available as
getUnderSaturatedTable( index ). In this particular example the first
undersaturated table looks like:
PRESSURE B-OIL VISCOSITY
50.00 1.10615 1.180
75.00 1.10164 1.247
100.00 1.09744 1.315
125.00 1.09351 1.384
150.00 1.08984 1.453
The first row actually corresponds to saturated values.
*/
namespace Opm {
class DeckKeyword;
class PvtxTable {
public:
static size_t numTables( const DeckKeyword& keyword);
static std::vector<std::pair<size_t , size_t> > recordRanges( const DeckKeyword& keyword);
explicit PvtxTable(const std::string& columnName);
const SimpleTable& getUnderSaturatedTable(size_t tableNumber) const;
void init(const DeckKeyword& keyword, size_t tableIdx);
size_t size() const;
double evaluate(const std::string& column, double outerArg, double innerArg) const;
double getArgValue(size_t index) const;
const SimpleTable& getSaturatedTable() const;
/*
Will iterate over the internal undersaturated tables; same
as getUnderSaturatedTable( ).
*/
std::vector< SimpleTable >::const_iterator begin() const;
std::vector< SimpleTable >::const_iterator end() const;
protected:
ColumnSchema m_outerColumnSchema;
TableColumn m_outerColumn;
TableSchema m_underSaturatedSchema;
TableSchema m_saturatedSchema;
std::vector< SimpleTable > m_underSaturatedTables;
SimpleTable m_saturatedTable;
};
}
#endif

View File

@@ -0,0 +1,87 @@
/*
Copyright (C) 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
MERCHANREGILITY 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 REGDIMS_HPP
#define REGDIMS_HPP
/*
The Regdims class is a small utility class designed to hold on to
the values from the REGDIMS keyword.
*/
#include <opm/parser/eclipse/Parser/ParserKeywords/R.hpp>
namespace Opm {
class Regdims {
public:
Regdims() :
m_NTFIP( ParserKeywords::REGDIMS::NTFIP::defaultValue ),
m_NMFIPR( ParserKeywords::REGDIMS::NMFIPR::defaultValue ),
m_NRFREG( ParserKeywords::REGDIMS::NRFREG::defaultValue ),
m_NTFREG( ParserKeywords::REGDIMS::NTFREG::defaultValue ),
m_NPLMIX( ParserKeywords::REGDIMS::NPLMIX::defaultValue )
{ }
Regdims(size_t ntfip , size_t nmfipr , size_t nrfregr , size_t ntfreg , size_t nplmix) :
m_NTFIP( ntfip ),
m_NMFIPR( nmfipr ),
m_NRFREG( nrfregr ),
m_NTFREG( ntfreg ),
m_NPLMIX( nplmix )
{}
size_t getNTFIP() const {
return m_NTFIP;
}
size_t getNMFIPR() const {
return m_NMFIPR;
}
size_t getNRFREG() const {
return m_NRFREG;
}
size_t getNTFREG() const {
return m_NTFREG;
}
size_t getNPLMIX() const {
return m_NPLMIX;
}
private:
size_t m_NTFIP;
size_t m_NMFIPR;
size_t m_NRFREG;
size_t m_NTFREG;
size_t m_NPLMIX;
};
}
#endif

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