Updated Ert to e2a5a9cc20705537d07822958d925e092a323367 to include new accesss to well rates

This commit is contained in:
Jacob Støren
2017-02-07 13:44:59 +01:00
parent 76bc449d1f
commit a6b7bc7c41
475 changed files with 12978 additions and 5850 deletions
+82 -42
View File
@@ -1,45 +1,85 @@
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
set( ERT_DOC_EXTERNAL_ROOT "" CACHE PATH "Path to site local ERT documentation")
option( ERT_RST_DOC "Build RST based documentation" ON)
option( ERT_DOXY_DOC "Build doxygen documentation" ON)
option( ERT_DOXY_GRAPHICAL "Add graphics to doxygen documentation" OFF)
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/tmp_doc")
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/user" "${PROJECT_BINARY_DIR}/tmp_doc/user")
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/tmp_doc/code")
if (ERT_DOC_EXTERNAL_ROOT)
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${ERT_DOC_EXTERNAL_ROOT}" "${PROJECT_BINARY_DIR}/tmp_doc/external-doc")
message(STATUS "Adding documentation link ${PROJECT_BINARY_DIR}/tmp_doc/external-doc -> ${ERT_DOC_EXTERNAL_ROOT}")
set( ERT_DOC_LINK external-doc/index )
else()
set( ERT_DOC_LINK "" )
endif()
configure_file(index.rst.in ${PROJECT_BINARY_DIR}/tmp_doc/index.rst)
configure_file(conf.py.in ${PROJECT_BINARY_DIR}/conf.py)
add_custom_target(doc_out ALL
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/script/run-sphinx.py ${PROJECT_BINARY_DIR}/conf.py ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} ${PROJECT_BINARY_DIR}/tmp_doc
DEPENDS enkf)
INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/tmp_doc/_build/ DESTINATION ${CMAKE_INSTALL_PREFIX}/documentation )
if (ERT_DOC_INSTALL_PATH)
INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/tmp_doc/_build/ DESTINATION ${ERT_DOC_INSTALL_PATH} )
endif()
find_package(Doxygen)
if (DOXYGEN_FOUND)
message(STATUS "Creating doxygen target")
if (DOXYGEN_DOT_FOUND)
message(STATUS "Found graphviz, will run doxygen with graphics")
set( DOXYGEN_HAVE_DOT "YES" )
else()
message(STATUS "Graphviz not found, disabling dot")
set( DOXYGEN_HAVE_DOT "NO" )
if (NOT BUILD_ERT)
if (ERT_RST_DOC)
message(WARNING "Turning off ERT_RST_DOC. Depends on BUILD_ERT.")
set (ERT_RST_DOC OFF)
endif()
if (ERT_DOXY_DOC)
message(WARNING "Turning off ERT_DOXY_DOC. Depends on BUILD_ERT.")
set (ERT_DOXY_DOC OFF)
endif()
configure_file(doxygen.cfg.in ${PROJECT_BINARY_DIR}/doxygen.cfg)
add_custom_target(doxy
COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doxygen.cfg
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/../
COMMENT "Generating doxygen documentation")
endif()
if (ERT_RST_DOC)
find_package(Sphinx REQUIRED)
if (SPHINX_FOUND)
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
set( ERT_DOC_EXTERNAL_ROOT "" CACHE PATH "Path to site local ERT documentation")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/doc-src")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/doc-src/_static")
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/user" "${PROJECT_BINARY_DIR}/doc-src/user")
if (ERT_DOC_EXTERNAL_ROOT)
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${ERT_DOC_EXTERNAL_ROOT}" "${PROJECT_BINARY_DIR}/doc-src/external-doc")
message(STATUS "Adding documentation link ${PROJECT_BINARY_DIR}/doc-src/external-doc -> ${ERT_DOC_EXTERNAL_ROOT}")
set( ERT_DOC_LINK external-doc/index )
else()
set( ERT_DOC_LINK "" )
endif()
configure_file(index.rst.in ${PROJECT_BINARY_DIR}/doc-src/index.rst)
configure_file(conf.py.in ${PROJECT_BINARY_DIR}/doc-src/conf.py)
if (BUILD_PYTHON)
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/doc-src/code")
add_custom_target(api-doc ALL
COMMAND sphinx-apidoc -e -o doc-src/API/python ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}
DEPENDS enkf
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
add_custom_target(rst-doc ALL
COMMAND sphinx-build -b html -d doc-src/doctrees doc-src documentation/rst
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS api-doc
)
else()
message(STATUS "Sphinx documentation tool not found - documentation not generated")
endif()
endif()
if (ERT_DOXY_DOC)
find_package(Doxygen)
if (DOXYGEN_FOUND)
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/documentation/doxy")
set( DOXYGEN_HAVE_DOT "NO" )
if ( ERT_DOXY_GRAPHICAL)
if (DOXYGEN_DOT_FOUND)
set( DOXYGEN_HAVE_DOT "YES" )
endif()
endif()
if (BUILD_ERT)
SET( DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/libanalysis ${PROJECT_SOURCE_DIR}/libconfig ${PROJECT_SOURCE_DIR}/libecl ${PROJECT_SOURCE_DIR}/libecl_well ${PROJECT_SOURCE_DIR}/libeclxx ${PROJECT_SOURCE_DIR}/libenkf ${PROJECT_SOURCE_DIR}/libert_util ${PROJECT_SOURCE_DIR}/libert_utilxx ${PROJECT_SOURCE_DIR}/libgeometry ${PROJECT_SOURCE_DIR}/libjob_queue ${PROJECT_SOURCE_DIR}/librms ${PROJECT_SOURCE_DIR}/libsched")
else()
SET( DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/libecl ${PROJECT_SOURCE_DIR}/libecl_well ${PROJECT_SOURCE_DIR}/libeclxx ${PROJECT_SOURCE_DIR}/libert_util ${PROJECT_SOURCE_DIR}/libert_utilxx ${PROJECT_SOURCE_DIR}/libgeometry")
endif()
configure_file(doxygen.cfg.in ${PROJECT_BINARY_DIR}/doxygen.cfg)
add_custom_target(doxy ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doxygen.cfg
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/../
COMMENT "Generating doxygen documentation"
DEPENDS enkf)
endif()
endif()
INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/documentation DESTINATION ${CMAKE_INSTALL_PREFIX} )
+34
View File
@@ -0,0 +1,34 @@
QUEUE_SYSTEM LOCAL
JOBNAME SNAKE_OIL_%d
NUM_REALIZATIONS 25
DEFINE <STORAGE> storage/<CONFIG_FILE_BASE>
RUNPATH_FILE directory/test_runpath_list.txt
RUNPATH <STORAGE>/runpath/realisation-%d/iter-%d
ENSPATH <STORAGE>/ensemble
ECLBASE SNAKE_OIL_FIELD
SUMMARY *
HISTORY_SOURCE REFCASE_HISTORY
REFCASE refcase/SNAKE_OIL_FIELD
TIME_MAP refcase/time_map.txt
INSTALL_JOB SNAKE_OIL_SIMULATOR jobs/SNAKE_OIL_SIMULATOR
INSTALL_JOB SNAKE_OIL_NPV jobs/SNAKE_OIL_NPV
INSTALL_JOB SNAKE_OIL_DIFF jobs/SNAKE_OIL_DIFF
FORWARD_MODEL SNAKE_OIL_SIMULATOR
FORWARD_MODEL SNAKE_OIL_NPV
FORWARD_MODEL SNAKE_OIL_DIFF
RUN_TEMPLATE templates/seed_template.txt seed.txt
GEN_KW SNAKE_OIL_PARAM templates/snake_oil_template.txt snake_oil_params.txt parameters/snake_oil_parameters.txt
CUSTOM_KW SNAKE_OIL_NPV snake_oil_npv.txt
GEN_DATA SNAKE_OIL_OPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_opr_diff_%d.txt REPORT_STEPS:199
GEN_DATA SNAKE_OIL_WPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_wpr_diff_%d.txt REPORT_STEPS:199
GEN_DATA SNAKE_OIL_GPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_gpr_diff_%d.txt REPORT_STEPS:199
+4
View File
@@ -0,0 +1,4 @@
STDOUT snake_oil_diff.stdout
STDERR snake_oil_diff.stderr
EXECUTABLE snake_oil_diff.py
+4
View File
@@ -0,0 +1,4 @@
STDOUT snake_oil_npv.stdout
STDERR snake_oil_npv.stderr
EXECUTABLE snake_oil_npv.py
@@ -0,0 +1,4 @@
STDOUT snake_oil.stdout
STDERR snake_oil.stderr
EXECUTABLE snake_oil_simulator.py
@@ -0,0 +1,24 @@
#!/usr/bin/env python
from ert.ecl import EclSum
def writeDiff(filename, vector1, vector2):
with open(filename, "w") as f:
for index in range(len(vector1)):
node1 = vector1[index]
node2 = vector2[index]
diff = node1.value - node2.value
f.write("%f\n" % diff)
if __name__ == '__main__':
ecl_sum = EclSum("SNAKE_OIL_FIELD")
report_step = 199
writeDiff("snake_oil_opr_diff_%d.txt" % report_step, ecl_sum["WOPR:OP1"], ecl_sum["WOPR:OP2"])
writeDiff("snake_oil_wpr_diff_%d.txt" % report_step, ecl_sum["WWPR:OP1"], ecl_sum["WWPR:OP2"])
writeDiff("snake_oil_gpr_diff_%d.txt" % report_step, ecl_sum["WGPR:OP1"], ecl_sum["WGPR:OP2"])
+103
View File
@@ -0,0 +1,103 @@
#!/usr/bin/env python
from ert.ecl import EclSum
OIL_PRICES = {"2010-01-01": 78.33,
"2010-02-01": 76.39,
"2010-03-01": 81.20,
"2010-04-01": 84.29,
"2010-05-01": 73.74,
"2010-06-01": 75.34,
"2010-07-01": 76.32,
"2010-08-01": 76.60,
"2010-09-01": 75.24,
"2010-10-01": 81.89,
"2010-11-01": 84.25,
"2010-12-01": 89.15,
"2011-01-01": 89.17,
"2011-02-01": 88.58,
"2011-03-01": 102.86,
"2011-04-01": 109.53,
"2011-05-01": 100.90,
"2011-06-01": 96.26,
"2011-07-01": 97.30,
"2011-08-01": 86.33,
"2011-09-01": 85.52,
"2011-10-01": 86.32,
"2011-11-01": 97.16,
"2011-12-01": 98.56,
"2012-01-01": 100.27,
"2012-02-01": 102.20,
"2012-03-01": 106.16,
"2012-04-01": 103.32,
"2012-05-01": 94.65,
"2012-06-01": 82.30,
"2012-07-01": 87.90,
"2012-08-01": 94.13,
"2012-09-01": 94.51,
"2012-10-01": 89.49,
"2012-11-01": 86.53,
"2012-12-01": 87.86,
"2013-01-01": 94.76,
"2013-02-01": 95.31,
"2013-03-01": 92.94,
"2013-04-01": 92.02,
"2013-05-01": 94.51,
"2013-06-01": 95.77,
"2013-07-01": 104.67,
"2013-08-01": 106.57,
"2013-09-01": 106.29,
"2013-10-01": 100.54,
"2013-11-01": 93.86,
"2013-12-01": 97.63,
"2014-01-01": 94.62,
"2014-02-01": 100.82,
"2014-03-01": 100.80,
"2014-04-01": 102.07,
"2014-05-01": 102.18,
"2014-06-01": 105.79,
"2014-07-01": 103.59,
"2014-08-01": 96.54,
"2014-09-01": 93.21,
"2014-10-01": 84.40,
"2014-11-01": 75.79,
"2014-12-01": 59.29,
"2015-01-01": 47.22,
"2015-02-01": 50.58,
"2015-03-01": 47.82,
"2015-04-01": 54.45,
"2015-05-01": 59.27,
"2015-06-01": 59.82,
"2015-07-01": 50.90,
"2015-08-01": 42.87,
"2015-09-01": 45.48}
if __name__ == '__main__':
ecl_sum = EclSum("SNAKE_OIL_FIELD")
start_time = ecl_sum.getStartTime()
date_ranges = ecl_sum.timeRange(start_time, interval="1M")
production_sums = ecl_sum.blockedProduction("FOPT", date_ranges)
npv = 0.0
for index in range(0, len(date_ranges) - 1):
date = date_ranges[index + 1] # end of period
production_sum = production_sums[index]
oil_price = OIL_PRICES[date.date().strftime("%Y-%m-%d")]
production_value = oil_price * production_sum
npv += production_value
with open("snake_oil_npv.txt", "w") as output_file:
output_file.write("NPV %s\n" % npv)
if npv < 80000:
rating = "POOR"
elif 80000 <= npv < 100000:
rating = "AVERAGE"
elif 100000 <= npv < 120000:
rating = "GOOD"
else:
rating = "EXCELLENT"
output_file.write("RATING %s\n" % rating)
@@ -0,0 +1,185 @@
#!/usr/bin/env python
from datetime import datetime
import os
import sys
from ert.ecl import EclSum, EclSumTStep
from ert.test import ExtendedTestCase
try:
from synthesizer import OilSimulator
except ImportError as e:
share_lib_path = os.path.join(ExtendedTestCase.findShareRoot(), "lib")
sys.path.insert(0, share_lib_path)
synthesizer_module = __import__("synthesizer")
OilSimulator = synthesizer_module.OilSimulator
sys.path.pop(0)
def globalIndex(i, j, k, nx=10, ny=10, nz=10):
return i + nx * (j - 1) + nx * ny * (k - 1)
def readParameters(filename):
params = {}
with open(filename, "r") as f:
for line in f:
key, value = line.split(":", 1)
params[key] = value.strip()
return params
def runSimulator(simulator, history_simulator, time_step_count):
""" @rtype: EclSum """
ecl_sum = EclSum.writer("SNAKE_OIL_FIELD", datetime(2010, 1, 1), 10, 10, 10)
ecl_sum.addVariable("FOPT")
ecl_sum.addVariable("FOPR")
ecl_sum.addVariable("FGPT")
ecl_sum.addVariable("FGPR")
ecl_sum.addVariable("FWPT")
ecl_sum.addVariable("FWPR")
ecl_sum.addVariable("FGOR")
ecl_sum.addVariable("FWCT")
ecl_sum.addVariable("FOPTH")
ecl_sum.addVariable("FOPRH")
ecl_sum.addVariable("FGPTH")
ecl_sum.addVariable("FGPRH")
ecl_sum.addVariable("FWPTH")
ecl_sum.addVariable("FWPRH")
ecl_sum.addVariable("FGORH")
ecl_sum.addVariable("FWCTH")
ecl_sum.addVariable("WOPR", wgname="OP1")
ecl_sum.addVariable("WOPR", wgname="OP2")
ecl_sum.addVariable("WWPR", wgname="OP1")
ecl_sum.addVariable("WWPR", wgname="OP2")
ecl_sum.addVariable("WGPR", wgname="OP1")
ecl_sum.addVariable("WGPR", wgname="OP2")
ecl_sum.addVariable("WGOR", wgname="OP1")
ecl_sum.addVariable("WGOR", wgname="OP2")
ecl_sum.addVariable("WWCT", wgname="OP1")
ecl_sum.addVariable("WWCT", wgname="OP2")
ecl_sum.addVariable("WOPRH", wgname="OP1")
ecl_sum.addVariable("WOPRH", wgname="OP2")
ecl_sum.addVariable("WWPRH", wgname="OP1")
ecl_sum.addVariable("WWPRH", wgname="OP2")
ecl_sum.addVariable("WGPRH", wgname="OP1")
ecl_sum.addVariable("WGPRH", wgname="OP2")
ecl_sum.addVariable("WGORH", wgname="OP1")
ecl_sum.addVariable("WGORH", wgname="OP2")
ecl_sum.addVariable("WWCTH", wgname="OP1")
ecl_sum.addVariable("WWCTH", wgname="OP2")
ecl_sum.addVariable("BPR", num=globalIndex(5, 5, 5))
ecl_sum.addVariable("BPR", num=globalIndex(1, 3, 8))
time_map = []
mini_step_count = 10
total_step_count = time_step_count * mini_step_count
for report_step in range(time_step_count):
for mini_step in range(mini_step_count):
t_step = ecl_sum.addTStep(report_step + 1, sim_days=report_step * mini_step_count + mini_step)
time_map.append(t_step.getSimTime().datetime().strftime("%d/%m/%Y"))
simulator.step(scale=1.0 / total_step_count)
history_simulator.step(scale=1.0 / total_step_count)
t_step["FOPR"] = simulator.fopr()
t_step["FOPT"] = simulator.fopt()
t_step["FGPR"] = simulator.fgpr()
t_step["FGPT"] = simulator.fgpt()
t_step["FWPR"] = simulator.fwpr()
t_step["FWPT"] = simulator.fwpt()
t_step["FGOR"] = simulator.fgor()
t_step["FWCT"] = simulator.fwct()
t_step["WOPR:OP1"] = simulator.opr("OP1")
t_step["WOPR:OP2"] = simulator.opr("OP2")
t_step["WGPR:OP1"] = simulator.gpr("OP1")
t_step["WGPR:OP2"] = simulator.gpr("OP2")
t_step["WWPR:OP1"] = simulator.wpr("OP1")
t_step["WWPR:OP2"] = simulator.wpr("OP2")
t_step["WGOR:OP1"] = simulator.gor("OP1")
t_step["WGOR:OP2"] = simulator.gor("OP2")
t_step["WWCT:OP1"] = simulator.wct("OP1")
t_step["WWCT:OP2"] = simulator.wct("OP2")
t_step["BPR:5,5,5"] = simulator.bpr("5,5,5")
t_step["BPR:1,3,8"] = simulator.bpr("1,3,8")
t_step["FOPRH"] = history_simulator.fopr()
t_step["FOPTH"] = history_simulator.fopt()
t_step["FGPRH"] = history_simulator.fgpr()
t_step["FGPTH"] = history_simulator.fgpt()
t_step["FWPRH"] = history_simulator.fwpr()
t_step["FWPTH"] = history_simulator.fwpt()
t_step["FGORH"] = history_simulator.fgor()
t_step["FWCTH"] = history_simulator.fwct()
t_step["WOPRH:OP1"] = history_simulator.opr("OP1")
t_step["WOPRH:OP2"] = history_simulator.opr("OP2")
t_step["WGPRH:OP1"] = history_simulator.gpr("OP1")
t_step["WGPRH:OP2"] = history_simulator.gpr("OP2")
t_step["WWPRH:OP1"] = history_simulator.wpr("OP1")
t_step["WWPRH:OP2"] = history_simulator.wpr("OP2")
t_step["WGORH:OP1"] = history_simulator.gor("OP1")
t_step["WGORH:OP2"] = history_simulator.gor("OP2")
t_step["WWCTH:OP1"] = history_simulator.wct("OP1")
t_step["WWCTH:OP2"] = history_simulator.wct("OP2")
return ecl_sum, time_map
def roundedInt(value):
return int(round(float(value)))
if __name__ == '__main__':
seed = int(readParameters("seed.txt")["SEED"])
parameters = readParameters("snake_oil_params.txt")
op1_divergence_scale = float(parameters["OP1_DIVERGENCE_SCALE"])
op2_divergence_scale = float(parameters["OP2_DIVERGENCE_SCALE"])
op1_persistence = float(parameters["OP1_PERSISTENCE"])
op2_persistence = float(parameters["OP2_PERSISTENCE"])
op1_offset = float(parameters["OP1_OFFSET"])
op2_offset = float(parameters["OP2_OFFSET"])
bpr_138_persistence = float(parameters["BPR_138_PERSISTENCE"])
bpr_555_persistence = float(parameters["BPR_555_PERSISTENCE"])
op1_octaves = roundedInt(parameters["OP1_OCTAVES"])
op2_octaves = roundedInt(parameters["OP2_OCTAVES"])
simulator = OilSimulator()
simulator.addWell("OP1", seed * 997, persistence=op1_persistence, octaves=op1_octaves, divergence_scale=op1_divergence_scale, offset=op1_offset)
simulator.addWell("OP2", seed * 13, persistence=op2_persistence, octaves=op2_octaves, divergence_scale=op2_divergence_scale, offset=op2_offset)
simulator.addBlock("5,5,5", seed * 37, persistence=bpr_555_persistence)
simulator.addBlock("1,3,8", seed * 31, persistence=bpr_138_persistence)
history_simulator = OilSimulator()
history_simulator.addWell("OP1", 222118781)
history_simulator.addWell("OP2", 118116362)
report_step_count = 200
ecl_sum, time_map = runSimulator(simulator, history_simulator, report_step_count)
ecl_sum.fwrite()
with open("time_map.txt", "w") as f:
for t in time_map:
f.write("%s\n" % t)
@@ -0,0 +1,11 @@
OP1_PERSISTENCE UNIFORM 0.01 0.4
OP1_OCTAVES UNIFORM 3 5
OP1_DIVERGENCE_SCALE UNIFORM 0.25 1.25
OP1_OFFSET UNIFORM -0.1 0.1
OP2_PERSISTENCE UNIFORM 0.1 0.6
OP2_OCTAVES UNIFORM 5 12
OP2_DIVERGENCE_SCALE UNIFORM 0.5 1.5
OP2_OFFSET UNIFORM -0.2 0.2
BPR_555_PERSISTENCE UNIFORM 0.1 0.5
BPR_138_PERSISTENCE UNIFORM 0.2 0.7
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
To create a refcase run the snake_oil_simulator.py job with the this as working directory.
+1
View File
@@ -0,0 +1 @@
SEED:268776
@@ -0,0 +1,10 @@
OP1_PERSISTENCE:0.15
OP1_OCTAVES:4
OP1_DIVERGENCE_SCALE:0.5
OP1_OFFSET:0.0
OP2_PERSISTENCE:0.25
OP2_OCTAVES:7.0
OP2_DIVERGENCE_SCALE:1.0
OP2_OFFSET:0.0
BPR_555_PERSISTENCE:0.25
BPR_138_PERSISTENCE:0.35
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
QUEUE_SYSTEM LOCAL
JOBNAME SNAKE_OIL_%d
NUM_REALIZATIONS 25
DEFINE <STORAGE> storage/<CONFIG_FILE_BASE>
STORE_SEED SEED
LOAD_SEED SEED
RUNPATH_FILE directory/test_runpath_list.txt
RUNPATH <STORAGE>/runpath/realisation-%d/iter-%d
ENSPATH <STORAGE>/ensemble
ECLBASE SNAKE_OIL_FIELD
SUMMARY *
HISTORY_SOURCE REFCASE_HISTORY
REFCASE refcase/SNAKE_OIL_FIELD
TIME_MAP refcase/time_map.txt
OBS_CONFIG observations/observations.txt
INSTALL_JOB SNAKE_OIL_SIMULATOR jobs/SNAKE_OIL_SIMULATOR
INSTALL_JOB SNAKE_OIL_NPV jobs/SNAKE_OIL_NPV
INSTALL_JOB SNAKE_OIL_DIFF jobs/SNAKE_OIL_DIFF
FORWARD_MODEL SNAKE_OIL_SIMULATOR
FORWARD_MODEL SNAKE_OIL_NPV
FORWARD_MODEL SNAKE_OIL_DIFF
RUN_TEMPLATE templates/seed_template.txt seed.txt
GEN_KW SNAKE_OIL_PARAM templates/snake_oil_template.txt snake_oil_params.txt parameters/snake_oil_parameters.txt
CUSTOM_KW SNAKE_OIL_NPV snake_oil_npv.txt
GEN_DATA SNAKE_OIL_OPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_opr_diff_%d.txt REPORT_STEPS:199
GEN_DATA SNAKE_OIL_WPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_wpr_diff_%d.txt REPORT_STEPS:199
GEN_DATA SNAKE_OIL_GPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_gpr_diff_%d.txt REPORT_STEPS:199
LOG_LEVEL 3
LOG_FILE log/log.txt
UPDATE_LOG_PATH log/update
@@ -0,0 +1 @@
SEED:<IENS>
@@ -0,0 +1,10 @@
OP1_PERSISTENCE:<OP1_PERSISTENCE>
OP1_OCTAVES:<OP1_OCTAVES>
OP1_DIVERGENCE_SCALE:<OP1_DIVERGENCE_SCALE>
OP1_OFFSET:<OP1_OFFSET>
OP2_PERSISTENCE:<OP2_PERSISTENCE>
OP2_OCTAVES:<OP2_OCTAVES>
OP2_DIVERGENCE_SCALE:<OP2_DIVERGENCE_SCALE>
OP2_OFFSET:<OP2_OFFSET>
BPR_555_PERSISTENCE:<BPR_555_PERSISTENCE>
BPR_138_PERSISTENCE:<BPR_138_PERSISTENCE>
+7
View File
@@ -0,0 +1,7 @@
1. Create a small Python script which will load a ERT configuration
file and instantiate a EnkfMain object.
2. Query the EnKFMain instance and print on standard out:
a) How many realisations there are.
b) List all GEN_KW keywords, and their internal keys.
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python
import sys
import time
from ert.enkf import EnKFMain
from ert.enkf.enums import ErtImplType
# This will instantiate the EnkFMain object and create a handle to
# "everything" ert related for this instance.
ert = EnKFMain( sys.argv[1] )
# Ask the EnKFMain instance how many realisations it has. Observe that
# the answer to this question is just the value of the
# NUM_REALISATIONS setting in the configuration file.
print("This instance has %d realisations" % ert.getEnsembleSize())
# Get the ensemble configuration object, and ask for all GEN_KW keys:
ens_config = ert.ensembleConfig( )
for key in ens_config.getKeylistFromImplType(ErtImplType.GEN_KW):
config_node = ens_config[key]
# "Downcast" to GEN_KW configuration.
gen_kw_config = config_node.getModelConfig( )
print("%s : %s" % (key , gen_kw_config.getKeyWords( )))
+1
View File
@@ -0,0 +1 @@
Implement the [] operator for the gen_data class in GenData.py
+35
View File
@@ -0,0 +1,35 @@
The [] operator for python objects is implemeted with the
__getitem__() and __setitem__() methods.
1. The __setitem__ and __getitem__ methods should clearly be based on
C functions which set and get an item based on an index. Going to
libenkf/src/gen_data.c we see that two such functions already exist:
double gen_data_iget_double(const gen_data_type * gen_data, int index);
void gen_data_iset_double(gen_data_type * gen_data, int index, double value);
2. We must add bindings from Python to these C functions. Add the
following lines to at the top of the declaration of class GenData:
_iset = EnkfPrototype("void gen_data_iset_double(gen_data, int , double)")
_iget = EnkfPrototype("double gen_data_iget_double(gen_data, int )")
3. Create (simple) Python methods:
def __getitem__(self , index):
if index < len(self):
return self._iget( index )
else:
raise IndexError("Invalid index:%d - valid range: [0,%d)" % (index , len(self)))
def __setitem__(self , index, value):
if index < len(self):
self._iset( index , value )
else:
raise IndexError("Invalid index:%d - valid range: [0,%d)" % (index , len(self)))
+2
View File
@@ -0,0 +1,2 @@
Iterate through all the forward models which have been installed and
get the configuration file and executable.
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env python
import sys
import time
from ert.enkf import EnKFMain
# This will instantiate the EnkFMain object and create a handle to
# "everything" ert related for this instance.
ert = EnKFMain( sys.argv[1] )
site_config = ert.siteConfig( )
jobs = site_config.get_installed_jobs( )
for job in jobs:
print job.name()
print " config : %s" % job.get_config_file()
print " executable: %s" % job.get_executable( )
print
+13
View File
@@ -0,0 +1,13 @@
Create a small script which:
1. Loads the configuration file.
2. Initializes the realisations and creates runpath folders.
3. Submit simulations.
4. Wait for simulations to complete.
5. Fetch and print GEN_DATA results - use the GenData[] operator.
+71
View File
@@ -0,0 +1,71 @@
#!/usr/bin/env python
import sys
import time
from ert.enkf import EnKFMain, RunArg, NodeId
from ert.enkf.data import EnkfNode
from ert.job_queue import JobQueueManager
ert = EnKFMain( sys.argv[1] )
fs_manager = ert.getEnkfFsManager( )
fs = fs_manager.getCurrentFileSystem( )
# Initialize the realisations.
for iens in range( ert.getEnsembleSize()):
realisation = ert.getRealisation( iens )
realisation.initialize( fs )
# Fetch out the job_queue from the SiteConfig object. In addition we
# create a JobQueueManager objects which wraps the queue. The purpose
# of this manager object is to let the queue run nonblocking in the
# background.
site_config = ert.siteConfig( )
queue_manager = JobQueueManager( site_config.getJobQueue( ) )
queue_manager.startQueue( ert.getEnsembleSize( ) , verbose = False )
# Create list of RunArg instances which hold metadata for one running
# realisation, create the directory where the simulation should run
# and submit the simulation.
path_fmt = "/tmp/run%d"
arg_list = [ RunArg.createEnsembleExperimentRunArg(fs, iens, path_fmt % iens) for iens in range(ert.getEnsembleSize()) ]
for arg in arg_list:
ert.createRunPath( arg )
ert.submitSimulation( arg )
while True:
print("Waiting:%d Running:%d Complete:%d/%d" % (queue_manager.getNumWaiting( ), queue_manager.getNumRunning( ) , queue_manager.getNumSuccess() , queue_manager.getNumFailed( )))
if not queue_manager.isRunning( ):
break
time.sleep( 5 )
ens_config = ert.ensembleConfig( )
data_config = ens_config["SNAKE_OIL_OPR_DIFF"]
param_config = ens_config["SNAKE_OIL_PARAM"]
for iens in range(ert.getEnsembleSize( )):
data_id = NodeId( realization_number = iens,
report_step = 199 )
enkf_node1 = EnkfNode( data_config )
enkf_node1.load( fs , data_id )
gen_data = enkf_node1.asGenData( )
data = gen_data.getData( )
param_id = NodeId( realization_number = iens,
report_step = 0 )
enkf_node2 = EnkfNode( param_config )
enkf_node2.load( fs , param_id )
gen_kw = enkf_node2.asGenKw( )
print sum(data)
for v in gen_kw:
print v
# Using the __getitem__() of GenData which was implemented
# previously.
for d in gen_data:
print d
+2 -2
View File
@@ -5,7 +5,7 @@ PROJECT_NAME = "Ert"
PROJECT_NUMBER = ${ERT_VERSION_MAJOR}.${ERT_VERSION_MINOR}
PROJECT_BRIEF = "ERT is a software initially developed by Statoil which main feature is to handle several ECLIPSE simulations in an Ensemble setting. --- http://ert.nr.no/ert"
PROJECT_LOGO =
OUTPUT_DIRECTORY = ${PROJECT_BINARY_DIR}/doxy
OUTPUT_DIRECTORY = ${PROJECT_BINARY_DIR}/documentation/doxy
CREATE_SUBDIRS = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
@@ -25,7 +25,7 @@ WARN_IF_DOC_ERROR = NO
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
INPUT = ${PROJECT_SOURCE_DIR}/libanalysis ${PROJECT_SOURCE_DIR}/libconfig ${PROJECT_SOURCE_DIR}/libecl ${PROJECT_SOURCE_DIR}/libecl_well ${PROJECT_SOURCE_DIR}/libeclxx ${PROJECT_SOURCE_DIR}/libenkf ${PROJECT_SOURCE_DIR}/libert_util ${PROJECT_SOURCE_DIR}/libert_utilxx ${PROJECT_SOURCE_DIR}/libgeometry ${PROJECT_SOURCE_DIR}/libjob_queue ${PROJECT_SOURCE_DIR}/librms ${PROJECT_SOURCE_DIR}/libsched
INPUT = ${DOXYGEN_INPUT}
RECURSIVE = YES
EXCLUDE_PATTERNS = */test/* */build/* */test-data/* */docs/* */python*/
+188
View File
@@ -0,0 +1,188 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH ecl_summary "1" "November 8 2016"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
ecl_summary \- Program to extract summary vectors from ECLIPSE files
.SH DESCRIPTION
The ecl_summary program is used to quickly extract summary vectors
from ECLIPSE summary files. The program is invoked as:
.PP
computer> ecl_summary \fI\,/Path/to/ECLIPSE\/\fP key1 key2 key3 ....
.PP
Here ECLIPSE is the name of an existing case, you can give it with
extension, or without; the case need not be in the current directory.
.PP
The keys are formed by combining ECLIPSE variable names and
qualifiers from the WGNAMES and NUMS arrays. Examples of keys are:
.TP
WWCT:F\-36
\- The watercut in the well F\-36.
.TP
FOPT
\- The total field oil production.
.TP
RPR:3
\- The region pressure in region 3.
.TP
GGIT:NORTH
\- The total gas injection group NORTH.
.TP
SPR:F\-12:18
\- The segment pressure in well F\-12, segment 18.
.TP
BPR:10,10,10
\- The block pressure in cell 10,10,10.
.IP
LBPR:LGR3:10,10,10 \- The block pressure in cell 10,10,10 \- in LGR3
.PP
The option \fB\-\-list\fR can be used to list all available keys.
.SH OPTIONS
.HP
\fB\-\-list\fR : The program will list available keys.
.HP
\fB\-\-no\-restart\fR: If the simulation in question is a restart, i.e a prediction
.IP
which starts at the end of the historical period, the ecl_summary
program will by default also load historical data. If the \fB\-\-no\-restart\fR
option is used the program will not look for old results.
.HP
\fB\-\-no\-header\fR: By default ecl_summary will print a header line at the top, with the
.IP
option \fB\-\-no\-header\fR this will be suppressed.
.HP
\fB\-\-report\-only\fR: Will only report results at report times (i.e. DATES).
.HP
\fB\-\-help\fR: Print this message and exit.
.PP
The options should come before the ECLIPSE basename.
.PP
Example1:
.TP
computer> ecl_summary
CASE1_XXX WWCT:F\-36 FOPT FWPT
.IP
This example will load results from case 'CASE1_XXX' and print the
results for keys 'WWCT:F\-36', 'FOPT' and 'FWPT' on standard out.
.PP
Example2:
.TP
computer> ecl_summary
\fB\-\-list\fR CASE2_XXX "*:F\-36" "BPR:*"
.IP
This example will list all the available keys which end with
\&':F\-36' and those which start with 'BPR:'. Observe the use of
quoting characters "" when using shell wildcards.
.PP
The ecl_summary program will look for and load both unified and
non\-unified and formatted and non\-formatted files. The default
search order is: UNSMRY, Snnnn, FUNSMRY, Annnn, however you can
manipulate this with the extension to the basename:
.PP
* If the extension corresponds to an unformatted file, ecl_summary
.IP
will only look for unformatted files.
.PP
* If the extension corresponds to a unified file, ecl_summary will
.IP
only look for unified files.
.PP
Contact Joakim Hove / joaho@statoil.com / 92 68 57 04 for bugs
and feature requests.
.PP
The ecl_summary program is used to quickly extract summary vectors
from ECLIPSE summary files. The program is invoked as:
.PP
computer> ecl_summary \fI\,/Path/to/ECLIPSE\/\fP key1 key2 key3 ....
.PP
Here ECLIPSE is the name of an existing case, you can give it with
extension, or without; the case need not be in the current directory.
.PP
The keys are formed by combining ECLIPSE variable names and
qualifiers from the WGNAMES and NUMS arrays. Examples of keys are:
.TP
WWCT:F\-36
\- The watercut in the well F\-36.
.TP
FOPT
\- The total field oil production.
.TP
RPR:3
\- The region pressure in region 3.
.TP
GGIT:NORTH
\- The total gas injection group NORTH.
.TP
SPR:F\-12:18
\- The segment pressure in well F\-12, segment 18.
.TP
BPR:10,10,10
\- The block pressure in cell 10,10,10.
.IP
LBPR:LGR3:10,10,10 \- The block pressure in cell 10,10,10 \- in LGR3
.PP
The option \fB\-\-list\fR can be used to list all available keys.
.HP
\fB\-\-list\fR : The program will list available keys.
.HP
\fB\-\-no\-restart\fR: If the simulation in question is a restart, i.e a prediction
.IP
which starts at the end of the historical period, the ecl_summary
program will by default also load historical data. If the \fB\-\-no\-restart\fR
option is used the program will not look for old results.
.HP
\fB\-\-no\-header\fR: By default ecl_summary will print a header line at the top, with the
.IP
option \fB\-\-no\-header\fR this will be suppressed.
.HP
\fB\-\-report\-only\fR: Will only report results at report times (i.e. DATES).
.HP
\fB\-\-help\fR: Print this message and exit.
.PP
The options should come before the ECLIPSE basename.
.PP
Example1:
.TP
computer> ecl_summary
CASE1_XXX WWCT:F\-36 FOPT FWPT
.IP
This example will load results from case 'CASE1_XXX' and print the
results for keys 'WWCT:F\-36', 'FOPT' and 'FWPT' on standard out.
.PP
Example2:
.TP
computer> ecl_summary
\fB\-\-list\fR CASE2_XXX "*:F\-36" "BPR:*"
.IP
This example will list all the available keys which end with
\&':F\-36' and those which start with 'BPR:'. Observe the use of
quoting characters "" when using shell wildcards.
.PP
The ecl_summary program will look for and load both unified and
non\-unified and formatted and non\-formatted files. The default
search order is: UNSMRY, Snnnn, FUNSMRY, Annnn, however you can
manipulate this with the extension to the basename:
.PP
* If the extension corresponds to an unformatted file, ecl_summary
.IP
will only look for unformatted files.
.PP
* If the extension corresponds to a unified file, ecl_summary will
.IP
only look for unified files.
.PP
Contact Joakim Hove / joaho@statoil.com / 92 68 57 04 for bugs
and feature requests.
-19
View File
@@ -1,19 +0,0 @@
#!/usr/bin/env python
import sys
import os
import subprocess
import shutil
config_file = sys.argv[1]
PYTHONPATH = sys.argv[2]
work_path = sys.argv[3]
os.environ["PYTHONPATH"] = PYTHONPATH
shutil.copy(config_file , work_path)
os.chdir( work_path )
if not os.path.isdir("_static"):
os.mkdir("_static")
subprocess.call(["sphinx-apidoc" , "-e" , "-o" , "API/python" , PYTHONPATH ])
subprocess.call(["sphinx-build" , "-b" , "html" , "-d" , "_build/doctrees" , "." , "_build"])
+31
View File
@@ -114,6 +114,37 @@ variable, i.e. set it to a constant value. Here is an example of use:
CONST 1.0
DUNIF
-----
The keyword DUNIF is used to assign a discrete uniform distribution. It takes three arguments, the number bins, a minimum and maximum value. Here is an example which creates a discrete uniform distribution on [0,1] with 25 bins:
::
DUNIF 25 0 1
ERRF
-----
The ERRF keyword is used to define a prior resulting from applying the error function to a normally distributed variable with mean 0 and variance 1. The keyword takes four arguments:
::
ERRF MIN MAX SKEWNESS WIDTH
The arguments MIN and MAX sets the minimum and maximum value of the transform. Zero SKEWNESS results in a symmetric distribution, whereas negative SKEWNESS will shift the distribution towards the left and positive SKEWNESS will shift it towards the right. Letting WIDTH be larger than one will cause the distribution to be unimodal, whereas WIDTH less than one will create a bi-modal distribution.
DERRF
-----
The keyword DERRF is similar to ERRF, but will create a discrete output. DERRF takes 5 arguments:
::
DERRF NBINS MIN MAX SKEWNESS WIDTH
NBINS set the number of discrete values, and the other arguments have the same effect as in ERRF.
Priors and transformations
+108 -160
View File
@@ -33,7 +33,6 @@ List of keywords
Keyword name Required by user? Default value Purpose
===================================================================== ====================================== ============================== ==============================================================================================================================================
:ref:`ADD_FIXED_LENGTH_SCHEDULE_KW <add_fixed_length_schedule_kw>` NO Supporting unknown SCHEDULE keywords.
:ref:`ADD_STATIC_KW <add_Static_kw>` NO Add static ECLIPSE keyword that should be stored
:ref:`ANALYSIS_COPY <analysis_copy>` NO Create new instance of analysis module
:ref:`ANALYSIS_LOAD <analysis_load>` NO Load analysis module
:ref:`ANALYSIS_SET_VAR <analysis_set_var>` NO Set analysis module internal state variable
@@ -52,20 +51,15 @@ Keyword name Required by
:ref:`ENKF_BOOTSTRAP <enkf_bootstrap>` NO FALSE Should we bootstrap the Kalman gain estimate
:ref:`ENKF_CROSS_VALIDATION <enkf_cross_validation>` NO ...
:ref:`ENKF_CV_FOLDS <enkf_cv_folds>` NO 10 Number of folds used in the Cross-Validation scheme
:ref:`ENKF_FORCE_NCOMP <enkf_force_ncomp>` NO FALSE Should we want to use a spesific subspace dimension
:ref:`ENKF_KERNEL_REGRESSION <enkf_kernel_regression>` NO FALSE
:ref:`ENKF_KERNEL_FUNCTION <enkf_kernel_function>` NO 1
:ref:`ENKF_KERNEL_PARAM <enkf_kernel_param>` NO 1
:ref:`ENKF_LOCAL_CV <enkf_local_cv>` NO FALSE Should we estimate the subspace dimenseion using Cross-Validation
:ref:`ENKF_MERGE_OBSERVATIONS <enkf_merge_observations>` NO FALSE Should observations from many times be merged together
:ref:`ENKF_MODE <enkf_mode>` NO STANDARD Which EnKF should be used
:ref:`ENKF_NCOMP <enkf_ncomp>` NO 1 Dimension of the reduced order subspace (If ENKF_FORCE_NCOMP = TRUE)
:ref:`ENKF_PEN_PRESS <enkf_pen_press>` NO FALSE Should we want to use a penalised PRESS statistic in model selection?
:ref:`ENKF_RERUN <enkf_rerun>` NO FALSE Should the simulations be restarted from time zero after each update.
:ref:`ENKF_SCALING <enkf_scaling>` NO TRUE Do we want to normalize the data ensemble to have unit variance?
:ref:`ENKF_TRUNCATION <enfk_truncation>` NO 0.99 Cutoff used on singular value spectrum.
:ref:`ENSPATH <enspath>` NO storage Folder used for storage of simulation results.
:ref:`EQUIL_INIT_FILE <equil_init_file>` NO Use INIT_SECTION instead
:ref:`ENSPATH <enspath>` NO storage Folder used for storage of simulation results.
:ref:`FIELD <field>` NO Ads grid parameters
:ref:`FORWARD_MODEL <forward_model>` NO Add the running of a job to the simulation forward model.
:ref:`GEN_DATA <gen_data>` NO Specify a general type of data created/updated by the forward model.
@@ -76,11 +70,7 @@ Keyword name Required by
:ref:`GRID <grid>` NO Provide an ECLIPSE grid for the reservoir model.
:ref:`HISTORY_SOURCE <history_source>` NO REFCASE_HISTORY Source used for historical values.
:ref:`HOOK_WORKFLOW <hook_workflow>` NO Install a workflow to be run automatically.
:ref:`HOST_TYPE <host_type>` NO
:ref:`IGNORE_SCHEDULE <ignore_schedule>` NO
:ref:`IMAGE_TYPE <image_type>` NO png The type of the images created when plotting.
:ref:`IMAGE_VIEWER <image_viewer>` NO /usr/bin/display External program spawned to view images.
:ref:`INIT_SECTION <init_section>` NO Initialization code for the reservoir model.
:ref:`IGNORE_SCHEDULE <ignore_schedule>` NO
:ref:`INSTALL_JOB <install_jobb>` NO Install a job for use in a forward model.
:ref:`ITER_CASE <iter_Case>` NO IES%d Case name format - iterated ensemble smoother
:ref:`ITER_COUNT <iter_count>` NO 4 Number of iterations - iterated ensemble smoother
@@ -99,22 +89,13 @@ Keyword name Required by
:ref:`LSF_SERVER <lsf_server>` NO Set server used when submitting LSF jobs.
:ref:`MAX_ITER_COUNT <max_iter_count>` NO Maximal number of iterations - iterated ensemble smoother.
:ref:`MAX_RESAMPLE <max_resample>` NO 1 How many times should ert resample & retry a simulation.
:ref:`MAX_RUNNING_LOCAL <max_running_local>` NO The maximum number of running jobs when running locally.
:ref:`MAX_RUNNING_LSF <max_running_lsf>` NO The maximum number of simultaneous jobs submitted to LSF.
:ref:`MAX_RUNNING_RSH <max_running_rsh>` NO The maximum number of running jobs when using RSH queue system.
:ref:`MAX_RUNTIME <max_runtime>` NO 0 Set the maximum runtime in seconds for a realization.
:ref:`MAX_SUBMIT <max_submit>` NO 2 How many times should the queue system retry a simulation.
:ref:`MIN_REALIZATIONS <min_realizations>` NO 0 Set the number of minimum reservoir realizations to run before long running realizations are stopped. Keyword STOP_LONG_RUNNING must be set to TRUE when MIN_REALIZATIONS are set.
:ref:`NUM_REALIZATIONS <num_realizations>` YES Set the number of reservoir realizations to use.
:ref:`OBS_CONFIG <obs_config>` NO File specifying observations with uncertainties.
:ref:`PLOT_DRIVER <plot_driver>` NO PLPLOT Which plotting system should be used.
:ref:`PLOT_ERRORBAR <plot_errorbar>` NO FALSE Should errorbars on observations be plotted?
:ref:`PLOT_ERRORBAR_MAX <plot_errorbar_max>` NO 25 Show error bars if less than this number of observations.
:ref:`PLOT_HEIGHT <plot_height>` NO 768 Pixel height of the plots.
:ref:`PLOT_PATH <plot_path>` NO plots Path to where the plots are stored.
:ref:`PLOT_REFCASE <plot_refcase>` NO TRUE TRUE (IF you want to plot the listed reference cases) FALSE if not.
:ref:`PLOT_REFCASE_LIST <plot_refcase_list>` NO Deprecated. Use REFCASE_LIST instead.
:ref:`PLOT_WIDTH <plot_width>` NO 1024 Pixel width of the plots.
:ref:`PLOT_SETTINGS <plot_driver>` NO Possibility to configure some aspects of plotting.
:ref:`PRE_CLEAR_RUNPATH <pre_clear_runpath>` NO FALSE Should the runpath be cleared before initializing?
:ref:`QUEUE_SYSTEM <queue_system>` NO System used for running simulation jobs.
:ref:`REFCASE <refcase>` NO (see HISTORY_SOURCE and SUMMARY) Reference case used for observations and plotting.
@@ -132,7 +113,6 @@ Keyword name Required by
:ref:`SCHEDULE_PREDICTION_FILE <schedule_prediction_file>` NO Schedule prediction file.
:ref:`SETENV <setenv>` NO You can modify the UNIX environment with SETENV calls.
:ref:`SINGLE_NODE_UPDATE <single_node_update>` NO FALSE ...
:ref:`STD_CUTOFF <std_cutoff>` NO 1e-6 ...
:ref:`STOP_LONG_RUNNING <stop_long_running>` NO FALSE Stop long running realizations after minimum number of realizations (MIN_REALIZATIONS) have run.
:ref:`STORE_SEED <store_seed>` NO File where the random seed used is stored.
:ref:`SUMMARY <summary>` NO Add summary variables for internalization.
@@ -141,7 +121,8 @@ Keyword name Required by
:ref:`TIME_MAP <time_map>` NO Ability to manually enter a list of dates to establish report step <-> dates mapping.
:ref:`UMASK <umask>` NO Control the permissions on files created by ERT.
:ref:`UPDATE_LOG_PATH <update_log_path>` NO update_log Summary of the EnKF update steps are stored in this directory.
:ref:`UPDATE_PATH <update_path>` NO Modify a UNIX path variable like LD_LIBRARY_PATH.
:ref:`UPDATE_PATH <update_path>` NO Modify a UNIX path variable like LD_LIBRARY_PATH.
:ref:`UPDATE_SETTINGS <update_settings>` NO Possibility to configure some common aspects of the Smoother update.|
:ref:`WORKFLOW_JOB_DIRECTORY <workflow_job_directory>` NO Directory containing workflow jobs.
===================================================================== ====================================== ============================== ==============================================================================================================================================
@@ -207,29 +188,6 @@ These keywords must be set to make the enkf function properly.
GRID MY_GRID.EGRID
.. _init_section:
.. topic:: INIT_SECTION
The INIT_SECTION keyword is used to handle initialization of the ECLIPSE run. See the documentation of the Initialization for more details on why this has to be done. The keyword can be used in two different ways:
* If it is set to the name of an existing file, the contents of this file will be used for the initialization.
* If it is set to the name of a non-existing file, it will be assumed that a file with this name in the simulation folder will be generated when simulations are submitted, either by the enkf application itself, or by some job installed by the user (see INSTALL_JOB). This generated file will then be used by ECLIPSE for initialization.
*Example A:*
::
-- Use the contents of the file parameters/EQUIL.INC for initialization
INIT_SECTION params/EQUIL.INC
*Example B:*
::
-- Use a generated file for the initialization
INIT_SECTION MY_GENERATED_EQUIL_KEYWORD.INC
.. _num_realizations:
.. topic:: NUM_REALIZATIONS
@@ -591,7 +549,26 @@ The keywords in this section are used to define a parametrization of the ECLIPSE
Here ID is again an arbitrary string, ECLIPSE_FILE is the name of the file the enkf will export this field to when running simulations. Note that there should be an IMPORT statement in the ECLIPSE data file corresponding to the name given with ECLIPSE_FILE. INIT_FILES is a filename (with an embedded %d) to load the initial field from. Can be RMS ROFF format, ECLIPSE restart format or ECLIPSE GRDECL format.
The options MIN, MAX, INIT_TRANSFORM and OUTPUT_TRANSFORM are all optional. MIN and MAX are as for dynamic fields. OUTPUT_TRANSFORM is the name of a mathematical function which will be applied to the field before it is exported, and INIT_TRANSFORM is the name of a function which will be applied to the fields when they are loaded. [Just use INIT_TRANSFORM:XXX to get a list of available functions.]
The input arguments MIN, MAX, INIT_TRANSFORM and OUTPUT_TRANSFORM are all optional. MIN and MAX are as for dynamic fields.
For Assisted history matching, the variables in ERT should be normally distributed internally - the purpose of the transformations is to enable working with normally distributed variables internally in ERT. Thus, the optional arguments INIT_TRANSFORM:FUNC and OUTPUT_TRANSFORM:FUNC are used to transform the user input of parameter distribution. INIT_TRANSFORM:FUNC is a function which will be applied when they are loaded to ERT. OUTPUT_TRANSFORM:FUNC is a function which will be applied to the field when it is exported from ERT, and FUNC is the name of a transformation function to be applied. The avaialble functions are listed below:
"POW10" : This function will raise x to the power of 10: y = 10^x.
"TRUNC_POW10" : This function will raise x to the power of 10 - and truncate lower values at 0.001.
"LOG" : This function will take the NATURAL logarithm of x: y = ln(x).
"LN" : This function will take the NATURAL logarithm of x: y = ln(x).
"LOG10" : This function will take the log10 logarithm of x: y = log10(x).
"EXP" : This function will calculate y = exp(x).
"LN0" : This function will calculate y = ln(x + 0.000001
"EXP0" : This function will calculate y = exp(x) - 0.000001
For example, the most common scenario is that underlying log-normal distributed permeability in RMS are transformed to normally distributted in ERT, then you do:
INIT_TRANSFORM:LOG To ensure that the variables which were initially log-normal distributed are transformed to normal distribution when they are loaded into ert.
OUTPUT_TRANSFORM:EXP To ensure that the variables are reexponentiated to be log-normal distributed before going out to Eclipse.
If users specify the wrong function name (e.g INIT_TRANSFORM:I_DONT_KNOW), ERT will stop and print all the valid function names.
Regarding format of ECLIPSE_FILE: The default format for the parameter fields is binary format of the same type as used in the ECLIPSE restart files. This requires that the ECLIPSE datafile contains an IMPORT statement. The advantage with using a binary format is that the files are smaller, and reading/writing is faster than for plain text files. If you give the ECLIPSE_FILE with the extension .grdecl (arbitrary case), enkf will produce ordinary .grdecl files, which are loaded with an INCLUDE statement. This is probably what most users are used to beforehand - but we recomend the IMPORT form.
@@ -959,18 +936,8 @@ Keywords controlling the ES algorithm
.. _enkf_alpha:
.. topic:: ENKF_ALPHA
ENKF_ALPHA has some latex letters - need to be handled!!
Scaling factor (double) used in outlier detection. Increasing this factor means that more observations will potentially be included in the assimilation. The default value is 1.50.
Including outliers in the EnKF algorithm can dramatically increase the coupling between the ensemble members. It is therefore important to filter out these outlier data prior to data assimilation. An observation, \textstyle d^o_i, will be classified as an outlier if
::
|d^o_i - \bar{d}_i| > \mathrm{ENKF\_ALPHA} \left(s_{d_i} + \sigma_{d^o_i}\right),
where \textstyle\boldsymbol{d}^o is the vector of observed data, \textstyle\boldsymbol{\bar{d}} is the average of the forcasted data ensemble, \textstyle\boldsymbol{s_{d}} is the vector of estimated standard deviations for the forcasted data ensemble, and \textstyle\boldsymbol{s_{d}^o} is the vector standard deviations for the observation error (specified a priori).
See the sub keyword :code:`OVERLAP_LIMIT` under the :code:`UPDATE_SETTINGS`keyword.
.. _enkf_bootstrap:
.. topic:: ENKF_BOOTSTRAP
@@ -1219,27 +1186,6 @@ The keywords in this section, controls advanced features of the enkf application
Real low level fix for some SCHEDULE parsing problems.
.. _add_static_kw:
.. topic:: ADD_STATIC_KW
The restart files from ECLIPSE are organized by keywords, which are of three different types:
#. Keywords containing the dynamic solution, e.g. pressure and saturations.
#. Keywords containing various types of header information which is needed for a restart.
#. Keywords containing various types of diagnostic information which is not needed for a restart.
Keywords in category 2 and 3 are referred to as static keywords. To be able to restart ECLIPSE, the enkf application has to store the keywords in category 2, whereas keywords in category 3 can safely be dropped. To determine whether a particular keyword is in category 2 or 3 the enkf considers an internal list of keywords. The current list contains the keywords:
::
INTEHEAD LOGIHEAD DOUBHEAD IGRP SGRP XGRP ZGRP IWEL SWEL XWEL ZWEL
ICON SCON XCON HIDDEN STARTSOL PRESSURE SWAT SGAS RS RV ENDSOL ICAQNUM ICAQ IAAQ
SCAQNUM SCAQ SAAQ ACAQNUM ACAQ XAAQ
ISEG ILBS ILBR RSEG ISTHW ISTHG
By using ADD_STATIC_KW you can dynamically add to this list. The magic string __ALL__ will add all static keywords. Use of the __ALL__ option is strongly discouraged, as it wastes a lot disk space.
.. _define:
.. topic:: DEFINE
@@ -1456,24 +1402,6 @@ option.
The name of the LSF queue you are running ECLIPSE simulations in.
.. _max_running_lsf:
.. topic:: MAX_RUNNING_LSF
The keyword MAX_RUNNING_LSF controls the maximum number of
simultaneous jobs submitted to the LSF (Load Sharing Facility)
queue when using the LSF option in QUEUE_SYSTEM.
*Example:*
::
-- Submit no more than 30 simultaneous jobs
-- to the LSF cluster.
MAX_RUNNING_LSF 30
Configuring TORQUE access
-------------------------
.. _configuring_torque_access:
@@ -1599,25 +1527,6 @@ option DEBUG_OUTPUT:
QUEUE_OPTION TORQUE DEBUG_OUTPUT torque_log.txt
Configuring the LOCAL queue
---------------------------
.. _configuring_the_local_queue:
.. _max_running_local:
.. topic:: MAX_RUNNING_LOCAL
The keyword MAX_RUNNING_LOCAL controls the maximum number of simultaneous jobs running when using the LOCAL option in QUEUE_SYSTEM. It is strongly recommended to not let MAX_RUNNING_LOCAL exceed the number of processors on the workstation used.
*Example:*
::
-- No more than 3 simultaneous jobs
MAX_RUNNING_LOCAL 3
Configuring the RSH queue
-------------------------
.. _configuring_the_rsh_queue:
@@ -1661,24 +1570,6 @@ Keywords related to plotting
.. _keywords_related_to_plotting:
.. _image_viewer:
.. topic:: IMAGE_VIEWER
The enkf application has some limited plotting capabilities. The plotting is based on creating a graphics file (currently a png file) and then viewing that file with an external application. The current default image viewer is a program called /usr/bin/display, but you can set IMAGE_VIEWER to point to another binary if that is desired. In particular it can be interesting to set as
::
IMAGE_VIEWER /d/proj/bg/enkf/bin/noplot.sh
then the plot files will be created, but they will not be flashing in your face (which can be a bit annoying).
.. _image_type:
.. topic:: IMAGE_TYPE
This switch control the type of the plot figures/images created by the PLPLOT plot driver. It is by default set to png which works fine, but you can probably(??) use other popular graphics formats like gif and jpg as well.
.. _plot_driver:
.. topic:: PLOT_DRIVER
@@ -1733,22 +1624,31 @@ Keywords related to plotting
.. _plot_path:
.. topic:: PLOT_PATH
The plotting engine creates 'files' with plots, they are stored in a directory. You can tell what that directory should be. Observe that the current 'casename' will automatically be appended to the plot path.
.. plot_width:
.. topic:: PLOT_WIDTH
When the PLPLOT driver creates a plot file, it will have the width (in pixels) given by the PLOT_WIDTH keyword. The default value for PLOT_WIDTH is 1024 pixels. To create plots of half the size you use:
.. _plot_settings:
.. topic:: PLOT_SETTINGS
::
The :code:`PLOT_SETTINGS` keyword is a "master keyword" which
can be used to configure some aspects of the plotting. These
settings will affect the default behaviour when you create a
new plot, you can still changes these settings interactively.
PLOT_HEIGHT 384
PLOT_WIDTH 512
When using the :code:`PLOT_SETTINGS` keyword you supply a
secondary keyword and a values as the tow arguments:
::
PLOT_SETTINGS SHOW_REFCASE False
Will make sure that your plots are created without the refcase
plotted as default. The available secondary keys are:
SHOW_REFCASE : Default True
SHOW_HISTORY : Default True
.. _rft_config:
@@ -1796,27 +1696,37 @@ Keywords related to plotting
With the keyword :code:`HOOK_WORKFLOW` you can configure workflow
'hooks'; meaning workflows which will be run automatically at certain
points during ERTs execution. Currently there are two points in ERTs
flow of execution where you can hook in a workflow, either just before
the simulations start, :code:`PRE_SIMULATION` - or after all the
simulations have completed :code:`POST_SIMULATION`. The
points during ERTs execution. Currently there are four points in ERTs
flow of execution where you can hook in a workflow, before
the simulations start, :code:`PRE_SIMULATION`; after all the
simulations have completed :code:`POST_SIMULATION`;
before the update step, :code:`PRE_UPDATE` and after the update step, :code:`POST_UPDATE`. The
:code:`POST_SIMULATION` hook is typically used to trigger QC
workflows:
::
HOOK_WORKFLOW initWFLOW PRE_SIMULATION
HOOK_WORKFLOW QC_WFLOW1 POST_SIMULATION
HOOK_WORKFLOW QC_WFLOW2 POST_SIMULATION
HOOK_WORKFLOW initWFLOW PRE_SIMULATION
HOOK_WORKFLOW preUpdateWFLOW PRE_UPDATE
HOOK_WORKFLOW postUpdateWFLOW POST_UPDATE
HOOK_WORKFLOW QC_WFLOW1 POST_SIMULATION
HOOK_WORKFLOW QC_WFLOW2 POST_SIMULATION
In this example the the workflow :code:`initWFLOW` will run after all
the simulation directiories have been created, just before the forward
model is submitted to the queue. When all the simulations are complete
In this example the workflow :code:`initWFLOW` will run after all
the simulation directories have been created, just before the forward
model is submitted to the queue. The workflow :code:`preUpdateWFLOW` will be run before the
update step and :code:`postUpdateWFLOW` will be run after the
update step. When all the simulations are complete
the two workflows :code:`QC_WFLOW1` and :code:`QC_WFLOW2` will be
run. Observe that the workflows being 'hooked in' with the
run.
Observe that the workflows being 'hooked in' with the
:code:`HOOK_WORKFLOW` must be loaded with the :code:`LOAD_WORKFLOW`
keyword.
Currently, :code:`PRE_UPDATE` and :code:`POST_UPDATE` are only
available from python.
Manipulating the Unix environment
---------------------------------
@@ -1861,6 +1771,47 @@ The two keywords SETENV and UPDATE_PATH can be used to manipulate the Unix envir
The whole thing is just a workaround because we can not use $PATH.
.. _update_settings:
.. topic:: UPDATE_SETTINGS
The :code:`UPDATE_SETTINGS` keyword is a *super-keyword* which can be
used to control parameters which apply to the Ensemble Smoother update
algorithm. The :code:`UPDATE_SETTINGS`currently supports the two
subkeywords:
OVERLAP_LIMIT
Scaling factor used when detecting outliers. Increasing
this factor means that more observations will potentially be
included in the assimilation. The default value is 3.00..
Including outliers in the Smoother algorithm can dramatically
increase the coupling between the ensemble members. It is
therefore important to filter out these outlier data prior to
data assimilation. An observation, \textstyle d^o_i, will be
classified as an outlier if
::
|d^o_i - \bar{d}_i| > \mathrm{ENKF\_ALPHA} \left(s_{d_i} + \sigma_{d^o_i}\right),
where \textstyle\boldsymbol{d}^o is the vector of observed
data, \textstyle\boldsymbol{\bar{d}} is the average of the
forcasted data ensemble, \textstyle\boldsymbol{s_{d}} is the
vector of estimated standard deviations for the forcasted data
ensemble, and \textstyle\boldsymbol{s_{d}^o} is the vector
standard deviations for the observation error (specified a
priori).
STD_CUTOFF
If the ensemble variation for one particular measurment is
below this limit the observation will be deactivated. he
default value for this cutoff is 1e-6.
Observe that for the updates many settings should be applied on the
analysis module in question.
.. _umask:
.. topic:: UMASK
@@ -1916,6 +1867,3 @@ The two keywords SETENV and UPDATE_PATH can be used to manipulate the Unix envir
- Owner(7) can execute(1), write(2) and read(4).
- Group(5) can execute(1) and read(4).
- Others(2) can read(4)
+21 -12
View File
@@ -295,28 +295,37 @@ Automatically run workflows : HOOK_WORKFLOW
With the keyword :code:`HOOK_WORKFLOW` you can configure workflow
'hooks'; meaning workflows which will be run automatically at certain
points during ERTs execution. Currently there are two points in ERTs
flow of execution where you can hook in a workflow, either just before
the simulations start, :code:`PRE_SIMULATION` - or after all the
simulations have completed :code:`POST_SIMULATION`. The
points during ERTs execution. Currently there are four points in ERTs
flow of execution where you can hook in a workflow, before
the simulations start, :code:`PRE_SIMULATION`; after all the
simulations have completed :code:`POST_SIMULATION`;
before the update step, :code:`PRE_UPDATE` and after the update step, :code:`POST_UPDATE`. The
:code:`POST_SIMULATION` hook is typically used to trigger QC
workflows:
::
HOOK_WORKFLOW initWFLOW PRE_SIMULATION
HOOK_WORKFLOW QC_WFLOW1 POST_SIMULATION
HOOK_WORKFLOW QC_WFLOW2 POST_SIMULATION
HOOK_WORKFLOW initWFLOW PRE_SIMULATION
HOOK_WORKFLOW preUpdateWFLOW PRE_UPDATE
HOOK_WORKFLOW postUpdateWFLOW POST_UPDATE
HOOK_WORKFLOW QC_WFLOW1 POST_SIMULATION
HOOK_WORKFLOW QC_WFLOW2 POST_SIMULATION
In this example the the workflow :code:`initWFLOW` will run after all
the simulation directiories have been created, just before the forward
model is submitted to the queue. When all the simulations are complete
In this example the workflow :code:`initWFLOW` will run after all
the simulation directories have been created, just before the forward
model is submitted to the queue. The workflow :code:`preUpdateWFLOW` will be run before the
update step and :code:`postUpdateWFLOW` will be run after the
update step. When all the simulations are complete
the two workflows :code:`QC_WFLOW1` and :code:`QC_WFLOW2` will be
run. Observe that the workflows being 'hooked in' with the
run.
Observe that the workflows being 'hooked in' with the
:code:`HOOK_WORKFLOW` must be loaded with the :code:`LOAD_WORKFLOW`
keyword.
Currently, :code:`PRE_UPDATE` and :code:`POST_UPDATE` are only
available from python.
Locating the realisations: <RUNPATH_FILE>
-----------------------------------------