#2011 Update libecl to 89f6c44aa0 to fix RFT file reading and missing dyn nnc handling

This commit is contained in:
Jacob Støren
2017-10-26 17:16:36 +02:00
parent cb78ad8c31
commit 04404c3b2c
45 changed files with 2021 additions and 387 deletions

View File

@@ -45,6 +45,7 @@ endif()
option( BUILD_TESTS "Should the tests be built" OFF)
option( BUILD_APPLICATIONS "Should we build small utility applications" OFF)
option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF)
option( BUILD_NEXUS "Build support for the Nexus simulator" ON)
option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF)
option( BUILD_SHARED_LIBS "Build shared libraries" ON )
option( ERT_USE_OPENMP "Use OpenMP" OFF )
@@ -248,6 +249,11 @@ check_include_file(execinfo.h HAVE_EXECINFO)
check_include_file(getopt.h ERT_HAVE_GETOPT)
check_include_file(unistd.h ERT_HAVE_UNISTD)
# Portability checks; look for htons function
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("winsock2.h" HAVE_WINSOCK2_H)
check_type_size(time_t SIZE_OF_TIME_T)
if (${SIZE_OF_TIME_T} EQUAL 8)
try_run(RUN_RESULT COMPILE_RESULT ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_mktime_before1970.c)
@@ -357,9 +363,6 @@ if (BUILD_PYTHON)
endif()
endif()
if (INSTALL_ERT)
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
endif()
install(EXPORT ecl-config DESTINATION share/cmake/ecl)
export(TARGETS ecl FILE eclConfig.cmake)
export(PACKAGE ecl)

View File

@@ -0,0 +1,109 @@
This files contains additional information about the structure of restart files generated in ECLIPSE.
This applies to the case spe1 in the opm-data repository.
INTEHEAD:
0: Value based on computer time in which the file was written
67: Timestep
68: Report step
219: Report step-1
Values not described her or in ecl_kw_magic, are constant during simulation.
LOGIHEAD
1: Set to true if RV values are calculated.
86: does not impact solution
Values not described her or in ecl_kw_magic, are constant during simulation.
DOUBHEAD:
0: days
21: EQUIL, item 1
157: Reservoir mean pressure
158: A double related to RS, but does not impact solution
159: possibly related to RV, 0 if RV not set
160: Start of simulation, 735979 days after year 0
161: A whole number, value = 735979 + days
(735979 / 365.25 = 2015.00007. 735979 = Number of days since year 0)
Values not described her or in ecl_kw_magic, are constant during simulation.
IWEL:
Changes during eclipse simulation. Reset to start values at restart stage does not impact solution. Related to the values:
index: 7
index: 8
index: 23
index: 141
index: 154
index: 178
All values except 7, 8, 23 , 141 154 and 178 are constant during simulation.
Known IWELS in addition to ecl_kw_magic:
0: PROD, X
1: PROD, Y
2: COMPDAT, 'PROD', item 4
3: COMPDAT, 'PROD', item 5
4: Number of completion connections
7, Uncertain
8: Uncertain
15: 1 = Oil production, 3 = Gas production
155: INJ, X
156: INJ, Y
157: COMPDAT, 'INJ', item 4
158: COMPDAT, 'INJ', item 5
159: Number of completion connections
168: Uncertain
SWEL:
Mostly SWEL will contain the values:
0
1
+/-100000002004087734272, which are either missing entries in the .DATA file or settings.
Otherwise:
0: WCONPROD, item 4, noentry = 100000002004087734272
2: WCONPROD, item 6, noentry = 100000002004087734272
6: WCONPROD, item 9
9: WELSPECS, 'PROD', item 5
54: same as index: 2
55: same as index: 6
122: WCONINJ, item 6
124: WCONINJ, item 5
128: WCONINJ, item 7
131: WELSPECS, 'INJ', item 5
176: same as index: 124
177: same as index: 128
During simulation spe1, SWEL is constant.
ICON:
1: I coordinate
2: J coordinate
3: K coordinate
4: Number of cells IF: I, J, K is are max.
During simulation spe1, ICON is constant.
These KS are unchanged during simulation (spe1):
LOGIHEAD
IGRP
SGRP
SWEL
ZWLS
ICON
SCON
KW that does not need to be present (can be removed):
XGRP
ZGRP
XWEL
IWLS
XCON
DLYTIM
HIDDEN
REGDIMS
FIPFAMNA
REGRPT
note about STARTSOL:
ECLIPSE may cause if error or bugs anything unknwon or unecessary is added after STARTSOL
In spe1, there are some extra KWs after ENDSOL, and the TEMP and RV words, which should be removed.
If RV is calculated, Logihead indx: 1 should be set to true, if RV is not calculated, logihead,indx 1 should be set to false and RV should not be printed to solution.

View File

@@ -0,0 +1,268 @@
Source:
kw_magic: K
Schlum : S
Decrypt : D
INTEHEAD
INDEX SOURCE VALUE
0 S/D ISNUM = Time encoded number
1 D 201601
2 K/S units type = 1 (METRIC), 2 (FIELD), 3 (LAB), 4 (PVT-M)
3 D CONSTANT, -2345
4 D CONSTANT, -2345
5 D CONSTANT, -2345
6 D CONSTANT, -2345
7 D CONSTANT, -2345
8 K/S NX, cells in x dimension
9 K/S NY, cells in y dimension
10 K/S NZ, cells in z dimenstion
11 K/S NACTIV, number of active cells
12 - -
13 - -
14 K/S IPHS, intehead phase indicator
15 D CONSTANT, -2345
16 K/S NWELLS=number of wells
17 K/S NCWMAX=maximum number of completions per wells
18 - -
19 K/S NWGMAX=maximum number of wells in any well group
20 K/S NGMAXZ=maximum number of groups in field
21 D CONSTANT, 0
22 D CONSTANT, 0
23 D CONSTANT, 0
24 K/S NWELZ=number of data elements per well in IWEL array
25 K/S NSWELZ=number of data elements per well in SWEL array
26 K/S NXWELZ=number of data elements per well in XWEL array
27 K/S NZWELZ=number of data elements per well in ZWEL array
28 - -
29 - -
30 D CONSTANT, 1
31 D CONSTANT, -2345
32 K/S NICONZ=number of elements in ICON array
33 K/S NSCONZ=number of elements in SCON array
34 K/S NXCONZ=number of elements in XCON array
35 D CONSTANT, -2345
36 K/S NIGRPZ=number of data elements per group in IGRP array
37 S NSGRPZ=number of data elements per group in SGRP array
38 S NXGRPZ=number of data elements per group in XGRP array
39 S NZGRPZ=number of data elements per group in ZGRP array
40 D CONSTANT, 0
41 S NCAMAX=maximum number of analytic aquifer connections
42 S NIAAQZ=number of data elements per aquifer in IAAQ array
43 S NSAAQZ=number of data elements per aquifer in SAAQ array
44 S NXAAQZ=number of data elements per aquifer in XAAQ array
45 S NICAQZ=number of data elements per aquifer in ICAQ array
46 S NSCAQZ=number of data elements per aquifer in SCAQ array
47 S NXCAQZ=number of data elements per aquifer in XCAQ array
48 D CONSTANT, 0
49 - -
50 D CONSTANT, 1
51 - -
52 D CONSTANT, 0
53 D CONSTANT, 0
54 D CONSTANT, 0
55 - -
56 D CONSTANT, 0
57 D CONSTANT, 0
58 D CONSTANT, 0
59 D CONSTANT, 0
60 D CONSTANT, 0
61 D CONSTANT, 0
62 D CONSTANT, 0
63 D CONSTANT, 0
64 K/S IDAY
65 K/S IMON
66 K/S IYEAR
67 D Timestep
68 D Reportstep
69 D CONSTANT, 0
70 D CONSTANT, 1
71 D CONSTANT, 0
72 D CONSTANT, 0
73 D CONSTANT, 0
74 - -
75 D CONSTANT, 0
76 - -
77 D CONSTANT, 10
78 D CONSTANT 0
79 - -
80 D CONSTANT, 12
81 D CONSTANT, 1
82 - -
83 D CONSTANT, 1
84 D CONSTANT, -2345
85 D CONSTANT, -2345
86 - -
87 D CONSTANT, 8
88 - -
89 - -
90 D CONSTANT, 2
91 D CONSTANT, 3
92 D CONSTANT, 1
93 D CONSTANT, 2
94 K/S IPROG, simulation program identifier
95 D CONSTANT, 0
96 - -
97 D CONSTANT, 0
98 D CONSTANT, -17
99 - -
100 D 0
101 D 1
102 D 0
103 D 1
104 D 0
105 D NX
106 D NY
107 D Number of cells
108 - -
109 D CONSTANT, 1
110 D CONSTANT, 1
111 D CONSTANT, 1
112 D CONSTANT, 1
113 - -
114 - -
115 - -
116 D CONSTANT, 25
117 D CONSTANT, 1
118 D CONSTANT, 0
119 D CONSTANT, 0
120 D CONSTANT, 0
121 D CONSTANT, 0
122 D CONSTANT, 0
123 D CONSTANT, 1
124 D CONSTANT, 1
125 D CONSTANT, 1
126 D CONSTANT, 0
127 D CONSTANT, 0
128 - -
129 D CONSTANT, 0
130 D CONSTANT, 0
131 D CONSTANT, 0
132 D CONSTANT, 0
133 D CONSTAND, 14
134 D CONSTAND, 11
135 D CONSTAND, 10
136 D CONSTAND, 17
137 D CONSTANT, 2
138 D CONSTANT, 1
139 D CONSTANT, 1
140 D CONSTANT, 1
141 D CONSTANT, 1
142 - -
143 D CONSTANT, 1
144 D CONSTANT, 1
145 D CONSTANT, 1
146 D CONSTANT, 1
147 D CONSTANT, 1
148 D CONSTANT, 1
149 - -
150 D CONSTANT, 122
151 D CONSTANT, 0
152 D CONSTANT, 0
153 D CONSTANT, 0
154 D CONSTANT, 0
155 D CONSTANT, 0
156 D CONSTANT, 0
157 D CONSTANT, 50
158 D CONSTANT, 10
159 D CONSTANT, 4
160 D CONSTANT, 5
161 D CONSTANT, 9
162 D CONSTANT, 0
163 - -
164 D CONSTANT; 8
165 D CONSTANT; 8
166 D CONSTANT; 12
167 D CONSTANT; 1
168 D CONSTANT; 25
169 D CONSTANT; 1
170 D CONSTANT, -1073741823
171 D CONSTANT, -1073741823
172 D CONSTANT, -1073741823
173 D CONSTANT, -1073741823
174 D CONSTANT, 0
175 D CONSTANT, 1
176 D CONSTANT, 1
177 D CONSTANT, 1
178 D CONSTANT, 22
179 - -
180 D CONSTANT, 10
181 D CONSTANT, 1
182 D CONSTANT, 1
183 D CONSTANT, 1
184 D CONSTANT, 1
185 - -
186 D CONSTANT, 116
187 D CONSTANT, -1073741823
188 D CONSTANT, -1073741823
189 D CONSTANT, 0
190 D CONSTANT, 0
191 D CONSTANT, 130
192 D CONSTANT, 58
193 D CONSTANT, 180
194 D CONSTANT, 10
195 D CONSTANT, 0
196 D CONSTANT, 25
197 D CONSTANT, 155
198 D CONSTANT, 0
199 D CONSTANT, 0
200 D CONSTANT, 1
201 - -
202 D CONSTANT, 116
203 D CONSTANT, 0
204 D CONSTANT, 0
205 D CONSTANT, 0
206 D CONSTANT, 0
207 D CONSTANT, 0
208 D CONSTANT, 0
209 D CONSTANT, 1
210 D CONSTANT, 0
211 - -
212 D CONSTANT, 0
213 D CONSTANT, 0
214 D CONSTANT, 1
215 D CONSTANT, 0
216 D CONSTANT, 0
217 D CONSTANT, 1
218 D CONSTANT, 0
219 D Reportstep - 1
220 D CONSTANT, 12
221 D CONSTANT, 0
222 D CONSTANT, 0
223 D CONSTANT, 10
224 D CONSTANT, 13
225 D CONSTANT, 1
226 D CONSTANT, 0
227 D CONSTANT, 0
228 D CONSTANT, 0
229 D CONSTANT, 0
230 D CONSTANT, 2
231 D CONSTANT, 0
232 D CONSTANT, 0
233 D CONSTANT, 3600
234 D CONSTANT, 1
235 D CONSTANT, 0
236 D CONSTANT, 1
237 D CONSTANT, 10
238 D CONSTANT, 1
239 D CONSTANT, 10
240 - -
241 D CONSTANT, 1
242 - -
287 D Number of cells
302-410 D CONSTANT, -2345
DOUBHEAD

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python
import sys
import matplotlib.pyplot as plt
# Import the required symbols from the ecl.ecl package.
from ecl.ecl import EclFile, EclGrid, EclRegion, EclRestartFile
# Calculate the average pressure for all the cells in the region using
# three different methods.
def avg_pressure(p, sw, pv, region, region_id, result):
if region:
p_pv = p*pv
p_hc_pv = p*pv*(1 - sw)
hc_pv = pv*(1 - sw)
total_pv = pv.sum( mask = region )
total_hc_pv = hc_pv.sum( mask = region )
p1 = p.sum( mask = region) / region.active_size( )
if total_pv > 0:
p2 = p_pv.sum( mask = region ) / total_pv
else:
p2 = None
if total_hc_pv > 0:
p3 = p_hc_pv.sum( mask = region ) / total_hc_pv
else:
p3 = None
else:
p1 = None
p2 = None
p3 = None
if not region_id in result:
result[region_id] = [[],[],[]]
result[region_id][0].append(p1)
result[region_id][1].append(p2)
result[region_id][2].append(p3)
#-----------------------------------------------------------------
if __name__ == "__main__":
case = sys.argv[1]
grid = EclGrid("%s.EGRID" % case)
rst_file = EclRestartFile(grid, "%s.UNRST" % case)
init_file = EclFile("%s.INIT" % case)
# Create PORV keyword where all the inactive cells have been removed.
pv = grid.compressed_kw_copy( init_file["PORV"][0] )
# Extract an integer region keyword from the init file
region_kw = init_file["EQLNUM"][0]
sim_days = []
result = {}
for header in rst_file.headers():
line = {}
rst_block = rst_file.restart_view( report_step = header.get_report_step( ) )
p = rst_block["PRESSURE"][0]
sw = rst_block["SWAT"][0]
for region_id in range(region_kw.get_max( ) + 1):
region = EclRegion( grid, False )
region.select_equal( region_kw, region_id )
avg_pressure( p, sw, pv , region, region_id, result)
avg_pressure( p, sw, pv , EclRegion( grid, True ), "field", result)
sim_days.append( header.get_sim_days( ) )
for key in result.keys():
plt.figure(1)
for index,p in enumerate(result[key]):
plt.plot( sim_days, p , label="Region:%s P%d" % (key, index + 1))
plt.legend()
plt.show()

31
ThirdParty/Ert/docs/examples/cmp_nnc.py vendored Normal file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env python
import sys
from operator import itemgetter
from ecl.ecl import EclFile, EclGrid
if __name__ == "__main__":
case = sys.argv[1]
grid_file = EclFile("%s.EGRID" % case)
init_file = EclFile("%s.INIT" % case)
grid = EclGrid("%s.EGRID" % case)
nnc1 = grid_file["NNC1"][0]
nnc2 = grid_file["NNC2"][0]
tran = init_file["TRANNNC"][0]
nnc_list = []
for g1,g2,t in zip(nnc1,nnc2,tran):
nnc_list.append((g1,g2,t))
nnc_list = sorted(nnc_list, key = itemgetter(0))
for (g1,g2,T) in nnc_list:
i1,j1,k1 = grid.get_ijk( global_index = g1 )
i2,j2,k2 = grid.get_ijk( global_index = g2 )
print "(%02d,%02d,%02d) -> (%02d,%02d,%02d) T:%g" % (i1,j1,k2,i2,j2,k2,T)

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env python
import sys
from ecl.ecl import EclGrid, EclRegion
def volume_min_max(grid):
vols = [c.volume for c in grid if c.active]
return min(vols), max(vols)
def main(grid):
vmin,vmax = volume_min_max(grid)
dz_limit = 0.3
region = EclRegion(grid, False)
region.select_thin(dz_limit)
print "Smallest cell : %g" % vmin
print "Largest cell : %g" % vmax
print "Thin active cells : %d" % region.active_size()
for ai in region.get_active_list():
c = grid.cell(active_index=ai)
print('dz(%2d, %2d, %2d) = %.3f' % (c.i, c.j, c.k, c.dz))
if __name__ == "__main__":
if len(sys.argv) < 2:
exit('usage: grid_info.py path/to/file.EGRID')
case = sys.argv[1]
grid = EclGrid(case)
main(grid)

51
ThirdParty/Ert/docs/nexus.plt vendored Normal file
View File

@@ -0,0 +1,51 @@
bbbbPLOT__BIN_ : Header - verify file type
562*b : Header - skipped
264*b : Header - skipped
i : num_classes
iii : Day Month Year
i : nx
i : ny
i : nz
i : ncomp (number of phases???)
8b : ???
num_classes *8b : The class names
8*b : Skipped
num_classes *i : The number of variables in each class (var_in_class[])
8*b : Skipped
for c in classes:
4*b : TIME var name
for v in vars[c]:
4*b : The variable names
8*b : Skipped
4*b : Skipped
----> : This is the position of first timestep
while classname != STOP:
8*b : classname
8*b : skipped
f : timestep (will cast to int)
f : time
f : num_items (cast to int)
f : max_items (cast to int)
f : max_perfs (cast to int)
if classame in ["WELLBORE","WELLYR"]:
8*b : skipped
for item in num_items:
8*b : skipped
8*b : skipped
8*b : ncon = atoi( )
48*b : skipped
for con in ncon:
8*b : con_num (ignored)
8*b : layer_name (ignored)
var_in_class*f : The real data
16*b : skipped
else:
8*b : skipped
72*b : skipped
var_in_class*f : The real data

View File

@@ -71,9 +71,14 @@ if (ERT_BUILD_CXX)
ecl/FortIO.cpp
ecl/Smspec.cpp
ecl/EclFilename.cpp
nexus/nexus_plot.cpp
)
endif ()
if (BUILD_NEXUS)
list(APPEND opt_srcs nexus/nexus_plot.cpp)
endif ()
configure_file(build_config.h.in include/ert/util/build_config.h)
configure_file(ert_api_config.h.in include/ert/util/ert_api_config.h)
@@ -215,7 +220,7 @@ endif ()
set_target_properties(ecl PROPERTIES
VERSION ${ECL_VERSION_MAJOR}.${ECL_VERSION_MINOR}
SOVERSION ${ECL_VERSION_MAJOR})
if (INSTALL_ERT)
install(TARGETS ecl
EXPORT ecl-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -240,7 +245,6 @@ if (ERT_BUILD_CXX)
PATTERN *.hpp
)
endif ()
endif()
if (NOT BUILD_TESTS)
return ()
@@ -462,6 +466,15 @@ if (ERT_BUILD_CXX)
endforeach ()
endif ()
if (BUILD_NEXUS)
foreach (name nexus_plot_load nexus2ecl)
add_executable(${name} nexus/tests/${name}.cpp)
target_link_libraries(${name} ecl)
add_test(NAME ${name} COMMAND ${name} ${CMAKE_SOURCE_DIR})
endforeach ()
endif()
if (NOT STATOIL_TESTDATA_ROOT)
return ()
endif()
@@ -676,6 +689,7 @@ add_test(NAME ecl_rft_rft COMMAND ecl_rft ${_eclpath}/Gurbat/ECLIPSE.RFT RFT)
add_test(NAME ecl_rft_rft_rw COMMAND ecl_rft ${_eclpath}/Gurbat/ECLIPSE.RFT RFT_RW)
add_test(NAME ecl_rft_plt COMMAND ecl_rft ${_eclpath}/RFT/TEST1_1A.RFT PLT)
add_test(NAME ecl_rft_mswplt COMMAND ecl_rft ${_eclpath}/RFT/RFT2.RFT MSW-PLT)
add_test(NAME ecl_rft_alloc COMMAND ecl_rft ${_eclpath}/RFT/NORNE_ATW2013_RFTPLT_V2.RFT SIMPLE)
add_executable(ecl_grid_copy_statoil ecl/tests/ecl_grid_copy_statoil.c)
target_link_libraries(ecl_grid_copy_statoil ecl)

View File

@@ -30,6 +30,9 @@
#cmakedefine HAVE_CXX_SHARED_PTR
#cmakedefine HAVE_POSIX_UNLINK
#cmakedefine HAVE_WINDOWS_UNLINK
#cmakedefine HAVE_NETINET_IN_H
#cmakedefine HAVE_ARPA_INET_H
#cmakedefine HAVE_WINSOCK2_H
#cmakedefine HAVE_WINDOWS_GET_TEMP_PATH
@@ -62,5 +65,3 @@
#endif
#endif
#endif

View File

@@ -2442,6 +2442,9 @@ static void ecl_kw_inplace_div_indexed_ ## ctype( ecl_kw_type * target_kw , cons
}
ECL_KW_TYPED_INPLACE_DIV_INDEXED( int )
ECL_KW_TYPED_INPLACE_DIV_INDEXED( double )
ECL_KW_TYPED_INPLACE_DIV_INDEXED( float )
@@ -2467,6 +2470,7 @@ void ecl_kw_inplace_div_indexed( ecl_kw_type * target_kw , const int_vector_type
/*****************************************************************/
@@ -2623,6 +2627,49 @@ ECL_KW_MIN( double )
#undef ECL_KW_MAX_MIN
#define KW_SUM_INDEXED(type) \
{ \
const type * data = ecl_kw_get_data_ref(ecl_kw); \
type sum = 0; \
int size = int_vector_size( index_list ); \
const int * index_ptr = int_vector_get_const_ptr( index_list ); \
for (int i = 0; i < size; i++) \
sum += data[index_ptr[i]]; \
memcpy(_sum , &sum , ecl_kw_get_sizeof_ctype(ecl_kw)); \
}
void ecl_kw_element_sum_indexed(const ecl_kw_type * ecl_kw , const int_vector_type * index_list, void * _sum) {
switch (ecl_kw_get_type(ecl_kw)) {
case(ECL_FLOAT_TYPE):
KW_SUM_INDEXED(float);
break;
case(ECL_DOUBLE_TYPE):
KW_SUM_INDEXED(double);
break;
case(ECL_INT_TYPE):
KW_SUM_INDEXED(int);
break;
case(ECL_BOOL_TYPE):
{
const int * data = ecl_kw_get_data_ref(ecl_kw);
const int * index_ptr = int_vector_get_const_ptr( index_list );
const int size = int_vector_size( index_list );
int sum = 0;
for (int i = 0; i < size; i++)
sum += (data[index_ptr[i]] == ECL_BOOL_TRUE_INT);
memcpy(_sum , &sum , sizeof sum);
}
break;
default:
util_abort("%s: invalid type for element sum \n",__func__);
}
}
#undef KW_SUM
@@ -2630,10 +2677,9 @@ ECL_KW_MIN( double )
#define KW_SUM(type) \
{ \
type * data = ecl_kw_get_data_ref(ecl_kw); \
const type * data = ecl_kw_get_data_ref(ecl_kw); \
type sum = 0; \
int i; \
for (i=0; i < ecl_kw_get_size(ecl_kw); i++) \
for (int i=0; i < ecl_kw_get_size(ecl_kw); i++) \
sum += data[i]; \
memcpy(_sum , &sum , ecl_kw_get_sizeof_ctype(ecl_kw)); \
}

View File

@@ -167,20 +167,19 @@ static ecl_kw_type * ecl_nnc_data_get_kw( const ecl_grid_type * grid, const ecl_
return NULL;
}
static void assert_correct_kw_count(ecl_kw_type * kw, const char * function_name, bool check_kw_count, int correct_kw_count, int kw_count) {
if (check_kw_count & (correct_kw_count != kw_count))
static void assert_correct_kw_count(ecl_kw_type * kw, const char * function_name, int correct_kw_count, int kw_count) {
if (correct_kw_count != kw_count)
util_abort("In function %s, reading kw: %s. %d != %d", function_name, ecl_kw_get_header(kw), correct_kw_count, kw_count);
}
static void ecl_nnc_data_set_values(ecl_nnc_data_type * data, const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file, int kw_type) {
static bool ecl_nnc_data_set_values(ecl_nnc_data_type * data, const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file, int kw_type) {
int current_grid1 = -1;
int current_grid2 = -1;
ecl_kw_type * current_kw = NULL;
int correct_kw_count = 0;
int kw_count = 0;
bool check_kw_count = false;
int nnc_size = ecl_nnc_geometry_size( nnc_geo );
for (int nnc_index = 0; nnc_index < nnc_size; nnc_index++) {
@@ -191,42 +190,42 @@ static void ecl_nnc_data_set_values(ecl_nnc_data_type * data, const ecl_grid_typ
if (grid1 != current_grid1 || grid2 != current_grid2) {
current_grid1 = grid1;
current_grid2 = grid2;
assert_correct_kw_count(current_kw, __func__, check_kw_count, correct_kw_count, kw_count);
assert_correct_kw_count(current_kw, __func__, correct_kw_count, kw_count);
current_kw = ecl_nnc_data_get_kw( grid, init_file, grid1 , grid2 , kw_type);
kw_count = 0;
if (current_kw) {
correct_kw_count = ecl_kw_get_size( current_kw );
check_kw_count = true;
data->size = nnc_index + correct_kw_count;
}
else {
check_kw_count = false;
printf("Warning: failed to obtain kw from file in function %s. ", __func__);
printf("Grid1: %d, Grid2 %d\n", current_grid1, current_grid2);
return false;
}
}
if (current_kw) {
data->values[nnc_index] = ecl_kw_iget_as_double(current_kw, pair->input_index);
kw_count++;
data->values[nnc_index] = ecl_kw_iget_as_double(current_kw, pair->input_index);
kw_count++;
}
else
data->values[nnc_index] = -1;
}
assert_correct_kw_count(current_kw, __func__, check_kw_count, correct_kw_count, kw_count);
assert_correct_kw_count(current_kw, __func__, correct_kw_count, kw_count);
return true;
}
static ecl_nnc_data_type * ecl_nnc_data_alloc__(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file, int kw_type) {
ecl_nnc_data_type * data = util_malloc(sizeof * data);
data->size = 0;
int nnc_size = ecl_nnc_geometry_size( nnc_geo );
data->size = nnc_size;
data->values = util_malloc( nnc_size * sizeof(double));
ecl_nnc_data_set_values(data, grid, nnc_geo, init_file, kw_type);
if (ecl_nnc_data_set_values(data, grid, nnc_geo, init_file, kw_type))
return data;
else {
ecl_nnc_data_free( data );
return NULL;
}
return data;
}
ecl_nnc_data_type * ecl_nnc_data_alloc_tran(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file) {

View File

@@ -1492,3 +1492,36 @@ bool ecl_region_equal( const ecl_region_type * region1 , const ecl_region_type *
} else
return false;
}
/*****************************************************************/
int ecl_region_sum_kw_int( ecl_region_type * ecl_region, const ecl_kw_type * ecl_kw , bool force_active) {
int sum;
const int_vector_type * index_set = ecl_region_get_kw_index_list( ecl_region , ecl_kw , force_active);
ecl_kw_element_sum_indexed( ecl_kw , index_set , &sum );
return sum;
}
float ecl_region_sum_kw_float( ecl_region_type * ecl_region, const ecl_kw_type * ecl_kw , bool force_active) {
float sum;
const int_vector_type * index_set = ecl_region_get_kw_index_list( ecl_region , ecl_kw , force_active);
ecl_kw_element_sum_indexed( ecl_kw , index_set , &sum);
return sum;
}
double ecl_region_sum_kw_double( ecl_region_type * ecl_region, const ecl_kw_type * ecl_kw , bool force_active) {
double sum;
const int_vector_type * index_set = ecl_region_get_kw_index_list( ecl_region , ecl_kw , force_active);
ecl_kw_element_sum_indexed( ecl_kw , index_set , &sum);
return sum;
}
int ecl_region_sum_kw_bool( ecl_region_type * ecl_region, const ecl_kw_type * ecl_kw , bool force_active) {
int sum;
const int_vector_type * index_set = ecl_region_get_kw_index_list( ecl_region , ecl_kw , force_active);
ecl_kw_element_sum_indexed( ecl_kw , index_set , &sum);
return sum;
}

View File

@@ -161,7 +161,12 @@ static ecl_kw_type * ecl_rft_node_get_pressure_kw( ecl_rft_node_type * rft_node
if (ecl_kw_element_sum_float( conpres_kw ) > 0.0 )
return conpres_kw;
else
return ecl_file_view_iget_named_kw( rft , PRESSURE_KW , 0);
if (ecl_file_view_has_kw(rft, PRESSURE_KW))
return ecl_file_view_iget_named_kw( rft , PRESSURE_KW , 0);
else {
fprintf(stderr, "WARNING: %s returned a CONPRES_KW with all values at zero. PRESSURE_KW not found.\n", __func__);
return conpres_kw;
}
}
}

View File

@@ -980,24 +980,20 @@ bool ecl_smspec_needs_num( ecl_smspec_var_type var_type ) {
bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * other) {
bool equal = true;
bool ecl_smspec_equal(const ecl_smspec_type * self,
const ecl_smspec_type * other) {
if (vector_get_size( self->smspec_nodes ) != vector_get_size( other->smspec_nodes))
return false;
if (vector_get_size( self->smspec_nodes ) == vector_get_size( other->smspec_nodes)) {
for (int i=0; i < vector_get_size( self->smspec_nodes ); i++) {
const smspec_node_type * node1 = vector_iget_const( self->smspec_nodes , i );
const smspec_node_type * node2 = vector_iget_const( other->smspec_nodes , i );
for (int i=0; i < vector_get_size( self->smspec_nodes ); i++) {
const smspec_node_type * node1 = vector_iget_const(self->smspec_nodes, i);
const smspec_node_type * node2 = vector_iget_const(other->smspec_nodes, i);
if (!smspec_node_equal( node1,node2)) {
equal = false;
break;
}
if (!smspec_node_equal(node1, node2))
return false;
}
}
} else
equal = false;
return equal;
return true;
}

View File

@@ -1122,6 +1122,14 @@ static int smspec_node_cmp_KEYWORD( const smspec_node_type * node1, const smspec
}
static int smspec_node_cmp_key1( const smspec_node_type * node1, const smspec_node_type * node2) {
if (!node1->gen_key1) {
if (!node2->gen_key1)
return 0;
else
return -1;
} else if (!node2->gen_key1) {
return 1;
}
return util_strcmp_int( node1->gen_key1 , node2->gen_key1 );
}

View File

@@ -150,6 +150,11 @@ void test_plt( const char * plt_file ) {
}
void test_simple_load_rft(const char * filename) {
ecl_rft_file_type * rft_file = ecl_rft_file_alloc_case(filename);
ecl_rft_file_free( rft_file );
}
int main( int argc , char ** argv) {
const char * rft_file = argv[1];
@@ -164,8 +169,10 @@ int main( int argc , char ** argv) {
test_plt( rft_file );
else if (strcmp( mode_string , "MSW-PLT") == 0)
test_plt_msw( rft_file );
else if (strcmp( mode_string , "SIMPLE") == 0)
test_simple_load_rft(rft_file);
else
test_error_exit("Second argument:%s not recognized. Valid values are: RFT and PLT" , mode_string);
exit(0);
}

View File

@@ -57,6 +57,9 @@ void test_cmp_types() {
test_assert_true( smspec_node_cmp( misc_node1, misc_node2) < 0 );
test_assert_true( smspec_node_cmp( misc_node2, misc_node1) > 0 );
smspec_node_type * net1 = smspec_node_alloc(ECL_SMSPEC_NETWORK_VAR, "Net", "FOPT", "UNIT", ":", dims, 10 , 0, 0);
smspec_node_type * net2 = smspec_node_alloc(ECL_SMSPEC_NETWORK_VAR, "Net", "FOPT", "UNIT", ":", dims, 10 , 0, 0);
test_assert_true( smspec_node_cmp( net1, net2) == 0 );
smspec_node_free( segment_node );
smspec_node_free( aquifer_node );
@@ -67,6 +70,8 @@ void test_cmp_types() {
smspec_node_free( field_node );
smspec_node_free( misc_node1 );
smspec_node_free( misc_node2 );
smspec_node_free( net1 );
smspec_node_free( net2 );
}
void test_cmp_well() {

View File

@@ -31,6 +31,8 @@
void test_alloc_global_only(bool data_in_file) {
test_work_area_type * work_area = test_work_area_alloc("nnc-INIT");
{
@@ -66,10 +68,11 @@ void test_alloc_global_only(bool data_in_file) {
ecl_file_view_type * view_file = ecl_file_get_global_view( init_file );
ecl_nnc_data_type * nnc_geo_data = ecl_nnc_data_alloc_tran(grid0, nnc_geo, view_file);
int nnc_data_size = ecl_nnc_data_get_size( nnc_geo_data );
if (data_in_file) {
int nnc_data_size = ecl_nnc_data_get_size( nnc_geo_data );
test_assert_true( ecl_file_view_has_kw( view_file, TRANNNC_KW) );
test_assert_true(nnc_data_size == 3);
const double * values = ecl_nnc_data_get_values( nnc_geo_data );
@@ -78,9 +81,10 @@ void test_alloc_global_only(bool data_in_file) {
test_assert_double_equal(values[2] , 3.0);
}
else
test_assert_true(nnc_data_size == 0);
test_assert_NULL(nnc_geo_data);
ecl_nnc_data_free( nnc_geo_data );
if (data_in_file)
ecl_nnc_data_free( nnc_geo_data );
ecl_nnc_geometry_free( nnc_geo );
ecl_file_close(init_file);
}

View File

@@ -30,12 +30,6 @@
#include <ert/util/test_work_area.h>
void assert_data_values_read(ecl_nnc_data_type * nnc_data) {
int data_size = ecl_nnc_data_get_size(nnc_data);
for (int n = 0; n < data_size; n++) {
test_assert_double_not_equal(-1.0, ecl_nnc_data_iget_value(nnc_data, n));
}
}
int find_index(ecl_nnc_geometry_type * nnc_geo, int grid1, int grid2, int indx1, int indx2) {
int index = -1;
@@ -109,7 +103,7 @@ void test_alloc_file_flux(char * filename, int file_num) {
ecl_file_view_type * view_file = ecl_file_get_global_view( restart_file );
ecl_nnc_data_type * nnc_flux_data = ecl_nnc_data_alloc_wat_flux(grid, nnc_geo, view_file);
assert_data_values_read(nnc_flux_data);
test_assert_not_NULL(nnc_flux_data);
ecl_nnc_data_free( nnc_flux_data );
}
ecl_nnc_geometry_free(nnc_geo);

View File

@@ -148,6 +148,7 @@ extern "C" {
double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw );
void ecl_kw_inplace_inv(ecl_kw_type * my_kw);
void ecl_kw_element_sum(const ecl_kw_type * , void * );
void ecl_kw_element_sum_indexed(const ecl_kw_type * ecl_kw , const int_vector_type * index_list, void * _sum);
void ecl_kw_max_min(const ecl_kw_type * , void * , void *);
void * ecl_kw_get_void_ptr(const ecl_kw_type * ecl_kw);

View File

@@ -291,16 +291,19 @@ values (2e20) are denoted with '*'.
*/
#define INTEHEAD_UNIT_INDEX 2
#define INTEHEAD_NX_INDEX 8
#define INTEHEAD_NY_INDEX 9
#define INTEHEAD_NZ_INDEX 10
#define INTEHEAD_NACTIVE_INDEX 11
#define INTEHEAD_PHASE_INDEX 14
#define INTEHEAD_DAY_INDEX 64
#define INTEHEAD_MONTH_INDEX 65
#define INTEHEAD_YEAR_INDEX 66
#define INTEHEAD_IPROG_INDEX 94
#define INTEHEAD_UNIT_INDEX 2
#define INTEHEAD_NX_INDEX 8
#define INTEHEAD_NY_INDEX 9
#define INTEHEAD_NZ_INDEX 10
#define INTEHEAD_NACTIVE_INDEX 11
#define INTEHEAD_PHASE_INDEX 14
#define INTEHEAD_DAY_INDEX 64
#define INTEHEAD_MONTH_INDEX 65
#define INTEHEAD_YEAR_INDEX 66
#define INTEHEAD_TIMESTEP_INDEX 67
#define INTEHEAD_REPORT_STEP 68
#define INTEHEAD_IPROG_INDEX 94
#define INTEHEAD_REPORT_INDEX 219 (report_steps-1)
#define INTEHEAD_METRIC_VALUE 1

View File

@@ -185,6 +185,10 @@ typedef struct ecl_region_struct ecl_region_type;
/*****************************************************************/
double ecl_region_sum_kw_double( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active);
int ecl_region_sum_kw_int( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active);
float ecl_region_sum_kw_float( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active);
int ecl_region_sum_kw_bool( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active);

View File

@@ -0,0 +1,63 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'nexus_plot.hpp' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef NEXUS_PLOT_H
#define NEXUS_PLOT_H
#include <cinttypes>
#include <stdexcept>
#include <fstream>
#include <string>
#include <vector>
typedef struct ecl_sum_struct ecl_sum_type;
namespace nex {
struct bad_header : public std::runtime_error {
using std::runtime_error::runtime_error;
};
struct read_error : public std::runtime_error {
using std::runtime_error::runtime_error;
};
struct unexpected_eof : public std::runtime_error {
using std::runtime_error::runtime_error;
};
class NexusPlot {
public:
NexusPlot( const std::string& );
NexusPlot( std::istream& );
int32_t num_classes = 0;
int32_t day, month, year;
int32_t nx, ny, nz;
int32_t ncomp;
std::vector<std::string> class_names;
std::vector<int32_t> vars_in_class;
std::vector< std::vector<std::string> > var_names;
ecl_sum_type* ecl_summary( const std::string& ecl_case );
private:
void load( std::istream& );
};
}
#endif // NEXUS_PLOT_H

View File

@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rng.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rng.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef ERT_RNG_H
@@ -38,7 +38,7 @@ typedef enum {
typedef enum {
MZRAN = 1
} rng_alg_type;
typedef unsigned int ( rng_forward_ftype ) ( void * );
typedef void ( rng_set_state_ftype ) ( void * , const char * );
@@ -47,9 +47,9 @@ typedef enum {
typedef void ( rng_free_ftype ) ( void * );
typedef void ( rng_fscanf_ftype ) ( void * , FILE * );
typedef void ( rng_fprintf_ftype ) ( const void * , FILE * );
typedef struct rng_struct rng_type;
rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode );
void rng_free( rng_type * rng);
void rng_free( rng_type * rng);
@@ -63,21 +63,22 @@ typedef enum {
int rng_state_size( const rng_type * rng );
void rng_save_state( rng_type * rng , const char * filename);
void rng_load_state( rng_type * rng , const char * filename);
void rng_set_state( rng_type * rng , const char * state);
void rng_get_state( const rng_type * rng , char * state);
unsigned int rng_forward( rng_type * rng );
double rng_get_double( rng_type * rng );
int rng_get_int( rng_type * rng , int max_value );
unsigned int rng_get_max_int(const rng_type * rng);
double rng_std_normal( rng_type * rng );
void rng_shuffle_int( rng_type * rng , int * data , size_t num_elements);
void rng_shuffle( rng_type * rng , char * data , size_t element_size , size_t num_elements);
void rng_free__( void * arg);
UTIL_SAFE_CAST_HEADER( rng );
#ifdef __cplusplus
}
#endif

View File

@@ -36,6 +36,12 @@
test_error_exit("Correct exception not thrown at %s:%d\n",__FILE__ , __LINE__); \
}
#define test_assert_std_string_equal(s0, s1) \
{ \
if (s0.compare(s1) != 0) \
test_error_exit("Strings not equal at%s:%d (%s != %s)\n", \
__FILE__ , __LINE__, s0.c_str(), s1.c_str()); \
}
#endif

170
ThirdParty/Ert/lib/nexus/nexus_plot.cpp vendored Normal file
View File

@@ -0,0 +1,170 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'nexus_plot.cpp' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <algorithm>
#include <array>
#include <sstream>
#include <iostream>
#include <sstream>
#include <ert/util/build_config.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#elif defined(HAVE_ARPA_INET_H)
#include <arpa/inet.h>
#elif defined(HAVE_WINSOCK2_H)
#include <winsock2.h>
#endif
#include <ert/nexus/nexus_plot.hpp>
#include <ert/ecl/ecl_sum.h>
const std::string NEXUS_PLOT_TYPE_HEADER = "PLOT BIN ";
namespace {
template< int N >
std::string read_str(std::istream& stream) {
std::array< char, N> buf;
stream.read( buf.data(), N );
return std::string( buf.data(), N );
}
struct hinfo {
int32_t num_classes;
int32_t day, month, year;
int32_t nx, ny, nz;
int32_t ncomp;
std::vector<std::string> class_names;
std::vector<int32_t> vars_in_class;
std::vector< std::vector<std::string> > var_names;
};
hinfo headerinfo( std::istream& stream ) {
stream.seekg(4 + 10 + 562 + 264, std::ios::beg);
std::array< int32_t, 8 > buf {};
stream.read( (char*)buf.data(), buf.max_size() * 4 );
if ( !stream.good() ) throw nex::unexpected_eof("");
auto ntoh = []( int32_t x ) { return ntohl( x ); };
std::transform( buf.begin(), buf.end(), buf.begin(), ntoh );
auto negative = []( int32_t x ) { return x < 0; };
if ( std::any_of( buf.begin(), buf.end(), negative ) )
throw nex::bad_header("Negative value, corrupted file");
hinfo h = {
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
{},
std::vector< int32_t >( buf[0], 0 ),
std::vector< std::vector<std::string> >( buf[0],
std::vector<std::string>()),
};
stream.seekg(8, std::ios::cur);
std::array< char, 8 > class_name;
for (int i = 0; i < h.num_classes; i++) {
stream.read(class_name.data(), 8);
h.class_names.push_back(std::string( class_name.data(), 8 ));
}
stream.seekg(8, std::ios::cur);
stream.read((char*) h.vars_in_class.data(), h.num_classes * 4);
std::transform( h.vars_in_class.begin(),
h.vars_in_class.end(),
h.vars_in_class.begin(),
ntoh );
if (std::any_of( h.vars_in_class.begin(), h.vars_in_class.end(), negative))
throw nex::bad_header("Negative value, corrupted file");
stream.seekg(8, std::ios::cur);
for (int i = 0; i < h.num_classes; ++i) {
stream.seekg(4, std::ios::cur);
std::vector< char > var_names( h.vars_in_class[i] * 4, 0 );
stream.read( var_names.data(), h.vars_in_class[i] * 4 );
for (int k = 0; k < h.vars_in_class[i]; ++k)
h.var_names[i].push_back( std::string( var_names.data() + k*4 ,4 ));
stream.seekg(8, std::ios::cur);
}
stream.seekg(4, std::ios::cur);
return h;
}
}
nex::NexusPlot::NexusPlot( const std::string& filename ) {
std::ifstream stream(filename, std::ios::binary);
if ( !stream.good() )
throw nex::read_error("Could not open file " + filename);
this->load(stream);
}
nex::NexusPlot::NexusPlot( std::istream& stream ) {
this->load(stream);
}
void nex::NexusPlot::load(std::istream& stream) {
struct stream_guard {
stream_guard( std::istream& stream ) :
mask( stream.exceptions() ),
s( stream ) {}
~stream_guard() { this->s.exceptions( this->mask ); }
std::ios::iostate mask;
std::istream& s;
} g { stream };
stream.exceptions( std::ios::goodbit );
stream.seekg(4, std::ios::beg); // skip 4 bytes
auto type_header = read_str<10>(stream);
if (type_header.compare(NEXUS_PLOT_TYPE_HEADER) != 0 || !stream.good())
throw nex::bad_header("Could not verify file type");
auto header = headerinfo( stream );
this->num_classes = header.num_classes;
this->day = header.day;
this->month = header.month;
this->year = header.year;
this->nx = header.nx;
this->ny = header.ny;
this->nz = header.nz;
this->ncomp = header.ncomp;
this->class_names = header.class_names;
this->vars_in_class = header.vars_in_class;
this->var_names = header.var_names;
}
ecl_sum_type* nex::NexusPlot::ecl_summary( const std::string& ecl_case ) {
bool unified = true;
bool fmt_output = false;
const char* key_join_string = ":";
time_t sim_start = 0;
bool time_in_days = true;
ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( ecl_case.c_str(),
fmt_output,
unified,
key_join_string,
sim_start,
time_in_days,
this->nx, this->ny, this->nz);
return ecl_sum;
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'nexus2ecl.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <ert/util/test_work_area.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_sum.h>
#include <ert/nexus/nexus_plot.hpp>
void test_create_ecl_sum(char *root_folder) {
test_work_area_type *work_area = test_work_area_alloc("nexus_header");
std::stringstream ss;
ss << root_folder << "/test-data/local/nexus/SPE1.plt";
std::cout << ss.str() << std::endl;
nex::NexusPlot plt = nex::NexusPlot { ss.str() };
ecl_sum_type *ecl_sum = plt.ecl_summary( "ECL_CASE" );
test_assert_true( ecl_sum_is_instance( ecl_sum ));
ecl_sum_fwrite( ecl_sum );
ecl_sum_free( ecl_sum );
test_assert_true( util_file_exists( "ECL_CASE.SMSPEC"));
test_work_area_free(work_area);
}
int main(int argc, char **argv) {
util_install_signals();
test_create_ecl_sum(argv[1]);
exit(0);
}

View File

@@ -0,0 +1,142 @@
/*
Copyright (C) 2017 Statoil ASA, Norway.
The file 'nexus_plot_constructor.cpp' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <array>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <ert/util/test_util.hpp>
#include <ert/nexus/nexus_plot.hpp>
void test_invalid_header1() {
std::stringstream stream( "xxxxINVALID_HEADER" );
test_assert_throw(nex::NexusPlot { stream }, nex::bad_header);
}
void test_invalid_header2() {
std::stringstream stream( "xxx" );
test_assert_throw(nex::NexusPlot { stream }, nex::bad_header);
}
void test_valid_header() {
std::stringstream stream( "xxxxPLOT BIN " );
test_assert_throw(nex::NexusPlot { stream }, nex::unexpected_eof);
}
void test_spe1_header(char *argv) {
std::stringstream ss;
ss << argv << "/test-data/local/nexus/SPE1.plt";
auto plt = nex::NexusPlot { ss.str() };
std::array< std::string, 9 > class_names = {
"WELL ", "WLLYR ", "NODE ", "CONN ", "REGION ", "FIELD ",
"CONNLIST", "TARGET ", "FLOSTA "
};
std::array< int, 9 > vars_in_class = {
56, 52, 4, 43, 69, 58, 20, 25, 25
};
std::array< std::vector< std::string >, 9 > var_names = {
std::vector< std::string > {
"COP ", "CGP ", "CWP ", "CGI ", "CWI ", "QOP ", "QGP ", "QWP ",
"QGI ", "QWI ", "BHP ", "WPH ", "WKH ", "WPAV", "THP ", "COWP",
"QOWP", "GOR ", "WCUT", "WOR ", "QGLG", "CGLG", "DRDN", "DRMX",
"CROP", "CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP ", "RGP ",
"RWP ", "ROI ", "RGI ", "RWI ", "ONTM", "ALQ ", "API ", "QCDP",
"CCDP", "YCDP", "ACTV", "STAT", "Q1P ", "Q1I ", "C1P ", "C1I ",
"X1P ", "Y1P ", "Q2P ", "Q2I ", "C2P ", "C2I ", "X2P ", "Y2P " },
std::vector< std::string > {
"QOP ", "QGP ", "QWP ", "COP ", "CGP ", "CWP ", "CGI ", "CWI ",
"PRES", "HEAD", "RW ", "SKIN", "WI ", "WBC ", "PWB ", "QGI ",
"QWI ", "COWP", "QOWP", "GOR ", "WCUT", "ACTV", "CROP", "CRGP",
"CRWP", "CROI", "CRGI", "CRWI", "ROP ", "RGP ", "RWP ", "ROI ",
"RGI ", "RWI ", "QCDP", "CCDP", "YCDP", "API ", "MD ", "FSEC",
"Q1P ", "Q1I ", "C1P ", "C1I ", "X1P ", "Y1P ", "Q2P ", "Q2I ",
"C2P ", "C2I ", "X2P ", "Y2P " },
std::vector< std::string > { "PNOD", "PDAT", "TNOD", "ACTV" },
std::vector< std::string > {
"QGAS", "QOIL", "QWTR", "CGAS", "COIL", "CWTR", "CBFG", "CBFO",
"CBFW", "QGIS", "QOIS", "QWIS", "P_IN", "POUT", "T_IN", "TOUT",
"ACTV", "STAT", "CSTR", "ITRG", "ONTM", "ALQ ", "SETM", "SETA",
"POWM", "POWA", "SPDM", "SPDA", "API ", "DELP", "QTOT", "GVF ",
"EFF ", "POSN", "WCUT", "GOR ", "WOR ", "Q1 ", "Q2 ", "X1 ",
"X2 ", "Y1 ", "Y2 " },
std::vector< std::string > {
"COP ", "CGP ", "CWP ", "COI ", "CGI ", "CWI ", "PAVT", "PAVH",
"OIP ", "GIP ", "WIP ", "QOP ", "QGP ", "QWP ", "QOI ", "QGI ",
"QWI ", "OIN ", "GIN ", "WIN ", "SO ", "SG ", "SW ", "OREC",
"FGIP", "CIP ", "PAVE", "PAVD", "ROIP", "RGIP", "RWIP", "MRO ",
"MRG ", "MRW ", "NFLX", "PV ", "HCPV", "TAVT", "TAVH", "CROP",
"CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP ", "RGP ", "RWP ",
"ROI ", "RGI ", "RWI ", "QCDP", "CCDP", "YCDP", "API ", "GOR ",
"WCUT", "WOR ", "Z1 ", "Z2 ", "MC1 ", "MC2 ", "MC3 ", "C1P ",
"C2P ", "C3P ", "C1I ", "C2I ", "C3I " },
std::vector< std::string > {
"COP ", "CGP ", "CWP ", "CGI ", "CWI ", "QOP ", "QGP ", "QWP ",
"QGI ", "QWI ", "COWP", "QOWP", "GOR ", "OREC", "GREC", "PAVT",
"PAVH", "QGLG", "CGLG", "WCUT", "NFLX", "CROP", "CRGP", "CRWP",
"CROI", "CRGI", "CRWI", "ROP ", "RGP ", "RWP ", "ROI ", "RGI ",
"RWI ", "OIP ", "GIP ", "WIP ", "QCDP", "CCDP", "YCDP", "WLLS",
"PRDW", "GLFW", "WINJ", "GINJ", "ACTW", "API ", "Q1P ", "Q1I ",
"C1P ", "C1I ", "X1P ", "Y1P ", "Q2P ", "Q2I ", "C2P ", "C2I ",
"X2P ", "Y2P " },
std::vector< std::string > {
"QOP ", "QGP ", "QWP ", "QOI ", "QGI ", "QWI ", "COP ", "CGP ",
"CWP ", "COI ", "CGI ", "CWI ", "API ", "WCUT", "GOR ", "WOR ",
"Q1P ", "Q1I ", "Q2P ", "Q2I " },
std::vector< std::string > {
"SQO ", "SQG ", "SQW ", "SQL ", "SQA ", "SQH ", "RQO ", "RQG ",
"RQW ", "RQL ", "RQA ", "RQH ", "TSQO", "TSQG", "TSQW", "TSQL",
"TSQA", "TSQH", "TRQO", "TRQG", "TRQW", "TRQL", "TRQA", "TRQH",
"P " },
std::vector< std::string > {
"QOP ", "QGP ", "QWP ", "QOI ", "QGI ", "QWI ", "COP ", "CGP ",
"CWP ", "COI ", "CGI ", "CWI ", "WLLS", "PRDW", "GLFW", "WINJ",
"GINJ", "ACTW", "WCUT", "GOR ", "WOR ", "Q1P ", "Q1I ", "Q2P ",
"Q2I " }
};
test_assert_int_equal(plt.num_classes, 9);
test_assert_int_equal(plt.day, 1);
test_assert_int_equal(plt.month, 1);
test_assert_int_equal(plt.year, 1980);
test_assert_int_equal(plt.nx, 1);
test_assert_int_equal(plt.ny, 1);
test_assert_int_equal(plt.nz, 1);
test_assert_int_equal(plt.ncomp, 2);
for (int i = 0; i < plt.num_classes; i++)
test_assert_std_string_equal(class_names[i], plt.class_names[i]);
for (int i = 0; i < plt.num_classes; i++)
test_assert_int_equal(vars_in_class[i], plt.vars_in_class[i]);
for (int i = 0; i < plt.num_classes; ++i) {
for (int k = 0; k < plt.vars_in_class[i]; ++k) {
test_assert_std_string_equal(var_names[i][k], plt.var_names[i][k]);
}
}
}
int main(int argc, char* argv[]) {
test_invalid_header1();
test_invalid_header2();
test_valid_header();
test_spe1_header(argv[1]);
return 0;
}

View File

@@ -53,13 +53,18 @@ struct log_struct {
static void log_delete_empty(const log_type * logh) {
if (logh->filename && util_file_exists( logh->filename ) ) {
size_t file_size = util_file_size( logh->filename );
if (file_size == 0)
remove( logh->filename );
}
}
void log_reopen(log_type *logh , const char *filename) {
if (logh->stream != NULL) { /* Close the existing file descriptor. */
size_t file_size;
fclose( logh->stream );
file_size = util_file_size( logh->filename );
if (file_size == 0)
remove( logh->filename ); /* Unlink the old log file if it had zero size. */
log_delete_empty( logh );
}
logh->filename = util_realloc_string_copy( logh->filename , filename );
@@ -234,6 +239,7 @@ void log_close( log_type * logh ) {
if ((logh->stream != stdout) && (logh->stream != stderr) && (logh->stream != NULL))
fclose( logh->stream ); /* This closes BOTH the FILE * stream and the integer file descriptor. */
log_delete_empty( logh );
util_safe_free( logh->filename );
free( logh );
}

View File

@@ -203,6 +203,12 @@ void rng_free( rng_type * rng) {
free( rng );
}
void rng_free__( void * arg) {
rng_type * rng = rng_safe_cast( arg );
rng_free( rng );
}
void rng_fprintf_state( rng_type * rng , FILE * stream ) {
rng->fprintf_state( rng->state , stream );
}

View File

@@ -25,7 +25,8 @@
#define LOG_FILE "log.txt"
int main(int argc , char ** argv) {
void test_open() {
test_work_area_type * work_area = test_work_area_alloc("util/logh");
{
log_type * logh = log_open( NULL , 0 );
@@ -52,5 +53,58 @@ int main(int argc , char ** argv) {
}
test_work_area_free( work_area );
}
void test_delete_empty() {
test_work_area_type * work_area = test_work_area_alloc("logh_delete_empty");
{
log_type * logh = log_open( LOG_FILE , 0 );
test_assert_not_NULL(logh);
log_close( logh );
test_assert_false( util_file_exists( LOG_FILE ));
}
{
log_type * logh = log_open( LOG_FILE , 0 );
log_reopen( logh , "LOG2.txt");
log_close( logh );
test_assert_false( util_file_exists( LOG_FILE ));
}
{
log_type * logh = log_open( LOG_FILE , 1 );
log_add_message( logh , 1 , NULL , "Message" , false);
log_close( logh );
test_assert_true( util_file_exists( LOG_FILE ));
logh = log_open( LOG_FILE , 1 );
log_close( logh );
test_assert_true( util_file_exists( LOG_FILE ));
}
test_work_area_free( work_area );
}
/*
Someone else deletes the file before closing - that should not kill the thing.
*/
void test_file_deleted() {
log_type * logh = log_open( LOG_FILE , 1 );
log_add_message( logh , 1 , NULL , "Message" , false);
util_unlink( LOG_FILE );
test_assert_false( util_file_exists( LOG_FILE ));
log_close( logh );
test_assert_false( util_file_exists( LOG_FILE ));
}
int main(int argc , char ** argv) {
test_open();
test_delete_empty();
test_file_deleted( );
exit(0);
}

View File

@@ -28,6 +28,7 @@ set(PYTHON_SOURCES
ecl_sum_var_type.py
ecl_type.py
ecl_grid_generator.py
cell.py
)
add_python_package("python.ecl.ecl" ${PYTHON_INSTALL_PREFIX}/ecl/ecl "${PYTHON_SOURCES}" True)

View File

@@ -86,6 +86,7 @@ class EclPrototype(Prototype):
ECL_LIB = ecl.load("libecl")
from .cell import Cell
from .ecl_util import EclFileEnum, EclFileFlagEnum, EclPhaseEnum, EclUnitTypeEnum , EclUtil
from .ecl_type import EclTypeEnum, EclDataType
from .ecl_sum_var_type import EclSumVarType

View File

@@ -0,0 +1,127 @@
#!/usr/bin/env python
# Copyright (C) 2017 Statoil ASA, Norway.
#
# This file is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
# for more details.
class Cell(object):
def __init__(self, grid, global_index):
self._grid = grid
self._idx = global_index
self._ijk = grid.get_ijk(global_index=self._idx)
self._aidx = grid.get_active_index(global_index=self._idx)
@property
def volume(self):
return self._grid.cell_volume(global_index=self._idx)
@property
def global_index(self):
return self._idx
@property
def active_index(self):
return self._aidx
@property
def ijk(self):
return self._ijk
@property
def i(self):
return self._ijk[0]
@property
def j(self):
return self._ijk[1]
@property
def k(self):
return self._ijk[2]
@property
def active(self):
return self._aidx >= 0
def eval(self, kw):
return self._grid.grid_value(kw, self.i, self.j, self.k)
@property
def fracture(self):
return self._grid.active_fracture_index(global_index=self._idx)
@property
def dz(self):
return self._grid.cell_dz(global_index=self._idx)
@property
def dimension(self):
return self._grid.get_cell_dims(global_index=self._idx)
@property
def valid_geometry(self):
return self._grid.valid_cell_geometry(global_index=self._idx)
@property
def valid(self):
return not self._grid.cell_invalid(global_index=self._idx)
def __contains__(self, coord):
"""
Will check if this cell contains point given by world
coordinates (x,y,z)=coord.
"""
if len(coord) != 3:
raise ValueError('Cell contains takes a triple (x,y,z), was given %s.' % coord)
x,y,z = coord
return self._grid._cell_contains(self._idx, x,y,z)
def __eq__(self, other):
if isinstance(other, Cell):
idx_eq = self.global_index == other.global_index
return idx_eq and self._grid == other._grid
return NotImplemented
def __neq__(self, other):
if isinstance(other, Cell):
return not self == other
return NotImplemented
def hash(self):
return hash((self._idx, self._aidx, self.ijk))
@property
def coordinate(self):
return self._grid.get_xyz(global_index=self._idx)
@property
def corners(self):
"""
Return xyz for each of the eight vertices, indexed by:
lower layer: upper layer
2---3 6---7
| | | |
0---1 4---5
"""
cs = lambda c : self._grid.get_cell_corner(c, global_index=self._idx)
return [cs(i) for i in range(8)]
def __repr__(self):
act = 'active' if self.active else 'inactive'
pos = '(%.3f, %.3f, %.3f)' % self.coordinate
cnt = '%d, %d, %d, %s, %s, grid=%s' % (self.i, self.j, self.k,
act, pos,
self._grid.get_name())
return 'Cell(%s)' % cnt

View File

@@ -34,7 +34,7 @@ import itertools
from cwrap import CFILE, BaseCClass
from ecl.util import monkey_the_camel
from ecl.util import IntVector
from ecl.ecl import EclPrototype, EclDataType, EclKW, FortIO, EclUnitTypeEnum
from ecl.ecl import EclPrototype, EclDataType, EclKW, FortIO, EclUnitTypeEnum, Cell
class EclGrid(BaseCClass):
@@ -386,6 +386,33 @@ class EclGrid(BaseCClass):
n = self._get_name()
return str(n) if n else ''
def cell(self, global_index=None, active_index=None, i=None, j=None, k=None):
if global_index is not None:
return Cell(self, global_index)
if active_index is not None:
return Cell(self, self.global_index(active_index=active_index))
if i is not None:
return Cell(self, self.global_index(ijk=(i,j,k)))
def __getitem__(self, global_index):
if isinstance(global_index, tuple):
i,j,k = global_index
return self.cell(i=i, j=j, k=k)
return self.cell(global_index=global_index)
def __iter__(self):
for i in range(len(self)):
yield self[i]
def cells(self, active=False):
"""Iterator over all the (active) cells"""
if not active:
for c in self:
yield c
else:
for i in range(self.get_num_active()):
yield self.cell(active_index=i)
def global_index(self, active_index=None, ijk=None):
"""
Will convert either active_index or (i,j,k) to global index.

View File

@@ -643,27 +643,30 @@ class EclKW(BaseCClass):
# No __rdiv__()
def sum(self):
def sum(self, mask = None, force_active = False):
"""
Will calculate the sum of all the elements in the keyword.
String: Raise ValueError exception.
Bool: The number of true values
"""
if self.data_type.is_int():
return self._int_sum()
elif self.data_type.is_float():
return self._float_sum()
elif self.data_type.is_double():
return self._float_sum()
elif self.data_type.is_bool():
sum = 0
for elm in self:
if elm:
sum += 1
return sum
else:
raise ValueError('The keyword "%s" is of string type - sum is not implemented' % self.getName())
if mask is None:
if self.data_type.is_int():
return self._int_sum()
elif self.data_type.is_float():
return self._float_sum()
elif self.data_type.is_double():
return self._float_sum()
elif self.data_type.is_bool():
sum = 0
for elm in self:
if elm:
sum += 1
return sum
else:
raise ValueError('The keyword "%s" is of string type - sum is not implemented' % self.getName())
return mask.sum_kw(self, force_active)
@@ -716,7 +719,7 @@ class EclKW(BaseCClass):
"""
if self.isNumeric():
if type(value) == type(self):
if mask:
if mask is not None:
mask.copy_kw(self, value, force_active)
else:
if self.assert_binary(value):
@@ -724,7 +727,7 @@ class EclKW(BaseCClass):
else:
raise TypeError("Type / size mismatch")
else:
if mask:
if mask is not None:
mask.set_kw(self, value, force_active)
else:
if self.data_type.is_int():
@@ -744,7 +747,7 @@ class EclKW(BaseCClass):
See method assign() for documentation of optional arguments
@mask and @force_active.
"""
if mask:
if mask is not None:
mask.iadd_kw(self, other, force_active)
else:
return self.__iadd__(other)
@@ -754,7 +757,7 @@ class EclKW(BaseCClass):
See method assign() for documentation of optional arguments
@mask and @force_active.
"""
if mask:
if mask is not None:
mask.isub_kw(self, other, force_active)
else:
return self.__isub__(other)
@@ -764,7 +767,7 @@ class EclKW(BaseCClass):
See method assign() for documentation of optional arguments
@mask and @force_active.
"""
if mask:
if mask is not None:
mask.imul_kw(self, other, force_active)
else:
return self.__imul__(other)
@@ -774,7 +777,7 @@ class EclKW(BaseCClass):
See method assign() for documentation of optional arguments
@mask and @force_active.
"""
if mask:
if mask is not None:
mask.idiv_kw(self, other, force_active)
else:
return self.__idiv__(other)
@@ -802,7 +805,7 @@ class EclKW(BaseCClass):
See method assign() for documentation of optional arguments
@mask and @force_active.
"""
if mask:
if mask is not None:
active_list = mask.kw_index_list(self, force_active)
if arg:
for index in active_list:
@@ -884,6 +887,10 @@ class EclKW(BaseCClass):
n = self._get_header()
return str(n) if n else ''
@name.setter
def name(self, value):
self.set_name(value)
def get_name(self):
return self.name

View File

@@ -89,6 +89,10 @@ class EclRegion(BaseCClass):
_scale_kw_int = EclPrototype("void ecl_region_scale_kw_int( ecl_region , ecl_kw , int, bool) ")
_scale_kw_float = EclPrototype("void ecl_region_scale_kw_float( ecl_region , ecl_kw , float, bool ) ")
_scale_kw_double = EclPrototype("void ecl_region_scale_kw_double( ecl_region , ecl_kw , double , bool) ")
_sum_kw_int = EclPrototype("int ecl_region_sum_kw_int( ecl_region , ecl_kw , bool) ")
_sum_kw_float = EclPrototype("float ecl_region_sum_kw_float( ecl_region , ecl_kw , bool ) ")
_sum_kw_double = EclPrototype("double ecl_region_sum_kw_double( ecl_region , ecl_kw , bool) ")
_sum_kw_bool = EclPrototype("int ecl_region_sum_kw_int( ecl_region , ecl_kw , bool) ")
_free = EclPrototype("void ecl_region_free( ecl_region )")
_reset = EclPrototype("void ecl_region_reset( ecl_region )")
@@ -202,13 +206,10 @@ class EclRegion(BaseCClass):
return self._alloc_copy( )
def __zero__(self):
global_list = self.getGlobalList()
if len(global_list) > 0:
return True
else:
return False
def __nonzero__(self):
global_list = self.get_global_list()
return len(global_list) > 0
def __iand__(self , other):
"""
@@ -944,6 +945,21 @@ class EclRegion(BaseCClass):
EclDataType.ECL_DOUBLE : self._set_kw_double} , force_active)
def sum_kw(self, kw, force_active = False):
data_type = kw.data_type
if data_type == EclDataType.ECL_FLOAT:
return self._sum_kw_float( kw, force_active )
if data_type == EclDataType.ECL_INT:
return self._sum_kw_int( kw, force_active )
if data_type == EclDataType.ECL_DOUBLE:
return self._sum_kw_double( kw, force_active )
if data_type == EclDataType.ECL_BOOL:
return self._sum_kw_bool( kw, force_active )
raise ValueError("sum_kw only supported for; INT/FLOAT/DOUBLE/BOOL")
#################################################################
@@ -955,6 +971,14 @@ class EclRegion(BaseCClass):
return True
def active_size(self):
return len(self._get_active_list())
def global_size(self):
return len(self._get_global_list())
def get_active_list(self):
"""
IntVector instance with active indices in the region.

View File

@@ -19,6 +19,7 @@ set(TEST_SOURCES
test_fortio.py
test_grdecl.py
test_grid.py
test_cell.py
test_grid_statoil.py
test_grid_generator.py
test_indexed_read.py
@@ -48,6 +49,7 @@ set(TEST_SOURCES
add_python_package("python.tests.ecl" ${PYTHON_INSTALL_PREFIX}/tests/ecl "${TEST_SOURCES}" False)
addPythonTest(tests.ecl.test_fk_user_data.FKTest)
addPythonTest(tests.ecl.test_cell.CellTest)
addPythonTest(tests.ecl.test_grid.GridTest LABELS SLOW_1)
addPythonTest(tests.ecl.test_grid_generator.GridGeneratorTest LABELS SLOW_2)
addPythonTest(tests.ecl.test_ecl_kw.KWTest LABELS SLOW_2)

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env python
# Copyright (C) 2017 Statoil ASA, Norway.
#
# This file is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
# for more details.
from ecl.ecl import Cell, EclGrid
from ecl.test import ExtendedTestCase
class CellTest(ExtendedTestCase):
def setUp(self):
fk = self.createTestPath('local/ECLIPSE/faarikaal/faarikaal1.EGRID')
self.grid = EclGrid(fk)
self.cell = self.grid[3455]
self.actives = [c for c in self.grid if c.active]
def test_init(self):
cell = self.grid[0]
self.assertEqual(0, cell.global_index)
def test_actives(self):
self.assertEqual(4160, len(self.actives))
def test_volumes(self):
actives = self.actives
vols = [c.volume for c in actives]
vmin, vmax = min(vols), max(vols)
self.assertFloatEqual(vmin, 1332.328921)
self.assertFloatEqual(vmax, 10104.83204)
self.assertFloatEqual(actives[2000].dz, 1.68506)
act_dim = (48.5676, 54.1515, 1.685) # cell dimension in meter
cel_dim = self.cell.dimension
self.assertEqual(3, len(cel_dim))
for d in range(2):
self.assertFloatEqual(act_dim[d], cel_dim[d])
def test_indices(self):
c = self.cell
self.assertEqual(3455, c.global_index)
self.assertEqual(2000, c.active_index)
self.assertEqual((4,1,82), c.ijk)
self.assertEqual(c.ijk, (c.i, c.j, c.k))
def test_coordinates(self):
c = self.cell
corners = c.corners
self.assertEqual(8, len(corners))
se0 = corners[5] # upper south east
se0_act = (606900.002, 5202050.07, 5149.26)
for i in range(3):
self.assertFloatEqual(se0[i], se0_act[i])
coordinate = c.coordinate
coor_act = (606866.883, 5202064.939, 5154.52)
for i in range(3):
self.assertFloatEqual(coordinate[i], coor_act[i])
xyz = c.coordinate
self.assertIn(xyz, c)
def test_eq(self):
c1 = self.cell
c2 = self.grid[4,1,82]
c3 = self.grid[1,1,82]
self.assertEqual(c1,c2)
self.assertEqual(c2,c1)
self.assertNotEqual(c1, 'notacell')
self.assertNotEqual(c1,c3)
self.assertNotEqual(c3,c1)
def test_getitem_3(self):
c = self.cell
d = self.grid[4,1,82]
self.assertEqual(c, d)
def test_validity(self):
self.assertTrue(self.cell.valid_geometry)
self.assertTrue(self.cell.valid)
def test_repr(self):
c = self.cell
r = repr(c)
self.assertTrue(r.startswith('Cell(4, 1, 82, active, '))
self.assertIn('faarikaal1.EGRID', r)

View File

@@ -1,27 +1,28 @@
#!/usr/bin/env python
# Copyright (C) 2011 Statoil ASA, Norway.
#
# Copyright (C) 2011 Statoil ASA, Norway.
#
# The file 'test_kw.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
# for more details.
import os
import random
import numpy
import warnings
from ecl.ecl import EclKW, EclDataType, EclTypeEnum, EclFile, FortIO, EclFileFlagEnum , openFortIO
from ecl.ecl import (EclKW, EclDataType, EclTypeEnum, EclFile, FortIO,
EclFileFlagEnum, openFortIO)
from ecl.test import ExtendedTestCase , TestAreaContext
from ecl.test import ExtendedTestCase, TestAreaContext
def copy_long():
@@ -36,17 +37,25 @@ def copy_offset():
class KWTest(ExtendedTestCase):
def test_name(self):
kw = EclKW('TEST', 3, EclDataType.ECL_INT)
self.assertEqual(kw.name, 'TEST')
self.assertIn('TEST', repr(kw))
kw.name = 'SCHMEST'
self.assertEqual(kw.name, 'SCHMEST')
self.assertIn('SCHMEST', repr(kw))
def test_min_max(self):
kw = EclKW("TEST", 3, EclDataType.ECL_INT)
kw[0] = 10
kw[1] = 5
kw[2] = 0
self.assertEqual( 10 , kw.getMax())
self.assertEqual( 0 , kw.getMin())
self.assertEqual( (0,10) , kw.getMinMax())
self.assertEqual(10, kw.getMax())
self.assertEqual(0 , kw.getMin())
self.assertEqual((0,10) , kw.getMinMax())
def test_deprecated_datatypes(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
@@ -64,7 +73,7 @@ class KWTest(ExtendedTestCase):
self.assertTrue(len(w) > 0)
self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
def kw_test( self, data_type, data, fmt ):
def kw_test(self, data_type, data, fmt):
name1 = "file1.txt"
name2 = "file2.txt"
kw = EclKW("TEST", len(data), data_type)
@@ -82,49 +91,49 @@ class KWTest(ExtendedTestCase):
file2.write(fmt % d)
file2.close()
self.assertFilesAreEqual(name1, name2)
self.assertEqual( kw.data_type , data_type )
self.assertEqual(kw.data_type, data_type)
def test_create(self):
with self.assertRaises(ValueError):
EclKW( "ToGodDamnLong" , 100 , EclDataType.ECL_CHAR )
EclKW("ToGodDamnLong", 100, EclDataType.ECL_CHAR)
def test_sum( self ):
def test_sum(self):
for ecl_type in [EclDataType.ECL_CHAR, EclDataType.ECL_STRING(42)]:
kw_string = EclKW("STRING", 100, ecl_type)
with self.assertRaises(ValueError):
kw_string.sum()
kw_int = EclKW( "INT" , 4 , EclDataType.ECL_INT )
kw_int = EclKW("INT", 4, EclDataType.ECL_INT)
kw_int[0] = 1
kw_int[1] = 2
kw_int[2] = 3
kw_int[3] = 4
self.assertEqual( kw_int.sum() , 10 )
self.assertEqual(kw_int.sum(), 10)
kw_d = EclKW( "D" , 4 , EclDataType.ECL_DOUBLE )
kw_d = EclKW("D", 4, EclDataType.ECL_DOUBLE)
kw_d[0] = 1
kw_d[1] = 2
kw_d[2] = 3
kw_d[3] = 4
self.assertEqual( kw_d.sum() , 10 )
self.assertEqual(kw_d.sum(), 10)
kw_f = EclKW( "F" , 4 , EclDataType.ECL_FLOAT )
kw_f = EclKW("F", 4, EclDataType.ECL_FLOAT)
kw_f[0] = 1
kw_f[1] = 2
kw_f[2] = 3
kw_f[3] = 4
self.assertEqual( kw_f.sum() , 10 )
self.assertEqual(kw_f.sum(), 10)
kw_b = EclKW( "F" , 4 , EclDataType.ECL_BOOL )
kw_b = EclKW("F", 4, EclDataType.ECL_BOOL)
kw_b[0] = False
kw_b[1] = True
kw_b[2] = False
kw_b[3] = True
self.assertEqual( kw_b.sum() , 2 )
self.assertEqual(kw_b.sum(), 2)
def test_fprintf( self ):
def test_fprintf(self):
with TestAreaContext("python.ecl_kw"):
self.kw_test(EclDataType.ECL_INT, [0, 1, 2, 3, 4, 5], "%4d\n")
self.kw_test(EclDataType.ECL_FLOAT, [0.0, 1.1, 2.2, 3.3, 4.4, 5.5], "%12.6f\n")
@@ -180,41 +189,41 @@ class KWTest(ExtendedTestCase):
def test_fprintf_data(self):
with TestAreaContext("kw_no_header"):
kw = EclKW("REGIONS" , 10 , EclDataType.ECL_INT)
kw = EclKW("REGIONS", 10, EclDataType.ECL_INT)
for i in range(len(kw)):
kw[i] = i
fileH = open("test" , "w")
kw.fprintf_data( fileH )
fileH = open("test", "w")
kw.fprintf_data(fileH)
fileH.close()
fileH = open("test" , "r")
fileH = open("test", "r")
data = []
for line in fileH.readlines():
tmp = line.split()
for elm in tmp:
data.append( int(elm) )
data.append(int(elm))
for (v1,v2) in zip(data,kw):
self.assertEqual(v1,v2)
def test_sliced_set(self):
kw = EclKW("REGIONS" , 10 , EclDataType.ECL_INT)
kw = EclKW("REGIONS", 10, EclDataType.ECL_INT)
kw.assign(99)
kw[0:5] = 66
self.assertEqual(kw[0] , 66)
self.assertEqual(kw[4] , 66)
self.assertEqual(kw[5] , 99)
self.assertEqual(kw[0], 66)
self.assertEqual(kw[4], 66)
self.assertEqual(kw[5], 99)
def test_long_name(self):
with self.assertRaises(ValueError):
EclKW("LONGLONGNAME" , 10 , EclDataType.ECL_INT)
EclKW("LONGLONGNAME", 10, EclDataType.ECL_INT)
kw = EclKW("REGIONS" , 10 , EclDataType.ECL_INT)
kw = EclKW("REGIONS", 10, EclDataType.ECL_INT)
with self.assertRaises(ValueError):
kw.setName("LONGLONGNAME")
kw.name = "LONGLONGNAME"
def test_abs(self):
@@ -223,99 +232,99 @@ class KWTest(ExtendedTestCase):
EclDataType.ECL_BOOL,
EclDataType.ECL_STRING(32)
]:
kw = EclKW("NAME" , 10 , ecl_type)
kw = EclKW("NAME", 10, ecl_type)
with self.assertRaises(TypeError):
abs_kw = abs(kw)
kw = EclKW("NAME" , 10 , EclDataType.ECL_INT)
kw = EclKW("NAME", 10, EclDataType.ECL_INT)
for i in range(len(kw)):
kw[i] = -i
abs_kw = abs(kw)
for i in range(len(kw)):
self.assertEqual(kw[i] , -i )
self.assertEqual(abs_kw[i] , i )
self.assertEqual(kw[i], -i)
self.assertEqual(abs_kw[i], i)
def test_fmt(self):
kw1 = EclKW( "NAME1" , 100 , EclDataType.ECL_INT)
kw2 = EclKW( "NAME2" , 100 , EclDataType.ECL_INT)
kw1 = EclKW("NAME1", 100, EclDataType.ECL_INT)
kw2 = EclKW("NAME2", 100, EclDataType.ECL_INT)
for i in range(len(kw1)):
kw1[i] = i + 1
kw2[i] = len(kw1) - kw1[i]
with TestAreaContext("ecl_kw/fmt") as ta:
with openFortIO( "TEST.FINIT" , FortIO.WRITE_MODE , fmt_file = True ) as f:
kw1.fwrite( f )
kw2.fwrite( f )
with openFortIO( "TEST.FINIT" , fmt_file = True ) as f:
kw1b = EclKW.fread( f )
kw2b = EclKW.fread( f )
with openFortIO("TEST.FINIT", FortIO.WRITE_MODE, fmt_file=True) as f:
kw1.fwrite(f)
kw2.fwrite(f)
self.assertTrue( kw1 == kw1b )
self.assertTrue( kw2 == kw2b )
with openFortIO("TEST.FINIT", fmt_file=True) as f:
kw1b = EclKW.fread(f)
kw2b = EclKW.fread(f)
f = EclFile( "TEST.FINIT" )
self.assertTrue( kw1 == f[0] )
self.assertTrue( kw2 == f[1] )
self.assertTrue(kw1 == kw1b)
self.assertTrue(kw2 == kw2b)
f = EclFile("TEST.FINIT")
self.assertTrue(kw1 == f[0])
self.assertTrue(kw2 == f[1])
def test_first_different(self):
kw1 = EclKW( "NAME1" , 100 , EclDataType.ECL_INT)
kw2 = EclKW( "NAME2" , 100 , EclDataType.ECL_INT)
kw3 = EclKW( "NAME2" , 200 , EclDataType.ECL_INT)
kw4 = EclKW( "NAME2" , 100 , EclDataType.ECL_FLOAT)
kw5 = EclKW( "NAME2" , 100 , EclDataType.ECL_FLOAT)
with self.assertRaises( IndexError ):
EclKW.firstDifferent( kw1 , kw2 , offset = 100 )
with self.assertRaises( ValueError ):
EclKW.firstDifferent( kw1 , kw3 )
with self.assertRaises( TypeError ):
EclKW.firstDifferent( kw1 , kw4 )
with self.assertRaises( IndexError ):
kw1.firstDifferent( kw2 , offset = 100 )
with self.assertRaises( ValueError ):
kw1.firstDifferent( kw3 )
with self.assertRaises( TypeError ):
kw1.firstDifferent( kw4 )
kw1 = EclKW("NAME1", 100, EclDataType.ECL_INT)
kw2 = EclKW("NAME2", 100, EclDataType.ECL_INT)
kw3 = EclKW("NAME2", 200, EclDataType.ECL_INT)
kw4 = EclKW("NAME2", 100, EclDataType.ECL_FLOAT)
kw5 = EclKW("NAME2", 100, EclDataType.ECL_FLOAT)
kw1.assign( 1 )
kw2.assign( 1 )
with self.assertRaises(IndexError):
EclKW.firstDifferent(kw1, kw2, offset=100)
self.assertEqual( kw1.firstDifferent( kw2 ) , len(kw1))
with self.assertRaises(ValueError):
EclKW.firstDifferent(kw1, kw3)
with self.assertRaises(TypeError):
EclKW.firstDifferent(kw1, kw4)
with self.assertRaises(IndexError):
kw1.firstDifferent(kw2, offset=100)
with self.assertRaises(ValueError):
kw1.firstDifferent(kw3)
with self.assertRaises(TypeError):
kw1.firstDifferent(kw4)
kw1.assign(1)
kw2.assign(1)
self.assertEqual(kw1.firstDifferent(kw2), len(kw1))
kw1[0] = 100
self.assertEqual( kw1.firstDifferent( kw2 ) , 0)
self.assertEqual( kw1.firstDifferent( kw2 , offset = 1) , len(kw1))
self.assertEqual(kw1.firstDifferent(kw2), 0)
self.assertEqual(kw1.firstDifferent(kw2, offset=1), len(kw1))
kw1[10] = 100
self.assertEqual( kw1.firstDifferent( kw2 , offset = 1) , 10)
self.assertEqual(kw1.firstDifferent(kw2, offset=1), 10)
kw4.assign( 1.0 )
kw5.assign( 1.0 )
self.assertEqual( kw4.firstDifferent( kw5 ) , len(kw4))
kw4.assign(1.0)
kw5.assign(1.0)
self.assertEqual(kw4.firstDifferent(kw5), len(kw4))
kw4[10] *= 1.0001
self.assertEqual( kw4.firstDifferent( kw5 ) , 10)
self.assertEqual(kw4.firstDifferent(kw5), 10)
self.assertEqual(kw4.firstDifferent(kw5, epsilon=1.0), len(kw4))
self.assertEqual(kw4.firstDifferent(kw5, epsilon=0.0000001), 10)
self.assertEqual( kw4.firstDifferent( kw5 , epsilon = 1.0) , len(kw4))
self.assertEqual( kw4.firstDifferent( kw5 , epsilon = 0.0000001) , 10)
def test_numeric_equal(self):
kw1 = EclKW("Name1" , 10 , EclDataType.ECL_DOUBLE )
kw2 = EclKW("Name1" , 10 , EclDataType.ECL_DOUBLE )
kw1 = EclKW("Name1", 10, EclDataType.ECL_DOUBLE)
kw2 = EclKW("Name1", 10, EclDataType.ECL_DOUBLE)
shift = 0.0001
@@ -323,46 +332,46 @@ class KWTest(ExtendedTestCase):
abs_diff = shift
rel_diff = shift / (shift + 2* value)
kw1.assign( value )
kw2.assign( value + shift )
kw1.assign(value)
kw2.assign(value + shift)
self.assertTrue( kw1.equal_numeric( kw2 , abs_epsilon = abs_diff * 1.1 , rel_epsilon = rel_diff * 1.1))
self.assertFalse( kw1.equal_numeric( kw2 , abs_epsilon = abs_diff * 1.1 , rel_epsilon = rel_diff * 0.9))
self.assertFalse( kw1.equal_numeric( kw2 , abs_epsilon = abs_diff * 0.9 , rel_epsilon = rel_diff * 1.1))
self.assertTrue( kw1.equal_numeric( kw2 , abs_epsilon = 0 , rel_epsilon = rel_diff * 1.1))
self.assertTrue( kw1.equal_numeric( kw2 , abs_epsilon = abs_diff * 1.1 , rel_epsilon = 0))
self.assertTrue( kw1.equal_numeric(kw2, abs_epsilon=abs_diff * 1.1, rel_epsilon=rel_diff * 1.1))
self.assertFalse(kw1.equal_numeric(kw2, abs_epsilon=abs_diff * 1.1, rel_epsilon=rel_diff * 0.9))
self.assertFalse(kw1.equal_numeric(kw2, abs_epsilon=abs_diff * 0.9, rel_epsilon=rel_diff * 1.1))
self.assertTrue( kw1.equal_numeric(kw2, abs_epsilon=0, rel_epsilon=rel_diff * 1.1))
self.assertTrue( kw1.equal_numeric(kw2, abs_epsilon=abs_diff * 1.1, rel_epsilon=0))
def test_mul(self):
kw1 = EclKW("Name1" , 10 , EclDataType.ECL_INT )
kw1.assign( 10 )
kw1 = EclKW("Name1", 10, EclDataType.ECL_INT)
kw1.assign(10)
kw2 = EclKW("Name1" , 10 , EclDataType.ECL_INT )
kw2.assign( 2 )
kw2 = EclKW("Name1", 10, EclDataType.ECL_INT)
kw2.assign(2)
kw3 = kw1 * kw2
kw4 = kw1 + kw2
self.assertEqual( len(kw3) , len(kw1))
self.assertEqual( len(kw4) , len(kw1))
self.assertEqual(len(kw3), len(kw1))
self.assertEqual(len(kw4), len(kw1))
for v in kw3:
self.assertEqual( v , 20 )
self.assertEqual(v, 20)
for v in kw4:
self.assertEqual( v , 12 )
self.assertEqual(v, 12)
def test_numpy(self):
kw1 = EclKW("DOUBLE", 10, EclDataType.ECL_DOUBLE )
view = kw1.numpyView( )
copy = kw1.numpyCopy( )
kw1 = EclKW("DOUBLE", 10, EclDataType.ECL_DOUBLE)
self.assertTrue( copy[ 0 ] == kw1[ 0 ] )
self.assertTrue( view[ 0 ] == kw1[ 0 ] )
view = kw1.numpyView()
copy = kw1.numpyCopy()
self.assertTrue(copy[ 0 ] == kw1[ 0 ])
self.assertTrue(view[ 0 ] == kw1[ 0 ])
kw1[ 0 ] += 1
self.assertTrue( view[ 0 ] == kw1[ 0 ] )
self.assertTrue( copy[ 0 ] == kw1[ 0 ] - 1)
self.assertTrue(view[ 0 ] == kw1[ 0 ])
self.assertTrue(copy[ 0 ] == kw1[ 0 ] - 1)
for ecl_type in [
EclDataType.ECL_CHAR,
@@ -374,45 +383,45 @@ class KWTest(ExtendedTestCase):
def test_slice(self):
N = 100
kw = EclKW("KW" , N , EclDataType.ECL_INT)
kw = EclKW("KW", N, EclDataType.ECL_INT)
for i in range(len(kw)):
kw[i] = i
even = kw[0:len(kw):2]
odd = kw[1:len(kw):2]
self.assertEqual( len(even) , N/2 )
self.assertEqual( len(odd) , N/2 )
self.assertEqual(len(even), N/2)
self.assertEqual(len(odd) , N/2)
for i in range(len(even)):
self.assertEqual(even[i] , 2*i)
self.assertEqual(odd[i] , 2*i + 1)
self.assertEqual(even[i], 2*i)
self.assertEqual(odd[i], 2*i + 1)
def test_resize(self):
N = 4
kw = EclKW("KW" , N , EclDataType.ECL_INT)
kw = EclKW("KW", N, EclDataType.ECL_INT)
for i in range(N):
kw[i] = i
kw.resize( 2*N )
self.assertEqual( len(kw) , 2*N )
kw.resize(2*N)
self.assertEqual(len(kw), 2*N)
for i in range(N):
self.assertEqual( kw[i] , i )
self.assertEqual(kw[i], i)
kw.resize( N/2 )
self.assertEqual( len(kw) , N/2 )
kw.resize(N/2)
self.assertEqual(len(kw), N/2)
for i in range(N/2):
self.assertEqual( kw[i] , i )
self.assertEqual(kw[i], i)
def test_typename(self):
kw = EclKW("KW" , 100 , EclDataType.ECL_INT)
kw = EclKW("KW", 100, EclDataType.ECL_INT)
self.assertEqual( kw.typeName( ) , "INTE")
self.assertEqual(kw.typeName(), "INTE")
def test_string_alloc(self):
kw = EclKW("KW" , 10, EclDataType.ECL_STRING(30))
kw = EclKW("KW", 10, EclDataType.ECL_STRING(30))
for i in range(10):
kw[i] = str(i)*30
@@ -424,7 +433,7 @@ class KWTest(ExtendedTestCase):
for str_len in range(1000):
with TestAreaContext("my_space"):
kw = EclKW("TEST_KW" , 10, EclDataType.ECL_STRING(str_len))
kw = EclKW("TEST_KW", 10, EclDataType.ECL_STRING(str_len))
for i in range(10):
kw[i] = str(i)*str_len
@@ -442,7 +451,7 @@ class KWTest(ExtendedTestCase):
for str_len in range(1000):
with TestAreaContext("my_space"):
kw = EclKW("TEST_KW" , 10, EclDataType.ECL_STRING(str_len))
kw = EclKW("TEST_KW", 10, EclDataType.ECL_STRING(str_len))
for i in range(10):
kw[i] = str(i)*str_len
@@ -455,12 +464,12 @@ class KWTest(ExtendedTestCase):
self.assertEqual(kw, loaded_kw)
def test_string_padding(self):
kw = EclKW("TEST_KW" , 1 , EclDataType.ECL_STRING(4))
kw[0] = "AB"
self.assertEqual( kw[0] , "AB " )
kw = EclKW("TEST_KW" , 1 , EclDataType.ECL_CHAR)
def test_string_padding(self):
kw = EclKW("TEST_KW", 1, EclDataType.ECL_STRING(4))
kw[0] = "AB"
self.assertEqual(kw[0], "AB ")
kw = EclKW("TEST_KW", 1, EclDataType.ECL_CHAR)
kw[0] = "ABCD"
self.assertEqual( kw[0] , "ABCD " )
self.assertEqual(kw[0], "ABCD ")

View File

@@ -1,18 +1,18 @@
#!/usr/bin/env python
# Copyright (C) 2014 Statoil ASA, Norway.
#
# Copyright (C) 2014 Statoil ASA, Norway.
#
# The file 'test_grid.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
# for more details.
import os.path
from unittest import skipIf
@@ -120,7 +120,7 @@ def average(points):
# external test data. Tests involving Statoil test data are in the
# test_grid_statoil module.
class GridTest(ExtendedTestCase):
def test_oom_grid(self):
nx = 2000
ny = 2000
@@ -130,7 +130,7 @@ class GridTest(ExtendedTestCase):
grid = GridGen.createRectangular( (nx,ny,nz), (1,1,1))
def test_posXYEdge(self):
nx = 10
ny = 11
@@ -139,44 +139,67 @@ class GridTest(ExtendedTestCase):
self.assertEqual( grid.findCellCornerXY(nx,0,0) , nx)
self.assertEqual( grid.findCellCornerXY(0 , ny , 0) , (nx + 1 ) * ny )
self.assertEqual( grid.findCellCornerXY(nx,ny,0) , (nx + 1 ) * (ny + 1) - 1)
self.assertEqual( grid.findCellCornerXY(0.25,0,0) , 0 )
self.assertEqual( grid.findCellCornerXY(0,0.25,0) , 0 )
self.assertEqual( grid.findCellCornerXY(nx - 0.25,0,0) , nx )
self.assertEqual( grid.findCellCornerXY(nx , 0.25,0) , nx )
self.assertEqual( grid.findCellCornerXY(0 , ny - 0.25, 0) , (nx + 1 ) * ny )
self.assertEqual( grid.findCellCornerXY(0.25 , ny , 0) , (nx + 1 ) * ny )
self.assertEqual( grid.findCellCornerXY(nx -0.25 ,ny,0) , (nx + 1 ) * (ny + 1) - 1)
self.assertEqual( grid.findCellCornerXY(nx , ny - 0.25,0) , (nx + 1 ) * (ny + 1) - 1)
def test_dims(self):
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) )
self.assertEqual( grid.getNX() , 10 )
self.assertEqual( grid.getNY() , 20 )
self.assertEqual( grid.getNZ() , 30 )
self.assertEqual( grid.getGlobalSize() , 30*10*20 )
self.assertEqual( grid.getDims() , (10,20,30,6000) )
def test_create(self):
with self.assertRaises(ValueError):
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) , actnum = [0,1,1,2])
with self.assertRaises(ValueError):
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) , actnum = IntVector(initial_size = 10))
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) ) # actnum=None -> all active
self.assertEqual( grid.getNumActive( ) , 30*20*10)
actnum = IntVector(default_value = 1 , initial_size = 6000)
actnum[0] = 0
actnum[1] = 0
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) , actnum = actnum)
self.assertEqual( grid.getNumActive( ) , 30*20*10 - 2)
def test_all_iters(self):
fk = self.createTestPath('local/ECLIPSE/faarikaal/faarikaal1.EGRID')
grid = EclGrid(fk)
cell = grid[3455]
self.assertEqual(3455, cell.global_index)
cell = grid[(4,1,82)]
self.assertEqual(3455, cell.global_index)
self.assertEqual(grid.cell(global_index=3455),
grid.cell(active_index=2000))
self.assertEqual(grid.cell(global_index=3455),
grid.cell(i=4, j=1, k=82))
na = grid.get_num_active()
self.assertEqual(na, 4160)
cnt = 0
for c in grid.cells(active=True):
cnt += 1
self.assertTrue(c.active)
self.assertEqual(cnt, 4160)
cnt = len([c for c in grid.cells()])
self.assertEqual(cnt, len(grid))
def test_repr_and_name(self):
grid = GridGen.createRectangular((2,2,2), (10,10,10), actnum=[0,0,0,0,1,1,1,1])
pfx = 'EclGrid('
@@ -196,101 +219,101 @@ class GridTest(ExtendedTestCase):
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) )
with self.assertRaises(IndexError):
grid.getNodePos(-1,0,0)
with self.assertRaises(IndexError):
grid.getNodePos(11,0,0)
p0 = grid.getNodePos(0,0,0)
self.assertEqual( p0 , (0,0,0))
p7 = grid.getNodePos(10,20,30)
self.assertEqual( p7 , (10,20,30))
def test_truncated_file(self):
grid = GridGen.createRectangular( (10,20,30) , (1,1,1) )
with TestAreaContext("python/ecl_grid/truncated"):
grid.save_EGRID( "TEST.EGRID")
size = os.path.getsize( "TEST.EGRID")
with open("TEST.EGRID" , "r+") as f:
f.truncate( size / 2 )
with self.assertRaises(IOError):
EclGrid("TEST.EGRID")
def test_posXY1(self):
nx = 4
ny = 1
nz = 1
grid = GridGen.createRectangular( (nx,ny,nz) , (1,1,1) )
(i,j) = grid.findCellXY( 0.5 , 0.5, 0 )
(i,j) = grid.findCellXY( 0.5 , 0.5, 0 )
self.assertEqual(i , 0)
self.assertEqual(j , 0)
(i,j) = grid.findCellXY( 3.5 , 0.5, 0 )
(i,j) = grid.findCellXY( 3.5 , 0.5, 0 )
self.assertEqual(i , 3)
self.assertEqual(j , 0)
def test_init_ACTNUM(self):
nx = 10
ny = 23
nz = 7
grid = GridGen.createRectangular( (nx,ny,nz) , (1,1,1) )
actnum = grid.exportACTNUM()
self.assertEqual( len(actnum) , nx*ny*nz )
self.assertEqual( actnum[0] , 1 )
self.assertEqual( actnum[nx*ny*nz - 1] , 1 )
actnum_kw = grid.exportACTNUMKw( )
self.assertEqual(len(actnum_kw) , len(actnum))
for a1,a2 in zip(actnum, actnum_kw):
self.assertEqual(a1, a2)
def test_posXY(self):
nx = 10
ny = 23
nz = 7
grid = GridGen.createRectangular( (nx,ny,nz) , (1,1,1) )
with self.assertRaises(IndexError):
grid.findCellXY( 1 , 1, -1 )
grid.findCellXY( 1 , 1, -1 )
with self.assertRaises(IndexError):
grid.findCellXY( 1 , 1, nz + 1 )
grid.findCellXY( 1 , 1, nz + 1 )
with self.assertRaises(ValueError):
grid.findCellXY(15 , 78 , 2)
i,j = grid.findCellXY( 1.5 , 1.5 , 2 )
self.assertEqual(i , 1)
self.assertEqual(j , 1)
for i in range(nx):
for j in range(ny):
p = grid.findCellXY(i + 0.5 , j+ 0.5 , 0)
self.assertEqual( p[0] , i )
self.assertEqual( p[1] , j )
c = grid.findCellCornerXY( 0.10 , 0.10 , 0 )
self.assertEqual(c , 0)
c = grid.findCellCornerXY( 0.90 , 0.90 , 0 )
self.assertEqual( c , (nx + 1) + 1 )
c = grid.findCellCornerXY( 0.10 , 0.90 , 0 )
self.assertEqual( c , (nx + 1) )
c = grid.findCellCornerXY( 0.90 , 0.90 , 0 )
self.assertEqual( c , (nx + 1) + 1 )
c = grid.findCellCornerXY( 0.90 , 0.10 , 0 )
self.assertEqual( c , 1 )
def test_compressed_copy(self):
nx = 10
ny = 10
@@ -299,19 +322,19 @@ class GridTest(ExtendedTestCase):
kw1 = EclKW("KW" , 1001 , EclDataType.ECL_INT )
with self.assertRaises(ValueError):
cp = grid.compressedKWCopy( kw1 )
def test_dxdydz(self):
nx = 10
ny = 10
nz = 10
grid = GridGen.createRectangular( (nx,ny,nz) , (2,3,4) )
(dx,dy,dz) = grid.getCellDims( active_index = 0 )
self.assertEqual( dx , 2 )
self.assertEqual( dy , 3 )
self.assertEqual( dz , 4 )
def test_numpy3D(self):
nx = 10
ny = 7
@@ -329,7 +352,7 @@ class GridTest(ExtendedTestCase):
actnum[1] = 1
actnum[2] = 1
actnum[3] = 1
grid = GridGen.createRectangular( (nx,ny,nz) , (1,1,1), actnum = actnum)
self.assertEqual( len(grid) , nx*ny*nz )
self.assertEqual( grid.getNumActive( ) , 4 )
@@ -357,12 +380,12 @@ class GridTest(ExtendedTestCase):
g2 = EclGrid("CASE.EGRID")
self.assertFloatEqual( g2.cell_volume( global_index = 0 ) , 3.28084*3.28084*3.28084)
grid.save_EGRID( "CASE.EGRID" )
f = EclFile("CASE.EGRID")
g = f["GRIDUNIT"][0]
self.assertEqual( g[0].strip( ) , "METRES" )
grid.save_EGRID( "CASE.EGRID" , output_unit = EclUnitTypeEnum.ECL_LAB_UNITS)
f = EclFile("CASE.EGRID")
g = f["GRIDUNIT"][0]

View File

@@ -1,23 +1,22 @@
#!/usr/bin/env python
# Copyright (C) 2017 Statoil ASA, Norway.
#
# Copyright (C) 2017 Statoil ASA, Norway.
#
# The file 'test_region.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
#
# ERT 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.
#
# ERT 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 at <http://www.gnu.org/licenses/gpl.html>
# for more details.
from ecl.ecl import EclGrid, EclKW, EclRegion, EclDataType
from ecl.ecl.faults import Layer
from ecl.test import ExtendedTestCase
from ecl.util import IntVector
class RegionTest(ExtendedTestCase):
@@ -35,3 +34,56 @@ class RegionTest(ExtendedTestCase):
with self.assertRaises(ValueError):
region.select_equal( kw_float , 1 )
def test_sum(self):
grid = EclGrid.createRectangular( (10,10,1) , (1,1,1))
kw_mask = EclKW( "INT" , grid.getGlobalSize( ) , EclDataType.ECL_INT )
int_value = EclKW( "INT" , grid.getGlobalSize( ) , EclDataType.ECL_INT )
float_value = EclKW( "FLOAT" , grid.getGlobalSize( ) , EclDataType.ECL_FLOAT)
double_value = EclKW( "DOUBLE" , grid.getGlobalSize( ) , EclDataType.ECL_DOUBLE )
bool_value = EclKW( "BOOL" , grid.getGlobalSize( ) , EclDataType.ECL_BOOL )
kw_mask[0:50] = 1
for i in range(len(int_value)):
float_value[i] = i
double_value[i] = i
int_value[i] = i
bool_value[i] = True
region = EclRegion(grid, False)
region.select_equal( kw_mask , 1 )
self.assertEqual( int_value.sum( ) , 99*100/2 )
self.assertEqual( int_value.sum( mask = region ) , 49*50/2 )
self.assertEqual( double_value.sum( mask = region ) , 1.0*49*50/2 )
self.assertEqual( float_value.sum( mask = region ) , 1.0*49*50/2 )
self.assertEqual( bool_value.sum( mask = region ) , 50 )
def test_truth_and_size(self):
actnum = IntVector( initial_size = 100, default_value = 0)
actnum[0:50] = 1
grid = EclGrid.createRectangular( (10,10,1) , (1,1,1), actnum = actnum)
region = EclRegion(grid, False)
self.assertFalse( region )
self.assertEqual( 0, region.active_size( ))
self.assertEqual( 0, region.global_size( ))
region.select_all( )
self.assertTrue( region )
self.assertEqual( 50, region.active_size( ))
self.assertEqual( 100, region.global_size( ))
region.deselect_all()
self.assertFalse( region )
self.assertEqual( 0, region.active_size( ))
self.assertEqual( 0, region.global_size( ))
region = EclRegion(grid, False)
region.select_inactive()
self.assertTrue( region )
self.assertEqual( 0 , region.active_size( ))
self.assertEqual( 50, region.global_size( ))

View File

@@ -1,5 +1,73 @@
Version 2.2.0 September 2017 PR: 1 - 169
Open PR: 108, 145
Grid:
- Extracted implementation ecl_nnc_geometry [1, 66, 75, 78, 80, 109].
- Fix bug in cell_contains for mirrored grid [51, 53].
- Extract subgrid from grid [56].
- Expose mapaxes [63, 64].
- grid.get_lgr - numbered lookup [83]
- Added NUMRES values to EGRID header [125].
Build & testing:
- Removed warnings - added pylint [4, 5, 6, 10, 11, 12]
- Accept any Python 2.7.x version [17, 18]
- Remove ERT testing & building [3, 19]
- Changes to Python/cmake machinery [25, 30, 31, 32, 49, 52, 62].
- Added cmake config file [33, 44, 45, 47].
- Only *one* library [54, 55, 58, 69, 73, 77, 91, 133]
- Removed stale binaries [59].
- Require cmake >= 2.8.12 [67].
- Fix build on OSX [87, 88, 95, 103].
- Fix broken behavior with internal test data [97].
- Travis - compile with -Werror [122, 123, 127, 130]
- Started to support Python3 syntax [150, 161]
- Add support for paralell builds on Travis [149]
libecl now fully supports OSX. On Travis it is compiled with
-Werror=all which should protect against future warnings.
C++:
- Removed use of deignated initializers [7].
- Memory leak in EclFilename.cpp [14].
- Guarantee C linkage for ecl_data_type [65].
- New smspec overload [89].
- Use -std=c++0x if -std=c++11 is unavailable [118]
- Make all of (previous( libutil compile with C++ [162]
Well:
- Get well rates from restart files [8,20].
- Test if file exists before load [111].
- Fix some warnings [169]
Core:
- Support for variable length strings in binary eclipse files [13, 146].
- Renamed root package ert -> ecl [21]
- Load INTERSECT summary files with NAMES instead WGNAMES [34 - 39].
- Possible memory leak: [61]
- Refactored binary time search in __get_index_from_sim_time() [113]
- Possible to mark fortio writer as "failed" - will unlink on close [119].
- Allow keywords of more than 8 characters [120, 124].
- ecl_sum writer: Should write RESTART keyword [129, 131]
- Made EclVersion class [160]
- Functionality to dump an index file for binary files: [155, 159, 163, 166, 167]
Misc:
- Added legacy pacakge ert/ [48, 99]
- Improved logging - adding enums for og levels [90, 140, 141]
- Refactored to use snake_case instead of CamelCase [144, 145]
-----------------------------------------------------------------
Version 2.1.0 February 2017 PR: 1150 - 1415
Open PR: 1352, 1358, 1362
Open PR: 1352, 1358, 1362
Queue system/workflows:

View File

@@ -4,36 +4,32 @@ import json
import os
import sys
closed_pr = set( [1197 , 1201, 1235, 1244, 1245, 1252, 1261, 1262, 1366,
1357, 1282, 1279, 1267, 1273, 1305, 1312, 1313, 1339 , 1346,
1354, 1370,1371, 1381])
url_fmt = "https://api.github.com/repos/Statoil/libecl/pulls/%d"
def getPRList( api_token, first_pr ):
pr = first_pr
def getPRList( api_token, pr1, pr2):
pr = pr1
pr_list = []
prev_len = 0
sys.stderr.write("Downloading PR: ")
while True:
if pr in closed_pr:
pr += 1
else:
url = "https://api.github.com/repos/Ensembles/ert/pulls/%d" % pr
response = requests.get( url , {"access_token" : api_token})
for i in range(prev_len):
sys.stdout.write("\b")
url = url_fmt % pr
response = requests.get( url , {"access_token" : api_token})
for i in range(prev_len):
sys.stdout.write("\b")
sys.stdout.write("%d" % pr )
sys.stdout.flush()
prev_len = len("%s" % pr)
if response.status_code == 200:
pr_list.append( json.loads( response.content ) )
pr += 1
if pr > pr2:
break
sys.stdout.write("%d" % pr )
sys.stdout.flush()
prev_len = len("%s" % pr)
if response.status_code == 200:
pr_list.append( json.loads( response.content ) )
pr += 1
else:
break
return pr_list
@@ -42,7 +38,7 @@ def printPRList( pr_list , fileH):
title = pr["title"]
body = pr["body"]
nr = pr["number"]
try:
fileH.write( "[%d] *%s*\n\n" % (nr , title))
except UnicodeEncodeError:
@@ -61,8 +57,8 @@ def main():
sys.exit("You must create a github access token and set the environment variable 'GITHUB_API_TOKEN' to proceed")
pr1 = int(sys.argv[1])
pr_list = getPRList( github_api_token, pr1)
pr2 = pr_list[-1]["number"]
pr2 = int(sys.argv[2])
pr_list = getPRList( github_api_token, pr1, pr2)
filename = "/tmp/relnotes-%d-%d" % (pr1 , pr2)
printPRList( pr_list , open(filename , "w"))
@@ -71,7 +67,7 @@ def main():
if __name__ == "__main__":
main( )

Binary file not shown.