From 04091ad77d0580292c30796f7080618f80930f21 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 7 May 2019 07:15:25 +0200 Subject: [PATCH] #4266 Update libecl Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020 Excluded multibuild folder, as this caused git issues --- ThirdParty/Ert/.github/CODEOWNERS | 2 + .../Ert/.github/PULL_REQUEST_TEMPLATE.md | 9 +- ThirdParty/Ert/.gitignore | 3 +- ThirdParty/Ert/.gitmodules | 3 + ThirdParty/Ert/.travis.yml | 104 +- ThirdParty/Ert/CMakeLists.txt | 31 +- ThirdParty/Ert/README.md | 9 +- ThirdParty/Ert/WINDOWS.md | 27 + ThirdParty/Ert/Windows.txt | 90 - ThirdParty/Ert/applications/CMakeLists.txt | 24 +- ThirdParty/Ert/applications/ecl/convert.c | 2 +- ThirdParty/Ert/applications/ecl/ecl_pack.c | 2 +- .../Ert/applications/ecl/ecl_quantile.c | 3 +- ThirdParty/Ert/applications/ecl/ecl_unpack.c | 2 +- ThirdParty/Ert/applications/ecl/grdecl_grid.c | 2 +- ThirdParty/Ert/applications/ecl/grdecl_test.c | 2 +- ThirdParty/Ert/applications/ecl/grid_dump.c | 2 +- .../Ert/applications/ecl/grid_dump_ascii.c | 2 +- ThirdParty/Ert/applications/ecl/grid_info.c | 2 +- ThirdParty/Ert/applications/ecl/grid_layer.c | 2 +- ThirdParty/Ert/applications/ecl/key_list.c | 2 +- .../ecl/{kw_extract.c => kw_extract.cpp} | 2 +- ThirdParty/Ert/applications/ecl/kw_list.c | 2 +- ThirdParty/Ert/applications/ecl/load_test.c | 2 +- ThirdParty/Ert/applications/ecl/make_grid.c | 2 +- ThirdParty/Ert/applications/ecl/run_gravity.c | 2 +- ThirdParty/Ert/applications/ecl/select_test.c | 2 +- .../ecl/{sum_write.c => sum_write.cpp} | 12 +- .../Ert/applications/ecl/summary2csv2.c | 2 +- .../Ert/applications/ecl/view_restart.c | 2 +- ThirdParty/Ert/applications/ecl/view_rft.c | 2 +- .../ecl/{view_summary.c => view_summary.cpp} | 7 +- ThirdParty/Ert/applications/ecl/vprofile.c | 2 +- .../Ert/applications/man/man1/ecl_summary.1 | 5 +- .../Ert/applications/well/ri_well_test.c | 2 +- .../Ert/applications/well/segment_info.c | 2 +- .../Ert/applications/well/well_CF_dump.c | 2 +- ThirdParty/Ert/appveyor.yml | 1 - ThirdParty/Ert/bin/summary_resample | 6 +- ThirdParty/Ert/config.sh | 0 ThirdParty/Ert/debian/README.Debian | 4 - ThirdParty/Ert/debian/changelog | 2 +- ThirdParty/Ert/debian/copyright | 2 +- ThirdParty/Ert/docs/CMakeLists.txt | 38 - ThirdParty/Ert/docs/code/C/index.rst | 4 - .../docs/code/python/eclipse/API/index.rst | 9 - .../docs/code/python/examples/ert/index.rst | 3 - .../code/python/packages/geometry/index.rst | 2 - .../docs/code/python/packages/util/index.rst | 2 - .../docs/code/python/packages/well/index.rst | 2 - ThirdParty/Ert/docs/course/config/config.ert | 34 - .../docs/course/config/jobs/SNAKE_OIL_DIFF | 4 - .../Ert/docs/course/config/jobs/SNAKE_OIL_NPV | 4 - .../course/config/jobs/SNAKE_OIL_SIMULATOR | 4 - .../docs/course/config/jobs/snake_oil_diff.py | 24 - .../docs/course/config/jobs/snake_oil_npv.py | 103 - .../course/config/jobs/snake_oil_simulator.py | 185 -- .../parameters/snake_oil_parameters.txt | 11 - .../config/refcase/SNAKE_OIL_FIELD.SMSPEC | Bin 1416 -> 0 bytes .../config/refcase/SNAKE_OIL_FIELD.UNSMRY | Bin 455200 -> 0 bytes .../course/config/refcase/refcase_readme.txt | 1 - .../Ert/docs/course/config/refcase/seed.txt | 1 - .../config/refcase/snake_oil_params.txt | 10 - .../docs/course/config/refcase/time_map.txt | 2000 ----------------- .../Ert/docs/course/config/snake_oil.ert | 40 - .../course/config/templates/seed_template.txt | 1 - .../config/templates/snake_oil_template.txt | 10 - ThirdParty/Ert/docs/course/ex1/ex1.txt | 7 - ThirdParty/Ert/docs/course/ex1/sol1.py | 27 - ThirdParty/Ert/docs/course/ex2/ex2.txt | 1 - ThirdParty/Ert/docs/course/ex2/sol2.txt | 35 - ThirdParty/Ert/docs/course/ex3/ex3.txt | 2 - ThirdParty/Ert/docs/course/ex3/sol3.py | 17 - ThirdParty/Ert/docs/course/ex4/ex4.txt | 13 - ThirdParty/Ert/docs/course/ex4/sol4.py | 71 - ThirdParty/Ert/docs/doxygen.cfg.in | 42 - ThirdParty/Ert/docs/eclipse_restart_spe1.txt | 109 - .../docs/eclipse_restart_specification.txt | 268 --- ThirdParty/Ert/docs/nexus.plt | 51 - ThirdParty/Ert/install/install.py | 2 +- ThirdParty/Ert/lib/CMakeLists.txt | 93 +- ThirdParty/Ert/lib/ecl/EclFilename.cpp | 2 +- ThirdParty/Ert/lib/ecl/FortIO.cpp | 2 +- ThirdParty/Ert/lib/ecl/Smspec.cpp | 120 - ThirdParty/Ert/lib/ecl/ecl_box.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_file.cpp | 7 +- ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp | 4 +- ThirdParty/Ert/lib/ecl/ecl_file_view.cpp | 137 +- ThirdParty/Ert/lib/ecl/ecl_grav.cpp | 111 +- ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_grid.cpp | 60 +- ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_init_file.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_io_config.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_kw.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_nnc_export.cpp | 74 +- ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp | 10 +- ThirdParty/Ert/lib/ecl/ecl_region.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp | 8 +- ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp | 120 +- ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp | 103 +- ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp | 12 +- ThirdParty/Ert/lib/ecl/ecl_smspec.cpp | 1070 ++++----- ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp | 63 +- ThirdParty/Ert/lib/ecl/ecl_sum.cpp | 195 +- ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp | 59 +- ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp | 11 +- ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp | 71 +- ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp | 62 +- ThirdParty/Ert/lib/ecl/ecl_type.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp | 2 +- ThirdParty/Ert/lib/ecl/ecl_util.cpp | 4 +- ThirdParty/Ert/lib/ecl/fault_block.cpp | 2 +- ThirdParty/Ert/lib/ecl/fault_block_layer.cpp | 4 +- ThirdParty/Ert/lib/ecl/fortio.c | 4 +- ThirdParty/Ert/lib/ecl/grid_dims.cpp | 2 +- ThirdParty/Ert/lib/ecl/layer.cpp | 2 +- ThirdParty/Ert/lib/ecl/nnc_info.cpp | 36 +- ThirdParty/Ert/lib/ecl/nnc_vector.cpp | 43 +- ThirdParty/Ert/lib/ecl/smspec_node.cpp | 1339 ++++++----- .../Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp | 2 +- .../ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp | 3 +- .../Ert/lib/ecl/tests/ecl_coarse_test.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp | 2 +- ...=> ecl_fault_block_collection_equinor.cpp} | 4 +- .../lib/ecl/tests/ecl_fault_block_layer.cpp | 3 +- ....cpp => ecl_fault_block_layer_equinor.cpp} | 4 +- ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp | 9 +- ..._file_statoil.cpp => ecl_file_equinor.cpp} | 14 +- .../Ert/lib/ecl/tests/ecl_file_view.cpp | 5 +- ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp | 16 +- ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp | 30 +- .../lib/ecl/tests/ecl_get_num_cpu_test.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp | 10 +- .../Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp | 13 +- .../Ert/lib/ecl/tests/ecl_grid_case.cpp | 2 +- .../lib/ecl/tests/ecl_grid_cell_contains.cpp | 2 +- .../tests/ecl_grid_cell_contains_wellpath.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_copy.cpp | 2 +- ..._statoil.cpp => ecl_grid_copy_equinor.cpp} | 4 +- .../Ert/lib/ecl/tests/ecl_grid_corner.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_create.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_dims.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_export.cpp | 5 +- .../Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp | 11 +- .../Ert/lib/ecl/tests/ecl_grid_fwrite.cpp | 70 +- .../lib/ecl/tests/ecl_grid_init_fwrite.cpp | 8 +- .../lib/ecl/tests/ecl_grid_layer_contains.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp | 4 +- .../lib/ecl/tests/ecl_grid_reset_actnum.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_grid_simple.cpp | 2 +- .../lib/ecl/tests/ecl_grid_unit_system.cpp | 6 +- .../Ert/lib/ecl/tests/ecl_grid_volume.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_init_file.cpp | 7 +- .../Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp | 3 +- ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp | 9 +- ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp | 9 +- .../Ert/lib/ecl/tests/ecl_kw_grdecl.cpp | 5 +- ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp | 2 +- ...ayer_statoil.cpp => ecl_layer_equinor.cpp} | 4 +- ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp | 2 +- ...root.cpp => ecl_nnc_data_equinor_root.cpp} | 4 +- .../Ert/lib/ecl/tests/ecl_nnc_export.cpp | 22 +- .../lib/ecl/tests/ecl_nnc_export_get_tran.cpp | 2 +- .../ecl/tests/ecl_nnc_export_intersect.cpp | 117 + .../Ert/lib/ecl/tests/ecl_nnc_geometry.cpp | 6 +- .../Ert/lib/ecl/tests/ecl_nnc_index_list.cpp | 2 +- .../lib/ecl/tests/ecl_nnc_index_list_grid.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_nnc_info_test.cpp | 21 +- ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp | 19 +- .../Ert/lib/ecl/tests/ecl_nnc_vector.cpp | 22 +- ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_region2region.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_restart_test.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp | 11 +- ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp | 11 +- ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp | 23 +- .../Ert/lib/ecl/tests/ecl_smspec_node.cpp | 207 +- .../tests/ecl_sum_alloc_resampled_test.cpp | 83 +- .../Ert/lib/ecl/tests/ecl_sum_case_exists.cpp | 2 +- .../tests/ecl_sum_data_intermediate_test.cpp | 174 +- .../tests/ecl_sum_report_step_compatible.cpp | 2 +- .../ecl/tests/ecl_sum_report_step_equal.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_sum_restart.cpp | 167 ++ ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp | 2 +- .../Ert/lib/ecl/tests/ecl_sum_writer.cpp | 60 +- .../lib/ecl/tests/ecl_unsmry_loader_test.cpp | 15 +- .../Ert/lib/ecl/tests/ecl_util_filenames.cpp | 18 +- .../ecl/tests/ecl_util_make_date_no_shift.cpp | 2 +- .../ecl/tests/ecl_util_make_date_shift.cpp | 2 +- .../lib/ecl/tests/ecl_util_month_range.cpp | 2 +- .../lib/ecl/tests/ecl_util_path_access.cpp | 5 +- .../Ert/lib/ecl/tests/ecl_valid_basename.cpp | 2 +- .../Ert/lib/ecl/tests/eclxx_filename.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp | 15 +- ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp | 5 +- ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp | 130 -- ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/rft_test.cpp | 2 +- .../Ert/lib/ecl/tests/test_ecl_file_index.cpp | 5 +- .../Ert/lib/ecl/tests/test_ecl_nnc_data.cpp | 5 +- .../Ert/lib/ecl/tests/test_transactions.cpp | 9 +- .../lib/ecl/tests/well_branch_collection.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_conn.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp | 2 +- .../lib/ecl/tests/well_conn_collection.cpp | 2 +- .../Ert/lib/ecl/tests/well_conn_load.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_info.cpp | 6 +- .../Ert/lib/ecl/tests/well_lgr_load.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_segment.cpp | 2 +- .../tests/well_segment_branch_conn_load.cpp | 2 +- .../lib/ecl/tests/well_segment_collection.cpp | 2 +- .../Ert/lib/ecl/tests/well_segment_conn.cpp | 2 +- .../lib/ecl/tests/well_segment_conn_load.cpp | 2 +- .../Ert/lib/ecl/tests/well_segment_load.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_state.cpp | 2 +- .../Ert/lib/ecl/tests/well_state_load.cpp | 2 +- .../tests/well_state_load_missing_RSEG.cpp | 2 +- ThirdParty/Ert/lib/ecl/tests/well_ts.cpp | 5 +- .../Ert/lib/ecl/well_branch_collection.cpp | 51 +- ThirdParty/Ert/lib/ecl/well_conn.cpp | 6 +- .../Ert/lib/ecl/well_conn_collection.cpp | 29 +- ThirdParty/Ert/lib/ecl/well_info.cpp | 22 +- ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp | 3 +- ThirdParty/Ert/lib/ecl/well_segment.cpp | 35 +- .../Ert/lib/ecl/well_segment_collection.cpp | 55 +- ThirdParty/Ert/lib/ecl/well_state.cpp | 145 +- ThirdParty/Ert/lib/ecl/well_ts.cpp | 80 +- ThirdParty/Ert/lib/geometry/geo_pointset.cpp | 2 +- ThirdParty/Ert/lib/geometry/geo_polygon.cpp | 2 +- .../lib/geometry/geo_polygon_collection.cpp | 20 +- ThirdParty/Ert/lib/geometry/geo_region.cpp | 2 +- ThirdParty/Ert/lib/geometry/geo_surface.cpp | 2 +- ThirdParty/Ert/lib/geometry/geo_util.cpp | 2 +- .../Ert/lib/geometry/tests/geo_polygon.cpp | 2 +- .../geometry/tests/geo_polygon_collection.cpp | 2 +- .../Ert/lib/geometry/tests/geo_surface.cpp | 2 +- .../lib/geometry/tests/geo_util_xlines.cpp | 2 +- .../Ert/lib/include/ert/ecl/EclFilename.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp | 61 - .../Ert/lib/include/ert/ecl/ecl_box.hpp | 2 +- .../lib/include/ert/ecl/ecl_coarse_cell.hpp | 2 +- .../lib/include/ert/ecl/ecl_endian_flip.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_file.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_file_kw.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_file_view.hpp | 6 +- .../Ert/lib/include/ert/ecl/ecl_grav.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_grav_calc.hpp | 2 +- .../lib/include/ert/ecl/ecl_grav_common.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_grid.hpp | 10 +- .../Ert/lib/include/ert/ecl/ecl_grid_dims.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_init_file.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_io_config.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_nnc_data.hpp | 2 +- .../lib/include/ert/ecl/ecl_nnc_export.hpp | 5 +- .../lib/include/ert/ecl/ecl_nnc_geometry.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_region.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_rft_cell.hpp | 4 +- .../Ert/lib/include/ert/ecl/ecl_rft_file.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_rft_node.hpp | 5 +- .../Ert/lib/include/ert/ecl/ecl_rst_file.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_rsthead.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_smspec.hpp | 73 +- .../lib/include/ert/ecl/ecl_subsidence.hpp | 8 +- .../Ert/lib/include/ert/ecl/ecl_sum.hpp | 20 +- .../Ert/lib/include/ert/ecl/ecl_sum_data.hpp | 10 +- .../Ert/lib/include/ert/ecl/ecl_sum_index.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp | 19 +- .../lib/include/ert/ecl/ecl_sum_vector.hpp | 10 +- .../Ert/lib/include/ert/ecl/ecl_type.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_units.hpp | 2 +- .../Ert/lib/include/ert/ecl/ecl_util.hpp | 2 +- .../Ert/lib/include/ert/ecl/fault_block.hpp | 2 +- .../lib/include/ert/ecl/fault_block_layer.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/fortio.h | 2 +- .../Ert/lib/include/ert/ecl/grid_dims.hpp | 2 +- ThirdParty/Ert/lib/include/ert/ecl/layer.hpp | 2 +- .../Ert/lib/include/ert/ecl/nnc_info.hpp | 22 +- .../Ert/lib/include/ert/ecl/nnc_vector.hpp | 19 +- .../Ert/lib/include/ert/ecl/smspec_node.h | 129 +- .../Ert/lib/include/ert/ecl/smspec_node.hpp | 190 +- .../ert/ecl_well/well_branch_collection.hpp | 4 +- .../lib/include/ert/ecl_well/well_conn.hpp | 2 +- .../ert/ecl_well/well_conn_collection.hpp | 2 +- .../lib/include/ert/ecl_well/well_const.hpp | 2 +- .../lib/include/ert/ecl_well/well_info.hpp | 2 +- .../include/ert/ecl_well/well_rseg_loader.hpp | 2 +- .../lib/include/ert/ecl_well/well_segment.hpp | 2 +- .../ert/ecl_well/well_segment_collection.hpp | 2 +- .../lib/include/ert/ecl_well/well_state.hpp | 2 +- .../Ert/lib/include/ert/ecl_well/well_ts.hpp | 4 +- .../lib/include/ert/geometry/geo_pointset.hpp | 2 +- .../lib/include/ert/geometry/geo_polygon.hpp | 2 +- .../ert/geometry/geo_polygon_collection.hpp | 2 +- .../lib/include/ert/geometry/geo_region.hpp | 2 +- .../lib/include/ert/geometry/geo_surface.hpp | 2 +- .../Ert/lib/include/ert/geometry/geo_util.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/atomic.h | 144 +- .../Ert/lib/include/ert/util/buffer.hpp | 2 +- .../Ert/lib/include/ert/util/ecl_version.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/hash.hpp | 2 +- .../Ert/lib/include/ert/util/hash_node.hpp | 2 +- .../Ert/lib/include/ert/util/hash_sll.hpp | 2 +- .../Ert/lib/include/ert/util/lookup_table.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/mzran.hpp | 2 +- .../Ert/lib/include/ert/util/node_ctype.hpp | 2 +- .../Ert/lib/include/ert/util/node_data.hpp | 2 +- .../Ert/lib/include/ert/util/parser.hpp | 2 +- .../Ert/lib/include/ert/util/path_stack.hpp | 2 +- .../Ert/lib/include/ert/util/perm_vector.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/rng.hpp | 2 +- .../Ert/lib/include/ert/util/ssize_t.hpp | 2 +- .../Ert/lib/include/ert/util/statistics.hpp | 2 +- .../Ert/lib/include/ert/util/string_util.hpp | 2 +- .../Ert/lib/include/ert/util/stringlist.hpp | 2 +- .../Ert/lib/include/ert/util/test_util.hpp | 2 +- .../lib/include/ert/util/test_work_area.hpp | 58 +- .../Ert/lib/include/ert/util/thread_pool1.h | 2 +- .../lib/include/ert/util/time_interval.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/timer.hpp | 2 +- .../ert/util/type_vector_functions.hpp | 2 +- ThirdParty/Ert/lib/include/ert/util/util.h | 13 +- ThirdParty/Ert/lib/include/ert/util/util.hpp | 2 +- .../Ert/lib/include/ert/util/util_endian.h | 2 +- .../Ert/lib/include/ert/util/util_unlink.h | 2 +- .../Ert/lib/include/ert/util/vector.hpp | 2 +- .../Ert/lib/include/ert/util/vector_util.hpp | 52 + .../detail/ecl/ecl_grid_cache.hpp | 2 +- .../detail/ecl/ecl_sum_file_data.hpp | 2 +- ThirdParty/Ert/lib/util/buffer.cpp | 28 +- ThirdParty/Ert/lib/util/cxx_string_util.cpp | 2 +- ThirdParty/Ert/lib/util/hash.cpp | 7 +- ThirdParty/Ert/lib/util/hash_node.cpp | 2 +- ThirdParty/Ert/lib/util/hash_sll.cpp | 2 +- ThirdParty/Ert/lib/util/lookup_table.cpp | 2 +- ThirdParty/Ert/lib/util/mzran.cpp | 2 +- ThirdParty/Ert/lib/util/node_ctype.cpp | 2 +- ThirdParty/Ert/lib/util/node_data.cpp | 2 +- ThirdParty/Ert/lib/util/parser.cpp | 2 +- ThirdParty/Ert/lib/util/path.cpp | 19 +- ThirdParty/Ert/lib/util/path_stack.cpp | 2 +- ThirdParty/Ert/lib/util/perm_vector.cpp | 2 +- ThirdParty/Ert/lib/util/rng.cpp | 2 +- ThirdParty/Ert/lib/util/statistics.cpp | 2 +- ThirdParty/Ert/lib/util/string_util.cpp | 2 +- ThirdParty/Ert/lib/util/stringlist.cpp | 2 +- ThirdParty/Ert/lib/util/test_util.cpp | 3 +- ThirdParty/Ert/lib/util/test_work_area.cpp | 403 ++-- .../Ert/lib/util/tests/ert_util_addr2line.cpp | 6 +- .../tests/ert_util_alloc_file_components.cpp | 31 +- .../lib/util/tests/ert_util_approx_equal.cpp | 2 +- .../lib/util/tests/ert_util_before_after.cpp | 2 +- .../lib/util/tests/ert_util_binary_split.cpp | 8 +- .../Ert/lib/util/tests/ert_util_buffer.cpp | 3 +- .../Ert/lib/util/tests/ert_util_chdir.cpp | 15 +- .../Ert/lib/util/tests/ert_util_clamp.cpp | 2 +- .../Ert/lib/util/tests/ert_util_copy_file.cpp | 5 +- .../Ert/lib/util/tests/ert_util_cwd_test.cpp | 7 +- .../Ert/lib/util/tests/ert_util_datetime.cpp | 2 +- .../lib/util/tests/ert_util_file_readable.cpp | 2 +- .../Ert/lib/util/tests/ert_util_filename.cpp | 3 +- .../Ert/lib/util/tests/ert_util_hash_test.cpp | 2 +- .../Ert/lib/util/tests/ert_util_mkdir_p.cpp | 5 +- .../lib/util/tests/ert_util_normal_path.cpp | 8 +- .../lib/util/tests/ert_util_parent_path.cpp | 2 +- .../util/tests/ert_util_path_stack_test.cpp | 2 +- .../Ert/lib/util/tests/ert_util_ping.cpp | 2 +- .../Ert/lib/util/tests/ert_util_realpath.cpp | 2 +- .../lib/util/tests/ert_util_relpath_test.cpp | 2 +- .../Ert/lib/util/tests/ert_util_rng.cpp | 2 +- .../Ert/lib/util/tests/ert_util_spawn.cpp | 11 +- .../lib/util/tests/ert_util_split_path.cpp | 2 +- .../lib/util/tests/ert_util_sscan_test.cpp | 2 +- .../lib/util/tests/ert_util_statistics.cpp | 4 +- .../lib/util/tests/ert_util_strcat_test.cpp | 9 +- .../lib/util/tests/ert_util_string_util.cpp | 3 +- .../util/tests/ert_util_stringlist_test.cpp | 86 +- .../util/tests/ert_util_strstr_int_format.cpp | 2 +- .../tests/ert_util_type_vector_functions.cpp | 2 +- .../util/tests/ert_util_type_vector_test.cpp | 44 +- .../lib/util/tests/ert_util_unique_ptr.cpp | 2 +- .../lib/util/tests/ert_util_vector_test.cpp | 2 +- .../Ert/lib/util/tests/ert_util_work_area.cpp | 44 +- ThirdParty/Ert/lib/util/tests/test_area.cpp | 34 + .../Ert/lib/util/tests/test_thread_pool.cpp | 2 +- ThirdParty/Ert/lib/util/timer.cpp | 2 +- .../Ert/lib/util/type_vector_functions.cpp | 2 +- ThirdParty/Ert/lib/util/util.c | 80 +- ThirdParty/Ert/lib/util/util_endian.cpp | 2 +- ThirdParty/Ert/lib/util/util_lfs.c | 2 +- ThirdParty/Ert/lib/util/util_unlink.cpp | 2 +- ThirdParty/Ert/lib/util/vector.cpp | 3 +- ThirdParty/Ert/lib/util/vector_template.cpp | 71 +- ThirdParty/Ert/lib/vector_template.h.in | 4 +- ThirdParty/Ert/lib/vector_template.hpp.in | 2 +- ThirdParty/Ert/python/CMakeLists.txt | 3 + ThirdParty/Ert/python/docs/CMakeLists.txt | 60 + .../Ert/{ => python}/docs/code/index.rst | 1 - .../docs/code/python/eclipse/index.rst | 0 .../code/python/examples/eclipse/index.rst | 0 .../docs/code/python/examples/geo/index.rst | 0 .../docs/code/python/examples/index.rst | 1 - .../{ => python}/docs/code/python/index.rst | 2 - .../docs/code/python/introduction/index.rst | 0 .../code/python/packages/eclipse/index.rst | 0 .../docs/code/python/packages/index.rst | 3 - ThirdParty/Ert/{ => python}/docs/conf.py.in | 30 +- .../docs/examples/avg_pressure.py | 3 +- .../Ert/{ => python}/docs/examples/cmp_nnc.py | 10 +- .../{ => python}/docs/examples/grid_info.py | 2 +- ThirdParty/Ert/{ => python}/docs/index.rst.in | 4 +- ThirdParty/Ert/python/docs/latex/capt-of.sty | 33 + ThirdParty/Ert/python/docs/latex/fncychap.sty | 701 ++++++ ThirdParty/Ert/python/docs/latex/framed.sty | 548 +++++ .../Ert/python/docs/latex/needspace.sty | 35 + ThirdParty/Ert/python/docs/latex/tabulary.sty | 451 ++++ ThirdParty/Ert/python/docs/latex/titlesec.sty | 1349 +++++++++++ ThirdParty/Ert/python/docs/latex/upquote.sty | 40 + ThirdParty/Ert/python/docs/latex/wrapfig.sty | 598 +++++ ThirdParty/Ert/python/ecl/__init__.py | 2 +- ThirdParty/Ert/python/ecl/ecl_type.py | 2 +- ThirdParty/Ert/python/ecl/ecl_util.py | 2 +- ThirdParty/Ert/python/ecl/eclfile/__init__.py | 2 +- .../Ert/python/ecl/eclfile/ecl_3d_file.py | 2 +- ThirdParty/Ert/python/ecl/eclfile/ecl_3dkw.py | 2 +- ThirdParty/Ert/python/ecl/eclfile/ecl_file.py | 2 +- .../Ert/python/ecl/eclfile/ecl_file_view.py | 2 +- .../Ert/python/ecl/eclfile/ecl_init_file.py | 2 +- ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py | 2 +- .../python/ecl/eclfile/ecl_restart_file.py | 2 +- ThirdParty/Ert/python/ecl/eclfile/fortio.py | 2 +- .../Ert/python/ecl/gravimetry/__init__.py | 2 +- .../Ert/python/ecl/gravimetry/ecl_grav.py | 2 +- .../python/ecl/gravimetry/ecl_grav_calc.py | 2 +- .../python/ecl/gravimetry/ecl_subsidence.py | 14 +- ThirdParty/Ert/python/ecl/grid/__init__.py | 2 +- ThirdParty/Ert/python/ecl/grid/cell.py | 2 +- ThirdParty/Ert/python/ecl/grid/ecl_grid.py | 2 +- .../Ert/python/ecl/grid/ecl_grid_generator.py | 2 +- ThirdParty/Ert/python/ecl/grid/ecl_region.py | 2 +- .../Ert/python/ecl/grid/faults/fault.py | 2 +- .../Ert/python/ecl/grid/faults/fault_block.py | 2 +- .../ecl/grid/faults/fault_block_collection.py | 2 +- .../ecl/grid/faults/fault_block_layer.py | 2 +- .../ecl/grid/faults/fault_collection.py | 2 +- .../Ert/python/ecl/grid/faults/fault_line.py | 2 +- .../python/ecl/grid/faults/fault_segments.py | 2 +- .../Ert/python/ecl/grid/faults/layer.py | 2 +- ThirdParty/Ert/python/ecl/rft/__init__.py | 2 +- ThirdParty/Ert/python/ecl/rft/ecl_rft.py | 47 +- ThirdParty/Ert/python/ecl/rft/ecl_rft_cell.py | 2 +- .../Ert/python/ecl/rft/well_trajectory.py | 2 +- ThirdParty/Ert/python/ecl/summary/__init__.py | 2 +- ThirdParty/Ert/python/ecl/summary/ecl_cmp.py | 2 +- ThirdParty/Ert/python/ecl/summary/ecl_npv.py | 4 +- .../Ert/python/ecl/summary/ecl_smspec_node.py | 2 +- ThirdParty/Ert/python/ecl/summary/ecl_sum.py | 75 +- .../ecl/summary/ecl_sum_keyword_vector.py | 2 +- .../Ert/python/ecl/summary/ecl_sum_tstep.py | 2 +- .../python/ecl/summary/ecl_sum_var_type.py | 2 +- .../Ert/python/ecl/summary/ecl_sum_vector.py | 21 +- .../Ert/python/ecl/util/geometry/__init__.py | 2 +- .../Ert/python/ecl/util/geometry/cpolyline.py | 2 +- .../ecl/util/geometry/cpolyline_collection.py | 2 +- .../python/ecl/util/geometry/geo_pointset.py | 2 +- .../python/ecl/util/geometry/geo_region.py | 2 +- .../Ert/python/ecl/util/geometry/surface.py | 2 +- .../Ert/python/ecl/util/test/CMakeLists.txt | 1 - .../Ert/python/ecl/util/test/__init__.py | 1 - .../ecl/util/test/ecl_mock/ecl_sum_mock.py | 2 + .../python/ecl/util/test/ert_test_context.py | 2 +- .../python/ecl/util/test/import_test_case.py | 2 +- .../python/ecl/util/test/lint_test_case.py | 2 +- .../Ert/python/ecl/util/test/temp_area.py | 81 - .../Ert/python/ecl/util/test/test_area.py | 31 +- .../Ert/python/ecl/util/test/test_run.py | 2 +- .../Ert/python/ecl/util/util/__init__.py | 4 +- .../Ert/python/ecl/util/util/arg_pack.py | 2 +- .../Ert/python/ecl/util/util/bool_vector.py | 2 +- .../Ert/python/ecl/util/util/cthread_pool.py | 2 +- ThirdParty/Ert/python/ecl/util/util/ctime.py | 2 +- .../Ert/python/ecl/util/util/double_vector.py | 2 +- ThirdParty/Ert/python/ecl/util/util/hash.py | 2 +- .../Ert/python/ecl/util/util/int_vector.py | 2 +- .../Ert/python/ecl/util/util/lookup_table.py | 2 +- ThirdParty/Ert/python/ecl/util/util/matrix.py | 230 -- ThirdParty/Ert/python/ecl/util/util/rng.py | 2 +- .../Ert/python/ecl/util/util/stringlist.py | 2 +- .../Ert/python/ecl/util/util/time_vector.py | 2 +- .../Ert/python/ecl/util/util/util_func.py | 2 +- .../python/ecl/util/util/vector_template.py | 2 +- ThirdParty/Ert/python/ecl/well/well_info.py | 2 +- ThirdParty/Ert/python/ert/test/__init__.py | 1 - ThirdParty/Ert/python/tests/__init__.py | 28 +- .../tests/bin_tests/test_summary_resample.py | 3 +- .../Ert/python/tests/ecl_tests/CMakeLists.txt | 48 +- .../Ert/python/tests/ecl_tests/test_cell.py | 2 +- .../Ert/python/tests/ecl_tests/test_debug.py | 2 +- .../tests/ecl_tests/test_deprecation.py | 3 +- .../python/tests/ecl_tests/test_ecl_3dkw.py | 2 +- .../python/tests/ecl_tests/test_ecl_cmp.py | 10 +- .../python/tests/ecl_tests/test_ecl_file.py | 2 +- ...le_statoil.py => test_ecl_file_equinor.py} | 14 +- .../tests/ecl_tests/test_ecl_init_file.py | 10 +- .../Ert/python/tests/ecl_tests/test_ecl_kw.py | 2 +- ...l_kw_statoil.py => test_ecl_kw_equinor.py} | 12 +- .../tests/ecl_tests/test_ecl_restart_file.py | 16 +- .../python/tests/ecl_tests/test_ecl_sum.py | 18 +- .../tests/ecl_tests/test_ecl_sum_vector.py | 10 +- .../python/tests/ecl_tests/test_ecl_util.py | 2 +- ...atoil_faults.py => test_equinor_faults.py} | 12 +- .../tests/ecl_tests/test_fault_blocks.py | 2 +- ...tatoil.py => test_fault_blocks_equinor.py} | 10 +- .../Ert/python/tests/ecl_tests/test_faults.py | 2 +- .../tests/ecl_tests/test_fk_user_data.py | 2 +- .../Ert/python/tests/ecl_tests/test_fortio.py | 7 +- .../python/tests/ecl_tests/test_geertsma.py | 74 +- .../Ert/python/tests/ecl_tests/test_grdecl.py | 2 +- ...decl_statoil.py => test_grdecl_equinor.py} | 12 +- .../Ert/python/tests/ecl_tests/test_grid.py | 6 +- ...t_grid_statoil.py => test_grid_equinor.py} | 20 +- ..._coarse.py => test_grid_equinor_coarse.py} | 10 +- ...toil_dual.py => test_grid_equinor_dual.py} | 18 +- ...ase.py => test_grid_equinor_large_case.py} | 10 +- .../tests/ecl_tests/test_grid_generator.py | 2 +- .../tests/ecl_tests/test_grid_pandas.py | 2 +- .../tests/ecl_tests/test_kw_function.py | 2 +- .../Ert/python/tests/ecl_tests/test_layer.py | 2 +- .../Ert/python/tests/ecl_tests/test_npv.py | 8 +- .../Ert/python/tests/ecl_tests/test_region.py | 2 +- ...gion_statoil.py => test_region_equinor.py} | 10 +- .../python/tests/ecl_tests/test_removed.py | 4 +- .../python/tests/ecl_tests/test_restart.py | 14 +- .../tests/ecl_tests/test_restart_head.py | 12 +- .../Ert/python/tests/ecl_tests/test_rft.py | 30 +- .../python/tests/ecl_tests/test_rft_cell.py | 6 +- ...est_rft_statoil.py => test_rft_equinor.py} | 26 +- .../Ert/python/tests/ecl_tests/test_sum.py | 108 +- ...est_sum_statoil.py => test_sum_equinor.py} | 43 +- .../python/tests/global_tests/test_import.py | 2 +- .../python/tests/global_tests/test_pylint.py | 2 +- .../python/tests/legacy_tests/test_test.py | 1 - .../Ert/python/tests/util_tests/test_rng.py | 1 - .../python/tests/util_tests/test_vectors.py | 2 +- .../python/tests/util_tests/test_version.py | 2 +- .../python/tests/util_tests/test_work_area.py | 84 +- .../python/tests/well_tests/CMakeLists.txt | 2 + .../python/tests/well_tests/test_ecl_well.py | 28 +- .../python/tests/well_tests/test_ecl_well2.py | 8 +- .../python/tests/well_tests/test_ecl_well3.py | 10 +- .../well_tests/test_well_missing_ICON.py | 28 + ThirdParty/Ert/python/txt-doc/README.txt | 4 + .../Ert/python/{doc => txt-doc}/devel.txt | 14 +- .../Ert/python/{doc => txt-doc}/import.txt | 0 .../Ert/python/{doc => txt-doc}/install.txt | 0 .../Ert/{docs => python/txt-doc}/tips.txt | 8 +- ThirdParty/Ert/redhat/ecl.spec | 4 +- ThirdParty/Ert/requirements.txt | 4 + ThirdParty/Ert/script/download-pr | 4 +- ThirdParty/Ert/setup.py | 4 +- ThirdParty/Ert/test-data/README.txt | 8 +- .../local/ECLIPSE/cp_simple3/SHORT.SMSPEC | Bin 0 -> 64700 bytes .../local/ECLIPSE/cp_simple3/SHORT.UNSMRY | Bin 0 -> 301636 bytes .../ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA | 2 +- .../ECLIPSE/well/missing-ICON/ICON0.X0027 | Bin 0 -> 9280 bytes .../ECLIPSE/well/missing-ICON/ICON1.X0027 | Bin 0 -> 38168 bytes .../test-data/local/util/latex/report_OK.tex | 2 +- .../local/util/latex/report_error.tex | 2 +- 587 files changed, 8944 insertions(+), 7854 deletions(-) create mode 100644 ThirdParty/Ert/.github/CODEOWNERS create mode 100644 ThirdParty/Ert/.gitmodules create mode 100644 ThirdParty/Ert/WINDOWS.md delete mode 100644 ThirdParty/Ert/Windows.txt rename ThirdParty/Ert/applications/ecl/{kw_extract.c => kw_extract.cpp} (98%) rename ThirdParty/Ert/applications/ecl/{sum_write.c => sum_write.cpp} (96%) rename ThirdParty/Ert/applications/ecl/{view_summary.c => view_summary.cpp} (97%) create mode 100644 ThirdParty/Ert/config.sh delete mode 100644 ThirdParty/Ert/docs/CMakeLists.txt delete mode 100644 ThirdParty/Ert/docs/code/C/index.rst delete mode 100644 ThirdParty/Ert/docs/code/python/eclipse/API/index.rst delete mode 100644 ThirdParty/Ert/docs/code/python/examples/ert/index.rst delete mode 100644 ThirdParty/Ert/docs/code/python/packages/geometry/index.rst delete mode 100644 ThirdParty/Ert/docs/code/python/packages/util/index.rst delete mode 100644 ThirdParty/Ert/docs/code/python/packages/well/index.rst delete mode 100644 ThirdParty/Ert/docs/course/config/config.ert delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_DIFF delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_NPV delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_SIMULATOR delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/snake_oil_diff.py delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/snake_oil_npv.py delete mode 100644 ThirdParty/Ert/docs/course/config/jobs/snake_oil_simulator.py delete mode 100644 ThirdParty/Ert/docs/course/config/parameters/snake_oil_parameters.txt delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.SMSPEC delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.UNSMRY delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/refcase_readme.txt delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/seed.txt delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/snake_oil_params.txt delete mode 100644 ThirdParty/Ert/docs/course/config/refcase/time_map.txt delete mode 100644 ThirdParty/Ert/docs/course/config/snake_oil.ert delete mode 100644 ThirdParty/Ert/docs/course/config/templates/seed_template.txt delete mode 100644 ThirdParty/Ert/docs/course/config/templates/snake_oil_template.txt delete mode 100644 ThirdParty/Ert/docs/course/ex1/ex1.txt delete mode 100644 ThirdParty/Ert/docs/course/ex1/sol1.py delete mode 100644 ThirdParty/Ert/docs/course/ex2/ex2.txt delete mode 100644 ThirdParty/Ert/docs/course/ex2/sol2.txt delete mode 100644 ThirdParty/Ert/docs/course/ex3/ex3.txt delete mode 100644 ThirdParty/Ert/docs/course/ex3/sol3.py delete mode 100644 ThirdParty/Ert/docs/course/ex4/ex4.txt delete mode 100644 ThirdParty/Ert/docs/course/ex4/sol4.py delete mode 100644 ThirdParty/Ert/docs/doxygen.cfg.in delete mode 100644 ThirdParty/Ert/docs/eclipse_restart_spe1.txt delete mode 100644 ThirdParty/Ert/docs/eclipse_restart_specification.txt delete mode 100644 ThirdParty/Ert/docs/nexus.plt delete mode 100644 ThirdParty/Ert/lib/ecl/Smspec.cpp rename ThirdParty/Ert/lib/ecl/tests/{ecl_fault_block_collection_statoil.cpp => ecl_fault_block_collection_equinor.cpp} (95%) rename ThirdParty/Ert/lib/ecl/tests/{ecl_fault_block_layer_statoil.cpp => ecl_fault_block_layer_equinor.cpp} (95%) rename ThirdParty/Ert/lib/ecl/tests/{ecl_file_statoil.cpp => ecl_file_equinor.cpp} (90%) rename ThirdParty/Ert/lib/ecl/tests/{ecl_grid_copy_statoil.cpp => ecl_grid_copy_equinor.cpp} (91%) rename ThirdParty/Ert/lib/ecl/tests/{ecl_layer_statoil.cpp => ecl_layer_equinor.cpp} (96%) rename ThirdParty/Ert/lib/ecl/tests/{ecl_nnc_data_statoil_root.cpp => ecl_nnc_data_equinor_root.cpp} (97%) create mode 100644 ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_intersect.cpp create mode 100644 ThirdParty/Ert/lib/ecl/tests/ecl_sum_restart.cpp delete mode 100644 ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp delete mode 100644 ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp create mode 100644 ThirdParty/Ert/lib/include/ert/util/vector_util.hpp create mode 100644 ThirdParty/Ert/lib/util/tests/test_area.cpp create mode 100644 ThirdParty/Ert/python/docs/CMakeLists.txt rename ThirdParty/Ert/{ => python}/docs/code/index.rst (90%) rename ThirdParty/Ert/{ => python}/docs/code/python/eclipse/index.rst (100%) rename ThirdParty/Ert/{ => python}/docs/code/python/examples/eclipse/index.rst (100%) rename ThirdParty/Ert/{ => python}/docs/code/python/examples/geo/index.rst (100%) rename ThirdParty/Ert/{ => python}/docs/code/python/examples/index.rst (81%) rename ThirdParty/Ert/{ => python}/docs/code/python/index.rst (54%) rename ThirdParty/Ert/{ => python}/docs/code/python/introduction/index.rst (100%) rename ThirdParty/Ert/{ => python}/docs/code/python/packages/eclipse/index.rst (100%) rename ThirdParty/Ert/{ => python}/docs/code/python/packages/index.rst (86%) rename ThirdParty/Ert/{ => python}/docs/conf.py.in (93%) rename ThirdParty/Ert/{ => python}/docs/examples/avg_pressure.py (96%) rename ThirdParty/Ert/{ => python}/docs/examples/cmp_nnc.py (69%) rename ThirdParty/Ert/{ => python}/docs/examples/grid_info.py (94%) rename ThirdParty/Ert/{ => python}/docs/index.rst.in (87%) create mode 100644 ThirdParty/Ert/python/docs/latex/capt-of.sty create mode 100644 ThirdParty/Ert/python/docs/latex/fncychap.sty create mode 100644 ThirdParty/Ert/python/docs/latex/framed.sty create mode 100644 ThirdParty/Ert/python/docs/latex/needspace.sty create mode 100644 ThirdParty/Ert/python/docs/latex/tabulary.sty create mode 100644 ThirdParty/Ert/python/docs/latex/titlesec.sty create mode 100644 ThirdParty/Ert/python/docs/latex/upquote.sty create mode 100644 ThirdParty/Ert/python/docs/latex/wrapfig.sty delete mode 100644 ThirdParty/Ert/python/ecl/util/test/temp_area.py delete mode 100644 ThirdParty/Ert/python/ecl/util/util/matrix.py rename ThirdParty/Ert/python/tests/ecl_tests/{test_ecl_file_statoil.py => test_ecl_file_equinor.py} (97%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_ecl_kw_statoil.py => test_ecl_kw_equinor.py} (91%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_statoil_faults.py => test_equinor_faults.py} (94%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_fault_blocks_statoil.py => test_fault_blocks_equinor.py} (85%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_grdecl_statoil.py => test_grdecl_equinor.py} (93%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_grid_statoil.py => test_grid_equinor.py} (94%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_grid_statoil_coarse.py => test_grid_equinor_coarse.py} (84%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_grid_statoil_dual.py => test_grid_equinor_dual.py} (84%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_grid_statoil_large_case.py => test_grid_equinor_large_case.py} (78%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_region_statoil.py => test_region_equinor.py} (96%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_rft_statoil.py => test_rft_equinor.py} (81%) rename ThirdParty/Ert/python/tests/ecl_tests/{test_sum_statoil.py => test_sum_equinor.py} (93%) create mode 100644 ThirdParty/Ert/python/tests/well_tests/test_well_missing_ICON.py create mode 100644 ThirdParty/Ert/python/txt-doc/README.txt rename ThirdParty/Ert/python/{doc => txt-doc}/devel.txt (99%) rename ThirdParty/Ert/python/{doc => txt-doc}/import.txt (100%) rename ThirdParty/Ert/python/{doc => txt-doc}/install.txt (100%) rename ThirdParty/Ert/{docs => python/txt-doc}/tips.txt (99%) create mode 100644 ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SHORT.SMSPEC create mode 100644 ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SHORT.UNSMRY create mode 100644 ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON0.X0027 create mode 100644 ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON1.X0027 diff --git a/ThirdParty/Ert/.github/CODEOWNERS b/ThirdParty/Ert/.github/CODEOWNERS new file mode 100644 index 0000000000..a931a3003f --- /dev/null +++ b/ThirdParty/Ert/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# These owners will be the default owners for everything in the repo. +* @markusdregi @lars-petter-hauge @andreabrambilla @pgdr @jokva @xjules diff --git a/ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md b/ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md index adf85eaeb6..3ea367d2a9 100644 --- a/ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md +++ b/ThirdParty/Ert/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,5 @@ -**Task** -_Short description of the task_ - +**Issue** +Resolves # **Approach** _Short description of the approach_ - - -**Pre un-WIP checklist** -- [ ] Statoil tests pass locally diff --git a/ThirdParty/Ert/.gitignore b/ThirdParty/Ert/.gitignore index b835bff007..b92bed604e 100644 --- a/ThirdParty/Ert/.gitignore +++ b/ThirdParty/Ert/.gitignore @@ -11,8 +11,9 @@ python/lib64 /libenkf/src/.faultlist /develbranch/libenkf/src/.faultlist /build +/temp-build /libert_util/tests/data/latex_OK.pdf -/test-data/Statoil +/test-data/Equinor /python/python/ert/ecl/ecl_local.py /GPATH /GRTAGS diff --git a/ThirdParty/Ert/.gitmodules b/ThirdParty/Ert/.gitmodules new file mode 100644 index 0000000000..347fe93043 --- /dev/null +++ b/ThirdParty/Ert/.gitmodules @@ -0,0 +1,3 @@ +[submodule "multibuild"] + path = multibuild + url = https://github.com/matthew-brett/multibuild.git diff --git a/ThirdParty/Ert/.travis.yml b/ThirdParty/Ert/.travis.yml index 6fdc81f1a6..9bef0ca2d6 100644 --- a/ThirdParty/Ert/.travis.yml +++ b/ThirdParty/Ert/.travis.yml @@ -1,82 +1,70 @@ -language: c - -compiler: - - gcc - - clang +language: python +python: + - 2.7 + - 3.6 os: - linux - - osx -osx_image: xcode7.3 -sudo: false -dist: trusty +sudo: required +services: docker env: global: - ERT_SHOW_BACKTRACE=1 - - LD_LIBRARY_PATH="$(pwd)/install/lib64" + - MB_PYTHON_VERSION=$TRAVIS_PYTHON_VERSION matrix: - - PYTHON_VERSION=2.7 TEST_SUITE="-LE SLOW" # Run all tests not labeled as slow - - PYTHON_VERSION=2.7 TEST_SUITE="-L SLOW_1" # Run all tests labeled as SLOW in group 1 - - PYTHON_VERSION=2.7 TEST_SUITE="-L SLOW_2" # Run all tests labeled as SLOW in group 2 - - PYTHON_VERSION=3.6 # Run all tests + - TEST_SUITE="-LE SLOW" # Run all tests not labeled as slow + - TEST_SUITE="-L SLOW_1" # Run all tests labeled as SLOW in group 1 + - TEST_SUITE="-L SLOW_2" # Run all tests labeled as SLOW in group 2 matrix: fast_finish: true - exclude: + include: - os: osx - compiler: gcc - - os: linux - compiler: clang + language: generic + python: 2.7 + env: + - MB_PYTHON_VERSION=2.7 + - TEST_SUITE="" + - os: osx + language: generic + python: 3.6 + env: + - MB_PYTHON_VERSION=3.6 + - TEST_SUITE="" addons: apt: - sources: - - ubuntu-toolchain-r-test packages: - liblapack-dev - - valgrind - - gcc-4.8 - - g++-4.8 - - clang - - cmake - - cmake-data +before_install: + - unset -f pushd + - unset -f popd + - source multibuild/common_utils.sh + - source multibuild/travis_steps.sh + - before_install install: - - if [[ "$CC" == "gcc" ]]; then export CXX="g++-4.8"; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - export CONDA_OS=MacOSX; - else - export CONDA_OS=Linux; - fi - - if [[ $PYTHON_VERSION == 2.7 ]]; then - export TRAVIS_PYTHON_VERSION="2.7"; - fi - - if [[ $PYTHON_VERSION == 3.6 ]]; then - export TRAVIS_PYTHON_VERSION="3.6"; - fi - # We do this conditionally because it saves us some downloading if the version is the same. - - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - wget https://repo.continuum.io/miniconda/Miniconda2-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh; - else - wget https://repo.continuum.io/miniconda/Miniconda3-4.4.10-${CONDA_OS}-x86_64.sh -O miniconda.sh; - fi - - bash miniconda.sh -b -p $HOME/miniconda - - export CONDA_HOME="$HOME/miniconda" - - export PATH="$CONDA_HOME/bin:$PATH" - - hash -r - - python --version - pip install -r requirements.txt - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda info -a # Useful for debugging any issues with conda - - wget https://raw.githubusercontent.com/Statoil/ert/master/travis/install_python_packages.py - - python install_python_packages.py - -before_script: - - wget https://raw.githubusercontent.com/Statoil/ert/master/travis/build_total.py script: - - python build_total.py ecl ${TEST_SUITE} + - mkdir build + - pushd build + - cmake .. -DBUILD_TESTS=ON + -DENABLE_PYTHON=ON + -DINSTALL_CWRAP=OFF + -DBUILD_APPLICATIONS=ON + -DINSTALL_ERT_LEGACY=ON + -DERT_USE_OPENMP=ON + -DCMAKE_C_FLAGS='-Werror=all' + -DCMAKE_CXX_FLAGS='-Werror -Wno-unused-result' + - make + - sudo make install + - which python + - export PYTHONPATH="/usr/local/lib/python$MB_PYTHON_VERSION/site-packages:/usr/local/lib/python$MB_PYTHON_VERSION/dist-packages:$PYTHONPATH" + - python -c "import sys; print('\n'.join(sys.path))" + - set -e; python -c "import ecl"; set +e + - ctest --output-on-failure $TEST_SUITE + - popd diff --git a/ThirdParty/Ert/CMakeLists.txt b/ThirdParty/Ert/CMakeLists.txt index 5e2e1e42b4..36417d18e7 100644 --- a/ThirdParty/Ert/CMakeLists.txt +++ b/ThirdParty/Ert/CMakeLists.txt @@ -11,7 +11,7 @@ endif() #----------------------------------------------------------------- set( ECL_VERSION_MAJOR 2 ) # Remember to update release notes whenever -set( ECL_VERSION_MINOR 3 ) # you change the ERT_VERSION_MINOR or MAJOR +set( ECL_VERSION_MINOR 4 ) # you change the ERT_VERSION_MINOR or MAJOR set( ECL_VERSION_MICRO git ) # with "new in Ert Version X.X.X"! # If the micro version is not integer, that should be interpreted as a @@ -51,23 +51,22 @@ option( ENABLE_PYTHON "Build and install the Python wrappers" option( BUILD_SHARED_LIBS "Build shared libraries" ON ) option( ERT_USE_OPENMP "Use OpenMP" OFF ) option( RST_DOC "Build RST documentation" OFF) -option( ERT_BUILD_CXX "Build some CXX wrappers" ON) option( USE_RPATH "Don't strip RPATH from libraries and binaries" OFF) option( INSTALL_ERT_LEGACY "Add ert legacy wrappers" OFF) -set(STATOIL_TESTDATA_ROOT "" CACHE PATH "Root to Statoil internal testdata") -if (EXISTS ${STATOIL_TESTDATA_ROOT}) - set( LINK "${CMAKE_CURRENT_SOURCE_DIR}/test-data/Statoil" ) +set(EQUINOR_TESTDATA_ROOT "" CACHE PATH "Root to Equinor internal testdata") +if (EXISTS ${EQUINOR_TESTDATA_ROOT}) + set( LINK "${CMAKE_CURRENT_SOURCE_DIR}/test-data/Equinor" ) if (EXISTS ${LINK}) EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E remove "${LINK}") endif() - EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${STATOIL_TESTDATA_ROOT}" "${LINK}") - message(STATUS "Linking testdata: ${LINK} -> ${STATOIL_TESTDATA_ROOT}") + EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${EQUINOR_TESTDATA_ROOT}" "${LINK}") + message(STATUS "Linking testdata: ${LINK} -> ${EQUINOR_TESTDATA_ROOT}") - set(_statoil_test_data ${CMAKE_SOURCE_DIR}/test-data/Statoil) - set(_eclpath ${_statoil_test_data}/ECLIPSE) - set(_geopath ${_statoil_test_data}/Geometry) + set(_equinor_test_data ${CMAKE_SOURCE_DIR}/test-data/Equinor) + set(_eclpath ${_equinor_test_data}/ECLIPSE) + set(_geopath ${_equinor_test_data}/Geometry) endif() @@ -116,7 +115,7 @@ endif() # Treat warnings as errors if not on Windows if (NOT ERT_WINDOWS) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wno-unknown-pragmas ") - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wno-unused-result -Wno-unused-parameter" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wfatal-errors -Wall -Wno-unknown-pragmas -Wno-unused-result -Wno-unused-parameter" ) endif() if (MSVC) @@ -339,11 +338,6 @@ if (ENABLE_PYTHON) # fails in the python/CMakeLists.txt file the ENABLE_PYTHON # will be set to OFF. add_subdirectory( python ) - - if(RST_DOC) - add_subdirectory( docs ) - endif() - endif() if (ENABLE_PYTHON) @@ -352,9 +346,6 @@ if (ENABLE_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) diff --git a/ThirdParty/Ert/README.md b/ThirdParty/Ert/README.md index 07d72dec3a..37cb5a42dd 100644 --- a/ThirdParty/Ert/README.md +++ b/ThirdParty/Ert/README.md @@ -1,4 +1,4 @@ -# libecl [![Build Status](https://travis-ci.org/Statoil/libecl.svg?branch=master)](https://travis-ci.org/Statoil/libecl) +# libecl [![Build Status](https://travis-ci.org/Equinor/libecl.svg?branch=master)](https://travis-ci.org/Equinor/libecl) *libecl* is a package for reading and writing the result files from @@ -11,7 +11,7 @@ is a portability layer which ensures that most of the functionality is available on *Windows*. The main functionality is written in C/C++, and should typically be linked in in other compiled programs. *libecl* was initially developed as part of the [Ensemble Reservoir -Tool](http://github.com/Statoil/ert), other applications using +Tool](http://github.com/Equinor/ert), other applications using *libecl* are the reservoir simulator flow and Resinsight from the [OPM project](http://github.com/OPM/). @@ -30,7 +30,7 @@ configured with `-DCMAKE_INSTALL_PREFIX=/path/to/install`. *libecl* uses CMake as build system: ```bash -git clone https://github.com/Statoil/libecl +git clone https://github.com/Equinor/libecl cd libecl mkdir build cd build @@ -50,7 +50,7 @@ rudimentary "build system" which does a basic Python syntax check and configures files to correctly set up the interaction between the Python classes and the shared libraries built from the C code: ```bash -git clone https://github.com/Statoil/libecl +git clone https://github.com/Equinor/libecl cd libecl sudo pip install -r requirements.txt mkdir build @@ -78,5 +78,6 @@ fopt = summary.numpy_vector("FOPT") ``` +The installation with Python enabled is described in a [YouTube video](https://www.youtube.com/watch?v=Qqy1vA1PSk8) by Carl Fredrik Berg. [1]: The exact paths here will depend on your system and Python version. The example given is for a RedHat system with Python version 2.7. diff --git a/ThirdParty/Ert/WINDOWS.md b/ThirdParty/Ert/WINDOWS.md new file mode 100644 index 0000000000..2bfb46b95b --- /dev/null +++ b/ThirdParty/Ert/WINDOWS.md @@ -0,0 +1,27 @@ +# Compiling and Installing **_libecl_** on Windows + +## Prerequisits: +* Python 2.7 or 3.x https://www.python.org/ or https://anaconda.org/ +* Microsoft Visual Studio https://visualstudio.microsoft.com/downloads/ +* Local copy of **_libecl_** + +## Instructions: +1. Download or clone the **_libecl_** Github repository to your local disk. + +2. Python 2.7 or 3.x installation + - Download a python instalation or a python environment solution such as Anaconda. + +3. Download and install Microsoft Visual Studio . At a minimum **_libecl_** requires the VS Studio packages for cmake, msbuild, c and c++ compilers (CL.exe). + +4. Open a MSVC command prompt such as _x64 Native Tools Command Prompt for VS 2017_ from your start menu. In the open prompt, navigate to the **_libecl_** source directory you created in step 1. Use the Python package manager **pip** to install **_libecl_** requirements via `pip install -r requirements.txt`. If Python is not accessible from the prompt it may be necessary to add the Python environment location to your system path variable `PATH`. + +5. Execute the build commands with the desired CMAKE parameters from `README.md`. The cmake generator can be _`NMake Makefiles`_ , _`Ninja`_ or an appropriate version of _`MSVC`_. For the availble options type `cmake -G` in the MSVC command prompt. + + An example build and install is provided below where %VARIABLE% are user defined directory paths: +~~~~ + cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=%INSTALLPATH% -DBUILD_SHARED_LIBS="ON" -DENABLE_PYTHON="ON" -DCMAKE_BUILD_TYPE="Release" %SOURCEPATH% + cmake --build %BUILDPATH% --config Release --target install +~~~~ +6. For **_libecl_** to be accessible in Python the `%INSTALLPATH%\lib\pythonX.Y\site-package` and Python subdirectories must be added to the `PATH` and `PYTHONPATH` variables. Where `pythonx.y` is the current Python version _e.g._ (`python2.7`, `python3.6` _etc._) . + +8. Open a Python interactive session and run `import ecl` to check that the install and paths are now set. \ No newline at end of file diff --git a/ThirdParty/Ert/Windows.txt b/ThirdParty/Ert/Windows.txt deleted file mode 100644 index 7eda76b091..0000000000 --- a/ThirdParty/Ert/Windows.txt +++ /dev/null @@ -1,90 +0,0 @@ -Preparations: -------------- - -1. Install the CMake build system from www.cmake.org - -2. Install the MinGW and MSYS packages from www.mingw.org - this a - collection of gnu tools built for windows. Observe that these tools - behave like they do on linux, but they are native windows - applications and the compilers produce native windows binaries, not - like Cygwin which is based on a portability layer. - - Make sure to install at least the C and Fortran compilers. - -3. Install lapack; download and install instructions can be found on - http://icl.cs.utk.edu/lapack-for-windows/ The text says that you - will need the Intel Fortran compiler, but the Fortran compiler from - MinGW works fine. The distribution contains a cmake CMakeLists.txt - file, and build with Cmake is easy altough time consuming. - - To make sure the system can find your libraries you should update - the windows PATH variable to include the location of your - libblas.dll and liblapack.dll files; if you fail to do this CMake - will fail to generate a valid set of makefiles for building libutil - and libecl. - - -Building libecl / libutil -------------------------- - -1. Go to the root directory of the ert distribution and create a - directory to hold the files created by the build - - e.g. 'tmp-build'. - -2. Open the cmake gui and give the path to the source (i.e. the root - of the ert distribution) and the path to the build directory. - -3. Press the [Configure] button and select the "MSys Makefiles" - option. Cmake will inspect your system and set build configuration - variables accordingly. Cmake will fail with a beep and large red - warnings. Scroll down to the variables: - - USE_LSF - USE_PTHREAD - USE_ZLIB - - and uncheck them. In addition you might want to modify some other - variables? Press the [Configure] button again, and then finally the - [Generate] button to create makefiles. - -4. Start up the MSys shell, go to the build directory, - e.g. 'tmp-build', and type: - - make ; make install - - :-) - - -Using from VisualStudio ------------------------ -The ERT code itself can unfortunately not be compiled with the -VisualStudio C++ compiler, however you can link against the ert -libraries. In that case you will need the dummy header file -VisualStudio/stdbool.h - - - -About the portabaility and features ------------------------------------ - -The libecl library is virtually unmodified for compiling on windows, -but the libutil library (in particular the util.c file) has quite many - - #ifdef HAVE_FEATUREXX - - #endif - -codeblocks. The symbols HAVE_FEATUREXX are defined during the CMake -configure process. The system inspection is linux centric in the sense -that the features it is checked for are mostly present/defined on -linux. If FEATUREXX is not present it is sometimes completely ignore, -e.g. pthreads, or a windows alternative is compiled in. In the case of -windows alternative it is just assumed that the feature in question is -present on the other (i.e. Windows) platform. - - - - - - - diff --git a/ThirdParty/Ert/applications/CMakeLists.txt b/ThirdParty/Ert/applications/CMakeLists.txt index d2a2ed6e8c..37b624e75f 100644 --- a/ThirdParty/Ert/applications/CMakeLists.txt +++ b/ThirdParty/Ert/applications/CMakeLists.txt @@ -1,10 +1,10 @@ project(libecl-applications) if (BUILD_APPLICATIONS) - add_executable(sum_write ecl/sum_write.c) + add_executable(sum_write ecl/sum_write.cpp) add_executable(make_grid ecl/make_grid.c) add_executable(grdecl_grid ecl/grdecl_grid.c) - add_executable(summary ecl/view_summary.c) + add_executable(summary ecl/view_summary.cpp) target_link_libraries(sum_write ecl) target_link_libraries(make_grid ecl) target_link_libraries(grdecl_grid ecl) @@ -13,16 +13,16 @@ if (BUILD_APPLICATIONS) list(APPEND apps make_grid grdecl_grid summary) - foreach (app ecl_pack - ecl_unpack - kw_extract - grid_info - grid_dump - grid_dump_ascii - select_test - load_test + foreach (app ecl_pack.c + ecl_unpack.c + kw_extract.cpp + grid_info.c + grid_dump.c + grid_dump_ascii.c + select_test.c + load_test.c ) - add_executable(${app} ecl/${app}.c) + add_executable(${app} ecl/${app}) target_link_libraries(${app} ecl) list(APPEND apps ${app}) if (ERT_LINUX) @@ -71,7 +71,7 @@ if (BUILD_APPLICATIONS) endif() if (BUILD_ECL_SUMMARY) - add_executable(ecl_summary ecl/view_summary.c) + add_executable(ecl_summary ecl/view_summary.cpp) target_link_libraries(ecl_summary ecl) list(APPEND apps ecl_summary) diff --git a/ThirdParty/Ert/applications/ecl/convert.c b/ThirdParty/Ert/applications/ecl/convert.c index 104a432b3f..f593c283f6 100644 --- a/ThirdParty/Ert/applications/ecl/convert.c +++ b/ThirdParty/Ert/applications/ecl/convert.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'convert.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/ecl_pack.c b/ThirdParty/Ert/applications/ecl/ecl_pack.c index 9cd98fc5a3..337a327577 100644 --- a/ThirdParty/Ert/applications/ecl/ecl_pack.c +++ b/ThirdParty/Ert/applications/ecl/ecl_pack.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_pack.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/ecl_quantile.c b/ThirdParty/Ert/applications/ecl/ecl_quantile.c index e98ea5d1e6..116006eef5 100644 --- a/ThirdParty/Ert/applications/ecl/ecl_quantile.c +++ b/ThirdParty/Ert/applications/ecl/ecl_quantile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_quantile.c' is part of ERT - Ensemble based Reservoir Tool. @@ -812,7 +812,6 @@ void usage() { printf("All filenames in the configuration file will be interpreted relative to\n"); printf("the location of the configuration file, i.e. irrespective of the current\n"); printf("working directory when invoking the ecl_quantile program.\n\n"); - printf("ecl_quantile is written by Joakim Hove / joaho@statoil.com / 92 68 57 04.\n"); exit(0); } diff --git a/ThirdParty/Ert/applications/ecl/ecl_unpack.c b/ThirdParty/Ert/applications/ecl/ecl_unpack.c index fa08a9042f..87f9c2dae3 100644 --- a/ThirdParty/Ert/applications/ecl/ecl_unpack.c +++ b/ThirdParty/Ert/applications/ecl/ecl_unpack.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_unpack.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grdecl_grid.c b/ThirdParty/Ert/applications/ecl/grdecl_grid.c index f961118ef6..672bba80a1 100644 --- a/ThirdParty/Ert/applications/ecl/grdecl_grid.c +++ b/ThirdParty/Ert/applications/ecl/grdecl_grid.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'grdecl_grid.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grdecl_test.c b/ThirdParty/Ert/applications/ecl/grdecl_test.c index 8e73a7db4c..2646a13083 100644 --- a/ThirdParty/Ert/applications/ecl/grdecl_test.c +++ b/ThirdParty/Ert/applications/ecl/grdecl_test.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'grdecl_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grid_dump.c b/ThirdParty/Ert/applications/ecl/grid_dump.c index 8d405a2323..592d328ba1 100644 --- a/ThirdParty/Ert/applications/ecl/grid_dump.c +++ b/ThirdParty/Ert/applications/ecl/grid_dump.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'grid_info.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grid_dump_ascii.c b/ThirdParty/Ert/applications/ecl/grid_dump_ascii.c index e9e05964be..c639d7bc1a 100644 --- a/ThirdParty/Ert/applications/ecl/grid_dump_ascii.c +++ b/ThirdParty/Ert/applications/ecl/grid_dump_ascii.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'grid_dump_ascii.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grid_info.c b/ThirdParty/Ert/applications/ecl/grid_info.c index 9754a109f0..c191e77cee 100644 --- a/ThirdParty/Ert/applications/ecl/grid_info.c +++ b/ThirdParty/Ert/applications/ecl/grid_info.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'grid_info.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/grid_layer.c b/ThirdParty/Ert/applications/ecl/grid_layer.c index 05b5d2875e..8f6a11189d 100644 --- a/ThirdParty/Ert/applications/ecl/grid_layer.c +++ b/ThirdParty/Ert/applications/ecl/grid_layer.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'grid_layer.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/key_list.c b/ThirdParty/Ert/applications/ecl/key_list.c index e1ab0bb831..6dbb6bb419 100644 --- a/ThirdParty/Ert/applications/ecl/key_list.c +++ b/ThirdParty/Ert/applications/ecl/key_list.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'key_list.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/kw_extract.c b/ThirdParty/Ert/applications/ecl/kw_extract.cpp similarity index 98% rename from ThirdParty/Ert/applications/ecl/kw_extract.c rename to ThirdParty/Ert/applications/ecl/kw_extract.cpp index 9247ff073a..1b7db47b62 100644 --- a/ThirdParty/Ert/applications/ecl/kw_extract.c +++ b/ThirdParty/Ert/applications/ecl/kw_extract.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'kw_extract.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/kw_list.c b/ThirdParty/Ert/applications/ecl/kw_list.c index 482c3c096c..7f159cfda0 100644 --- a/ThirdParty/Ert/applications/ecl/kw_list.c +++ b/ThirdParty/Ert/applications/ecl/kw_list.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'kw_list.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/load_test.c b/ThirdParty/Ert/applications/ecl/load_test.c index 9a02887de2..669a8a90a1 100644 --- a/ThirdParty/Ert/applications/ecl/load_test.c +++ b/ThirdParty/Ert/applications/ecl/load_test.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'load_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/make_grid.c b/ThirdParty/Ert/applications/ecl/make_grid.c index f3c7adfd4e..636608cf7b 100644 --- a/ThirdParty/Ert/applications/ecl/make_grid.c +++ b/ThirdParty/Ert/applications/ecl/make_grid.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'make_grid.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/run_gravity.c b/ThirdParty/Ert/applications/ecl/run_gravity.c index f2ea723750..d0b3c17fca 100644 --- a/ThirdParty/Ert/applications/ecl/run_gravity.c +++ b/ThirdParty/Ert/applications/ecl/run_gravity.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'run_gravity.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/select_test.c b/ThirdParty/Ert/applications/ecl/select_test.c index 61acc18034..f23021f483 100644 --- a/ThirdParty/Ert/applications/ecl/select_test.c +++ b/ThirdParty/Ert/applications/ecl/select_test.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'select_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/sum_write.c b/ThirdParty/Ert/applications/ecl/sum_write.cpp similarity index 96% rename from ThirdParty/Ert/applications/ecl/sum_write.c rename to ThirdParty/Ert/applications/ecl/sum_write.cpp index 77234e4800..3bdf552d56 100644 --- a/ThirdParty/Ert/applications/ecl/sum_write.c +++ b/ThirdParty/Ert/applications/ecl/sum_write.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'sum_write' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify @@ -223,7 +223,7 @@ int main( int argc , char ** argv) { /* The return value from the ecl_sum_add_var() function is an - smspec_node_type instance (implemented in file smspec_node.c); + ecl::smspec_node instance (implemented in file smspec_node.c); which is essentially a struct holding header information about this varible. There are several options on how to handle the return value from the ecl_sum_add_var() function; which affect how @@ -243,8 +243,8 @@ int main( int argc , char ** argv) { */ - smspec_node_type * wwct_wellx = ecl_sum_add_var( ecl_sum , "WWCT" , NULL , 0 , "(1)" , 0.0); - smspec_node_type * wopr_wellx = ecl_sum_add_var( ecl_sum , "WOPR" , NULL , 0 , "Barrels" , 0.0); + const ecl::smspec_node * wwct_wellx = ecl_sum_add_var( ecl_sum , "WWCT" , NULL , 0 , "(1)" , 0.0); + const ecl::smspec_node * wopr_wellx = ecl_sum_add_var( ecl_sum , "WOPR" , NULL , 0 , "Barrels" , 0.0); { @@ -297,8 +297,8 @@ int main( int argc , char ** argv) { We can use the smspec_node value from the ecl_sum_add_var() function directly: */ - ecl_sum_tstep_set_from_node( tstep , wwct_wellx , sim_days ); - ecl_sum_tstep_set_from_node( tstep, wopr_wellx, sim_days * 100); + ecl_sum_tstep_set_from_node( tstep , *wwct_wellx , sim_days ); + ecl_sum_tstep_set_from_node( tstep, *wopr_wellx, sim_days * 100); } } } diff --git a/ThirdParty/Ert/applications/ecl/summary2csv2.c b/ThirdParty/Ert/applications/ecl/summary2csv2.c index 7655f1f02b..6ffae8c815 100644 --- a/ThirdParty/Ert/applications/ecl/summary2csv2.c +++ b/ThirdParty/Ert/applications/ecl/summary2csv2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'summary2csv2.c' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify diff --git a/ThirdParty/Ert/applications/ecl/view_restart.c b/ThirdParty/Ert/applications/ecl/view_restart.c index 7b18b622c6..16217677d5 100644 --- a/ThirdParty/Ert/applications/ecl/view_restart.c +++ b/ThirdParty/Ert/applications/ecl/view_restart.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'view_restart.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/view_rft.c b/ThirdParty/Ert/applications/ecl/view_rft.c index 358c8bf2d5..ffe43131da 100644 --- a/ThirdParty/Ert/applications/ecl/view_rft.c +++ b/ThirdParty/Ert/applications/ecl/view_rft.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'view_rft.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/ecl/view_summary.c b/ThirdParty/Ert/applications/ecl/view_summary.cpp similarity index 97% rename from ThirdParty/Ert/applications/ecl/view_summary.c rename to ThirdParty/Ert/applications/ecl/view_summary.cpp index 986f390db4..e139b44563 100644 --- a/ThirdParty/Ert/applications/ecl/view_summary.c +++ b/ThirdParty/Ert/applications/ecl/view_summary.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'view_summary.c' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify @@ -110,10 +110,7 @@ void print_help_and_exit() { printf("\n"); printf("* If the extension corresponds to a unified file, summary.x will\n"); printf(" only look for unified files.\n"); - printf("\n"); - printf("\n"); - printf("Contact Joakim Hove / joaho@statoil.com / 92 68 57 04 for bugs\n"); - printf("and feature requests.\n"); + printf("\n"); exit(1); } diff --git a/ThirdParty/Ert/applications/ecl/vprofile.c b/ThirdParty/Ert/applications/ecl/vprofile.c index e6edb40b55..5264fcca97 100644 --- a/ThirdParty/Ert/applications/ecl/vprofile.c +++ b/ThirdParty/Ert/applications/ecl/vprofile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vprofile.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/man/man1/ecl_summary.1 b/ThirdParty/Ert/applications/man/man1/ecl_summary.1 index 66b5ad9351..f881dc0efc 100644 --- a/ThirdParty/Ert/applications/man/man1/ecl_summary.1 +++ b/ThirdParty/Ert/applications/man/man1/ecl_summary.1 @@ -99,9 +99,6 @@ will only look for unformatted files. .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 @@ -183,6 +180,6 @@ will only look for unformatted files. .IP only look for unified files. .PP -Contact Joakim Hove / joaho@statoil.com / 92 68 57 04 for bugs +Contact Joakim Hove / joaho@equinor.com / 92 68 57 04 for bugs and feature requests. diff --git a/ThirdParty/Ert/applications/well/ri_well_test.c b/ThirdParty/Ert/applications/well/ri_well_test.c index 66e4b8d830..cc46160617 100644 --- a/ThirdParty/Ert/applications/well/ri_well_test.c +++ b/ThirdParty/Ert/applications/well/ri_well_test.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_CF_dump.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/well/segment_info.c b/ThirdParty/Ert/applications/well/segment_info.c index 2a445c2637..0d6e403273 100644 --- a/ThirdParty/Ert/applications/well/segment_info.c +++ b/ThirdParty/Ert/applications/well/segment_info.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'segment_info.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/applications/well/well_CF_dump.c b/ThirdParty/Ert/applications/well/well_CF_dump.c index 433aab6559..1fe2749cdc 100644 --- a/ThirdParty/Ert/applications/well/well_CF_dump.c +++ b/ThirdParty/Ert/applications/well/well_CF_dump.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_CF_dump.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/appveyor.yml b/ThirdParty/Ert/appveyor.yml index 73887395f0..c1dddec4e4 100644 --- a/ThirdParty/Ert/appveyor.yml +++ b/ThirdParty/Ert/appveyor.yml @@ -19,7 +19,6 @@ build_script: - cmake %W64% -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_PYTHON=ON - -DERT_BUILD_CXX=OFF -DBUILD_APPLICATIONS=ON - cmake --build . --config %configuration% --target install diff --git a/ThirdParty/Ert/bin/summary_resample b/ThirdParty/Ert/bin/summary_resample index eb6cf5521f..1a08006d2f 100644 --- a/ThirdParty/Ert/bin/summary_resample +++ b/ThirdParty/Ert/bin/summary_resample @@ -11,6 +11,7 @@ parser.add_argument("input_case", metavar="input_case", type=str) parser.add_argument("output_case", metavar="output_case", type=str) parser.add_argument("--num-timestep", type=int, default=50) parser.add_argument("--refcase", metavar="refcase", type=str) +parser.add_argument("--extrapolation", action="store_true") args = parser.parse_args() input_case = EclSum(args.input_case) @@ -23,5 +24,8 @@ else: end_time = input_case.get_end_time() time_points = TimeVector.create_linear(CTime(start_time), CTime(end_time), args.num_timestep) -output_case = input_case.resample(args.output_case, time_points) +output_case = input_case.resample(args.output_case, + time_points, + lower_extrapolation=args.extrapolation, + upper_extrapolation=args.extrapolation) output_case.fwrite( ) diff --git a/ThirdParty/Ert/config.sh b/ThirdParty/Ert/config.sh new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ThirdParty/Ert/debian/README.Debian b/ThirdParty/Ert/debian/README.Debian index ce79dec2d5..4660ad0d8e 100644 --- a/ThirdParty/Ert/debian/README.Debian +++ b/ThirdParty/Ert/debian/README.Debian @@ -7,7 +7,3 @@ working with ECLIPSE output files. The package contains functionality for reading, and partly writing, ECLIPSE INIT/GRID/EGRID/RFT and summary and restart files. There is also some functionality for working with .grdecl formatted ECLIPSE input files. - - -- Joakim Hove Wed, 23 Jan 2013 13:41:00 +0100 - - -- Arne Morten Kvarving Wed, 16 Jan 2013 11:21:17 +0100 diff --git a/ThirdParty/Ert/debian/changelog b/ThirdParty/Ert/debian/changelog index f12cdfca3a..71b218f1f9 100644 --- a/ThirdParty/Ert/debian/changelog +++ b/ThirdParty/Ert/debian/changelog @@ -1,4 +1,4 @@ -ecl (2018.10-rfinal-1~xenial) xenial; urgency=low +ecl (2018.10-rc1-1~xenial) xenial; urgency=low * New release diff --git a/ThirdParty/Ert/debian/copyright b/ThirdParty/Ert/debian/copyright index a8797ba46b..94d51ad9e4 100644 --- a/ThirdParty/Ert/debian/copyright +++ b/ThirdParty/Ert/debian/copyright @@ -3,7 +3,7 @@ Upstream-Name: libert.ecl Source: https://github.com/Ensembles/ert Files: * -Copyright: 2013 Statoil +Copyright: 2013 Equinor License: GPL-3+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ThirdParty/Ert/docs/CMakeLists.txt b/ThirdParty/Ert/docs/CMakeLists.txt deleted file mode 100644 index 833ce3a56e..0000000000 --- a/ThirdParty/Ert/docs/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -find_package(Sphinx REQUIRED) -if (SPHINX_FOUND) - 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 (ENABLE_PYTHON) - add_custom_target(api-doc ALL - COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/doc-src/code" - COMMAND sphinx-apidoc -e -o doc-src/API/python/ecl ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} - DEPENDS ecl - 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() - -INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/documentation DESTINATION ${CMAKE_INSTALL_PREFIX} ) diff --git a/ThirdParty/Ert/docs/code/C/index.rst b/ThirdParty/Ert/docs/code/C/index.rst deleted file mode 100644 index 60f6a764b1..0000000000 --- a/ThirdParty/Ert/docs/code/C/index.rst +++ /dev/null @@ -1,4 +0,0 @@ -Low level C libraries -===================== - -How to use the C libraries diff --git a/ThirdParty/Ert/docs/code/python/eclipse/API/index.rst b/ThirdParty/Ert/docs/code/python/eclipse/API/index.rst deleted file mode 100644 index 4e61a4fb95..0000000000 --- a/ThirdParty/Ert/docs/code/python/eclipse/API/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -The ert Python API -================== - -.. toctree:: - :maxdepth: 2 - - ../../API/python/ert - ../../API/python/ert_gui - diff --git a/ThirdParty/Ert/docs/code/python/examples/ert/index.rst b/ThirdParty/Ert/docs/code/python/examples/ert/index.rst deleted file mode 100644 index f7a37bfe3d..0000000000 --- a/ThirdParty/Ert/docs/code/python/examples/ert/index.rst +++ /dev/null @@ -1,3 +0,0 @@ -Working with full ert cases -=========================== - diff --git a/ThirdParty/Ert/docs/code/python/packages/geometry/index.rst b/ThirdParty/Ert/docs/code/python/packages/geometry/index.rst deleted file mode 100644 index 89c51ef2c5..0000000000 --- a/ThirdParty/Ert/docs/code/python/packages/geometry/index.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ert.geo package -=================== diff --git a/ThirdParty/Ert/docs/code/python/packages/util/index.rst b/ThirdParty/Ert/docs/code/python/packages/util/index.rst deleted file mode 100644 index 83bd652b28..0000000000 --- a/ThirdParty/Ert/docs/code/python/packages/util/index.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ert.util package -=================== diff --git a/ThirdParty/Ert/docs/code/python/packages/well/index.rst b/ThirdParty/Ert/docs/code/python/packages/well/index.rst deleted file mode 100644 index 9a3ea2c9a1..0000000000 --- a/ThirdParty/Ert/docs/code/python/packages/well/index.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ert.well package -==================== diff --git a/ThirdParty/Ert/docs/course/config/config.ert b/ThirdParty/Ert/docs/course/config/config.ert deleted file mode 100644 index ec14cc6def..0000000000 --- a/ThirdParty/Ert/docs/course/config/config.ert +++ /dev/null @@ -1,34 +0,0 @@ -QUEUE_SYSTEM LOCAL - -JOBNAME SNAKE_OIL_%d -NUM_REALIZATIONS 25 - -DEFINE storage/ - -RUNPATH_FILE directory/test_runpath_list.txt -RUNPATH /runpath/realisation-%d/iter-%d -ENSPATH /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 - diff --git a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_DIFF b/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_DIFF deleted file mode 100644 index 98a867d959..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_DIFF +++ /dev/null @@ -1,4 +0,0 @@ -STDOUT snake_oil_diff.stdout -STDERR snake_oil_diff.stderr - -EXECUTABLE snake_oil_diff.py \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_NPV b/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_NPV deleted file mode 100644 index 887830c756..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_NPV +++ /dev/null @@ -1,4 +0,0 @@ -STDOUT snake_oil_npv.stdout -STDERR snake_oil_npv.stderr - -EXECUTABLE snake_oil_npv.py \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_SIMULATOR b/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_SIMULATOR deleted file mode 100644 index b4b7f9928f..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/SNAKE_OIL_SIMULATOR +++ /dev/null @@ -1,4 +0,0 @@ -STDOUT snake_oil.stdout -STDERR snake_oil.stderr - -EXECUTABLE snake_oil_simulator.py \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_diff.py b/ThirdParty/Ert/docs/course/config/jobs/snake_oil_diff.py deleted file mode 100644 index 51ef5d472f..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_diff.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python -from ecl.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"]) - - - - diff --git a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_npv.py b/ThirdParty/Ert/docs/course/config/jobs/snake_oil_npv.py deleted file mode 100644 index 126c917725..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_npv.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python -from ecl.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) - diff --git a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_simulator.py b/ThirdParty/Ert/docs/course/config/jobs/snake_oil_simulator.py deleted file mode 100644 index 40b4d4a6a1..0000000000 --- a/ThirdParty/Ert/docs/course/config/jobs/snake_oil_simulator.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python -from datetime import datetime -import os -import sys - -from ecl.ecl import EclSum, EclSumTStep -from ecl.test import ExtendedTestCase - -try: - from synthesizer import OilSimulator -except ImportError as e: - share_lib_path = ExtendedTestCase.createShareRoot("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) diff --git a/ThirdParty/Ert/docs/course/config/parameters/snake_oil_parameters.txt b/ThirdParty/Ert/docs/course/config/parameters/snake_oil_parameters.txt deleted file mode 100644 index 64573d0058..0000000000 --- a/ThirdParty/Ert/docs/course/config/parameters/snake_oil_parameters.txt +++ /dev/null @@ -1,11 +0,0 @@ -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 - diff --git a/ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.SMSPEC b/ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.SMSPEC deleted file mode 100644 index 5a29e043b2d3740b3774a9deda10d6ead8937467..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1416 zcmeHHF;2uV5ZrJQAaq4aN>g1y1=WcPlbBqDVn>co);-`__|ScYN6=F71b%SrdN(1Y zLZV55qt#?K-tlC!3IOEZbV2)|0N}jXXpfj<+^at>(jcv}Zj9}e!u!+O217ZFONSK7U=mE z;N%Tw;6O96wRIr#)0rssF1?d|dEV2z{p0WY(9cBrvz9twUl*g9SR&6j&fXE1Uwh7I Ao&W#< diff --git a/ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.UNSMRY b/ThirdParty/Ert/docs/course/config/refcase/SNAKE_OIL_FIELD.UNSMRY deleted file mode 100644 index dfa04f80027b57788211c785cd6a5203769ee63b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 455200 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¨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 z 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 WJ%7nEk$S+7J3C!R$^J5S{Cbw? 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

IDEVE%a% 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 diff --git a/ThirdParty/Ert/docs/course/config/refcase/refcase_readme.txt b/ThirdParty/Ert/docs/course/config/refcase/refcase_readme.txt deleted file mode 100644 index a3d0fe6058..0000000000 --- a/ThirdParty/Ert/docs/course/config/refcase/refcase_readme.txt +++ /dev/null @@ -1 +0,0 @@ -To create a refcase run the snake_oil_simulator.py job with the this as working directory. \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/refcase/seed.txt b/ThirdParty/Ert/docs/course/config/refcase/seed.txt deleted file mode 100644 index 0009f6e89a..0000000000 --- a/ThirdParty/Ert/docs/course/config/refcase/seed.txt +++ /dev/null @@ -1 +0,0 @@ -SEED:268776 \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/refcase/snake_oil_params.txt b/ThirdParty/Ert/docs/course/config/refcase/snake_oil_params.txt deleted file mode 100644 index 3868522924..0000000000 --- a/ThirdParty/Ert/docs/course/config/refcase/snake_oil_params.txt +++ /dev/null @@ -1,10 +0,0 @@ -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 diff --git a/ThirdParty/Ert/docs/course/config/refcase/time_map.txt b/ThirdParty/Ert/docs/course/config/refcase/time_map.txt deleted file mode 100644 index d54b4293ae..0000000000 --- a/ThirdParty/Ert/docs/course/config/refcase/time_map.txt +++ /dev/null @@ -1,2000 +0,0 @@ -01/01/2010 -02/01/2010 -03/01/2010 -04/01/2010 -05/01/2010 -06/01/2010 -07/01/2010 -08/01/2010 -09/01/2010 -10/01/2010 -11/01/2010 -12/01/2010 -13/01/2010 -14/01/2010 -15/01/2010 -16/01/2010 -17/01/2010 -18/01/2010 -19/01/2010 -20/01/2010 -21/01/2010 -22/01/2010 -23/01/2010 -24/01/2010 -25/01/2010 -26/01/2010 -27/01/2010 -28/01/2010 -29/01/2010 -30/01/2010 -31/01/2010 -01/02/2010 -02/02/2010 -03/02/2010 -04/02/2010 -05/02/2010 -06/02/2010 -07/02/2010 -08/02/2010 -09/02/2010 -10/02/2010 -11/02/2010 -12/02/2010 -13/02/2010 -14/02/2010 -15/02/2010 -16/02/2010 -17/02/2010 -18/02/2010 -19/02/2010 -20/02/2010 -21/02/2010 -22/02/2010 -23/02/2010 -24/02/2010 -25/02/2010 -26/02/2010 -27/02/2010 -28/02/2010 -01/03/2010 -02/03/2010 -03/03/2010 -04/03/2010 -05/03/2010 -06/03/2010 -07/03/2010 -08/03/2010 -09/03/2010 -10/03/2010 -11/03/2010 -12/03/2010 -13/03/2010 -14/03/2010 -15/03/2010 -16/03/2010 -17/03/2010 -18/03/2010 -19/03/2010 -20/03/2010 -21/03/2010 -22/03/2010 -23/03/2010 -24/03/2010 -25/03/2010 -26/03/2010 -27/03/2010 -28/03/2010 -29/03/2010 -30/03/2010 -31/03/2010 -01/04/2010 -02/04/2010 -03/04/2010 -04/04/2010 -05/04/2010 -06/04/2010 -07/04/2010 -08/04/2010 -09/04/2010 -10/04/2010 -11/04/2010 -12/04/2010 -13/04/2010 -14/04/2010 -15/04/2010 -16/04/2010 -17/04/2010 -18/04/2010 -19/04/2010 -20/04/2010 -21/04/2010 -22/04/2010 -23/04/2010 -24/04/2010 -25/04/2010 -26/04/2010 -27/04/2010 -28/04/2010 -29/04/2010 -30/04/2010 -01/05/2010 -02/05/2010 -03/05/2010 -04/05/2010 -05/05/2010 -06/05/2010 -07/05/2010 -08/05/2010 -09/05/2010 -10/05/2010 -11/05/2010 -12/05/2010 -13/05/2010 -14/05/2010 -15/05/2010 -16/05/2010 -17/05/2010 -18/05/2010 -19/05/2010 -20/05/2010 -21/05/2010 -22/05/2010 -23/05/2010 -24/05/2010 -25/05/2010 -26/05/2010 -27/05/2010 -28/05/2010 -29/05/2010 -30/05/2010 -31/05/2010 -01/06/2010 -02/06/2010 -03/06/2010 -04/06/2010 -05/06/2010 -06/06/2010 -07/06/2010 -08/06/2010 -09/06/2010 -10/06/2010 -11/06/2010 -12/06/2010 -13/06/2010 -14/06/2010 -15/06/2010 -16/06/2010 -17/06/2010 -18/06/2010 -19/06/2010 -20/06/2010 -21/06/2010 -22/06/2010 -23/06/2010 -24/06/2010 -25/06/2010 -26/06/2010 -27/06/2010 -28/06/2010 -29/06/2010 -30/06/2010 -01/07/2010 -02/07/2010 -03/07/2010 -04/07/2010 -05/07/2010 -06/07/2010 -07/07/2010 -08/07/2010 -09/07/2010 -10/07/2010 -11/07/2010 -12/07/2010 -13/07/2010 -14/07/2010 -15/07/2010 -16/07/2010 -17/07/2010 -18/07/2010 -19/07/2010 -20/07/2010 -21/07/2010 -22/07/2010 -23/07/2010 -24/07/2010 -25/07/2010 -26/07/2010 -27/07/2010 -28/07/2010 -29/07/2010 -30/07/2010 -31/07/2010 -01/08/2010 -02/08/2010 -03/08/2010 -04/08/2010 -05/08/2010 -06/08/2010 -07/08/2010 -08/08/2010 -09/08/2010 -10/08/2010 -11/08/2010 -12/08/2010 -13/08/2010 -14/08/2010 -15/08/2010 -16/08/2010 -17/08/2010 -18/08/2010 -19/08/2010 -20/08/2010 -21/08/2010 -22/08/2010 -23/08/2010 -24/08/2010 -25/08/2010 -26/08/2010 -27/08/2010 -28/08/2010 -29/08/2010 -30/08/2010 -31/08/2010 -01/09/2010 -02/09/2010 -03/09/2010 -04/09/2010 -05/09/2010 -06/09/2010 -07/09/2010 -08/09/2010 -09/09/2010 -10/09/2010 -11/09/2010 -12/09/2010 -13/09/2010 -14/09/2010 -15/09/2010 -16/09/2010 -17/09/2010 -18/09/2010 -19/09/2010 -20/09/2010 -21/09/2010 -22/09/2010 -23/09/2010 -24/09/2010 -25/09/2010 -26/09/2010 -27/09/2010 -28/09/2010 -29/09/2010 -30/09/2010 -01/10/2010 -02/10/2010 -03/10/2010 -04/10/2010 -05/10/2010 -06/10/2010 -07/10/2010 -08/10/2010 -09/10/2010 -10/10/2010 -11/10/2010 -12/10/2010 -13/10/2010 -14/10/2010 -15/10/2010 -16/10/2010 -17/10/2010 -18/10/2010 -19/10/2010 -20/10/2010 -21/10/2010 -22/10/2010 -23/10/2010 -24/10/2010 -25/10/2010 -26/10/2010 -27/10/2010 -28/10/2010 -29/10/2010 -30/10/2010 -31/10/2010 -01/11/2010 -02/11/2010 -03/11/2010 -04/11/2010 -05/11/2010 -06/11/2010 -07/11/2010 -08/11/2010 -09/11/2010 -10/11/2010 -11/11/2010 -12/11/2010 -13/11/2010 -14/11/2010 -15/11/2010 -16/11/2010 -17/11/2010 -18/11/2010 -19/11/2010 -20/11/2010 -21/11/2010 -22/11/2010 -23/11/2010 -24/11/2010 -25/11/2010 -26/11/2010 -27/11/2010 -28/11/2010 -29/11/2010 -30/11/2010 -01/12/2010 -02/12/2010 -03/12/2010 -04/12/2010 -05/12/2010 -06/12/2010 -07/12/2010 -08/12/2010 -09/12/2010 -10/12/2010 -11/12/2010 -12/12/2010 -13/12/2010 -14/12/2010 -15/12/2010 -16/12/2010 -17/12/2010 -18/12/2010 -19/12/2010 -20/12/2010 -21/12/2010 -22/12/2010 -23/12/2010 -24/12/2010 -25/12/2010 -26/12/2010 -27/12/2010 -28/12/2010 -29/12/2010 -30/12/2010 -31/12/2010 -01/01/2011 -02/01/2011 -03/01/2011 -04/01/2011 -05/01/2011 -06/01/2011 -07/01/2011 -08/01/2011 -09/01/2011 -10/01/2011 -11/01/2011 -12/01/2011 -13/01/2011 -14/01/2011 -15/01/2011 -16/01/2011 -17/01/2011 -18/01/2011 -19/01/2011 -20/01/2011 -21/01/2011 -22/01/2011 -23/01/2011 -24/01/2011 -25/01/2011 -26/01/2011 -27/01/2011 -28/01/2011 -29/01/2011 -30/01/2011 -31/01/2011 -01/02/2011 -02/02/2011 -03/02/2011 -04/02/2011 -05/02/2011 -06/02/2011 -07/02/2011 -08/02/2011 -09/02/2011 -10/02/2011 -11/02/2011 -12/02/2011 -13/02/2011 -14/02/2011 -15/02/2011 -16/02/2011 -17/02/2011 -18/02/2011 -19/02/2011 -20/02/2011 -21/02/2011 -22/02/2011 -23/02/2011 -24/02/2011 -25/02/2011 -26/02/2011 -27/02/2011 -28/02/2011 -01/03/2011 -02/03/2011 -03/03/2011 -04/03/2011 -05/03/2011 -06/03/2011 -07/03/2011 -08/03/2011 -09/03/2011 -10/03/2011 -11/03/2011 -12/03/2011 -13/03/2011 -14/03/2011 -15/03/2011 -16/03/2011 -17/03/2011 -18/03/2011 -19/03/2011 -20/03/2011 -21/03/2011 -22/03/2011 -23/03/2011 -24/03/2011 -25/03/2011 -26/03/2011 -27/03/2011 -28/03/2011 -29/03/2011 -30/03/2011 -31/03/2011 -01/04/2011 -02/04/2011 -03/04/2011 -04/04/2011 -05/04/2011 -06/04/2011 -07/04/2011 -08/04/2011 -09/04/2011 -10/04/2011 -11/04/2011 -12/04/2011 -13/04/2011 -14/04/2011 -15/04/2011 -16/04/2011 -17/04/2011 -18/04/2011 -19/04/2011 -20/04/2011 -21/04/2011 -22/04/2011 -23/04/2011 -24/04/2011 -25/04/2011 -26/04/2011 -27/04/2011 -28/04/2011 -29/04/2011 -30/04/2011 -01/05/2011 -02/05/2011 -03/05/2011 -04/05/2011 -05/05/2011 -06/05/2011 -07/05/2011 -08/05/2011 -09/05/2011 -10/05/2011 -11/05/2011 -12/05/2011 -13/05/2011 -14/05/2011 -15/05/2011 -16/05/2011 -17/05/2011 -18/05/2011 -19/05/2011 -20/05/2011 -21/05/2011 -22/05/2011 -23/05/2011 -24/05/2011 -25/05/2011 -26/05/2011 -27/05/2011 -28/05/2011 -29/05/2011 -30/05/2011 -31/05/2011 -01/06/2011 -02/06/2011 -03/06/2011 -04/06/2011 -05/06/2011 -06/06/2011 -07/06/2011 -08/06/2011 -09/06/2011 -10/06/2011 -11/06/2011 -12/06/2011 -13/06/2011 -14/06/2011 -15/06/2011 -16/06/2011 -17/06/2011 -18/06/2011 -19/06/2011 -20/06/2011 -21/06/2011 -22/06/2011 -23/06/2011 -24/06/2011 -25/06/2011 -26/06/2011 -27/06/2011 -28/06/2011 -29/06/2011 -30/06/2011 -01/07/2011 -02/07/2011 -03/07/2011 -04/07/2011 -05/07/2011 -06/07/2011 -07/07/2011 -08/07/2011 -09/07/2011 -10/07/2011 -11/07/2011 -12/07/2011 -13/07/2011 -14/07/2011 -15/07/2011 -16/07/2011 -17/07/2011 -18/07/2011 -19/07/2011 -20/07/2011 -21/07/2011 -22/07/2011 -23/07/2011 -24/07/2011 -25/07/2011 -26/07/2011 -27/07/2011 -28/07/2011 -29/07/2011 -30/07/2011 -31/07/2011 -01/08/2011 -02/08/2011 -03/08/2011 -04/08/2011 -05/08/2011 -06/08/2011 -07/08/2011 -08/08/2011 -09/08/2011 -10/08/2011 -11/08/2011 -12/08/2011 -13/08/2011 -14/08/2011 -15/08/2011 -16/08/2011 -17/08/2011 -18/08/2011 -19/08/2011 -20/08/2011 -21/08/2011 -22/08/2011 -23/08/2011 -24/08/2011 -25/08/2011 -26/08/2011 -27/08/2011 -28/08/2011 -29/08/2011 -30/08/2011 -31/08/2011 -01/09/2011 -02/09/2011 -03/09/2011 -04/09/2011 -05/09/2011 -06/09/2011 -07/09/2011 -08/09/2011 -09/09/2011 -10/09/2011 -11/09/2011 -12/09/2011 -13/09/2011 -14/09/2011 -15/09/2011 -16/09/2011 -17/09/2011 -18/09/2011 -19/09/2011 -20/09/2011 -21/09/2011 -22/09/2011 -23/09/2011 -24/09/2011 -25/09/2011 -26/09/2011 -27/09/2011 -28/09/2011 -29/09/2011 -30/09/2011 -01/10/2011 -02/10/2011 -03/10/2011 -04/10/2011 -05/10/2011 -06/10/2011 -07/10/2011 -08/10/2011 -09/10/2011 -10/10/2011 -11/10/2011 -12/10/2011 -13/10/2011 -14/10/2011 -15/10/2011 -16/10/2011 -17/10/2011 -18/10/2011 -19/10/2011 -20/10/2011 -21/10/2011 -22/10/2011 -23/10/2011 -24/10/2011 -25/10/2011 -26/10/2011 -27/10/2011 -28/10/2011 -29/10/2011 -30/10/2011 -31/10/2011 -01/11/2011 -02/11/2011 -03/11/2011 -04/11/2011 -05/11/2011 -06/11/2011 -07/11/2011 -08/11/2011 -09/11/2011 -10/11/2011 -11/11/2011 -12/11/2011 -13/11/2011 -14/11/2011 -15/11/2011 -16/11/2011 -17/11/2011 -18/11/2011 -19/11/2011 -20/11/2011 -21/11/2011 -22/11/2011 -23/11/2011 -24/11/2011 -25/11/2011 -26/11/2011 -27/11/2011 -28/11/2011 -29/11/2011 -30/11/2011 -01/12/2011 -02/12/2011 -03/12/2011 -04/12/2011 -05/12/2011 -06/12/2011 -07/12/2011 -08/12/2011 -09/12/2011 -10/12/2011 -11/12/2011 -12/12/2011 -13/12/2011 -14/12/2011 -15/12/2011 -16/12/2011 -17/12/2011 -18/12/2011 -19/12/2011 -20/12/2011 -21/12/2011 -22/12/2011 -23/12/2011 -24/12/2011 -25/12/2011 -26/12/2011 -27/12/2011 -28/12/2011 -29/12/2011 -30/12/2011 -31/12/2011 -01/01/2012 -02/01/2012 -03/01/2012 -04/01/2012 -05/01/2012 -06/01/2012 -07/01/2012 -08/01/2012 -09/01/2012 -10/01/2012 -11/01/2012 -12/01/2012 -13/01/2012 -14/01/2012 -15/01/2012 -16/01/2012 -17/01/2012 -18/01/2012 -19/01/2012 -20/01/2012 -21/01/2012 -22/01/2012 -23/01/2012 -24/01/2012 -25/01/2012 -26/01/2012 -27/01/2012 -28/01/2012 -29/01/2012 -30/01/2012 -31/01/2012 -01/02/2012 -02/02/2012 -03/02/2012 -04/02/2012 -05/02/2012 -06/02/2012 -07/02/2012 -08/02/2012 -09/02/2012 -10/02/2012 -11/02/2012 -12/02/2012 -13/02/2012 -14/02/2012 -15/02/2012 -16/02/2012 -17/02/2012 -18/02/2012 -19/02/2012 -20/02/2012 -21/02/2012 -22/02/2012 -23/02/2012 -24/02/2012 -25/02/2012 -26/02/2012 -27/02/2012 -28/02/2012 -29/02/2012 -01/03/2012 -02/03/2012 -03/03/2012 -04/03/2012 -05/03/2012 -06/03/2012 -07/03/2012 -08/03/2012 -09/03/2012 -10/03/2012 -11/03/2012 -12/03/2012 -13/03/2012 -14/03/2012 -15/03/2012 -16/03/2012 -17/03/2012 -18/03/2012 -19/03/2012 -20/03/2012 -21/03/2012 -22/03/2012 -23/03/2012 -24/03/2012 -25/03/2012 -26/03/2012 -27/03/2012 -28/03/2012 -29/03/2012 -30/03/2012 -31/03/2012 -01/04/2012 -02/04/2012 -03/04/2012 -04/04/2012 -05/04/2012 -06/04/2012 -07/04/2012 -08/04/2012 -09/04/2012 -10/04/2012 -11/04/2012 -12/04/2012 -13/04/2012 -14/04/2012 -15/04/2012 -16/04/2012 -17/04/2012 -18/04/2012 -19/04/2012 -20/04/2012 -21/04/2012 -22/04/2012 -23/04/2012 -24/04/2012 -25/04/2012 -26/04/2012 -27/04/2012 -28/04/2012 -29/04/2012 -30/04/2012 -01/05/2012 -02/05/2012 -03/05/2012 -04/05/2012 -05/05/2012 -06/05/2012 -07/05/2012 -08/05/2012 -09/05/2012 -10/05/2012 -11/05/2012 -12/05/2012 -13/05/2012 -14/05/2012 -15/05/2012 -16/05/2012 -17/05/2012 -18/05/2012 -19/05/2012 -20/05/2012 -21/05/2012 -22/05/2012 -23/05/2012 -24/05/2012 -25/05/2012 -26/05/2012 -27/05/2012 -28/05/2012 -29/05/2012 -30/05/2012 -31/05/2012 -01/06/2012 -02/06/2012 -03/06/2012 -04/06/2012 -05/06/2012 -06/06/2012 -07/06/2012 -08/06/2012 -09/06/2012 -10/06/2012 -11/06/2012 -12/06/2012 -13/06/2012 -14/06/2012 -15/06/2012 -16/06/2012 -17/06/2012 -18/06/2012 -19/06/2012 -20/06/2012 -21/06/2012 -22/06/2012 -23/06/2012 -24/06/2012 -25/06/2012 -26/06/2012 -27/06/2012 -28/06/2012 -29/06/2012 -30/06/2012 -01/07/2012 -02/07/2012 -03/07/2012 -04/07/2012 -05/07/2012 -06/07/2012 -07/07/2012 -08/07/2012 -09/07/2012 -10/07/2012 -11/07/2012 -12/07/2012 -13/07/2012 -14/07/2012 -15/07/2012 -16/07/2012 -17/07/2012 -18/07/2012 -19/07/2012 -20/07/2012 -21/07/2012 -22/07/2012 -23/07/2012 -24/07/2012 -25/07/2012 -26/07/2012 -27/07/2012 -28/07/2012 -29/07/2012 -30/07/2012 -31/07/2012 -01/08/2012 -02/08/2012 -03/08/2012 -04/08/2012 -05/08/2012 -06/08/2012 -07/08/2012 -08/08/2012 -09/08/2012 -10/08/2012 -11/08/2012 -12/08/2012 -13/08/2012 -14/08/2012 -15/08/2012 -16/08/2012 -17/08/2012 -18/08/2012 -19/08/2012 -20/08/2012 -21/08/2012 -22/08/2012 -23/08/2012 -24/08/2012 -25/08/2012 -26/08/2012 -27/08/2012 -28/08/2012 -29/08/2012 -30/08/2012 -31/08/2012 -01/09/2012 -02/09/2012 -03/09/2012 -04/09/2012 -05/09/2012 -06/09/2012 -07/09/2012 -08/09/2012 -09/09/2012 -10/09/2012 -11/09/2012 -12/09/2012 -13/09/2012 -14/09/2012 -15/09/2012 -16/09/2012 -17/09/2012 -18/09/2012 -19/09/2012 -20/09/2012 -21/09/2012 -22/09/2012 -23/09/2012 -24/09/2012 -25/09/2012 -26/09/2012 -27/09/2012 -28/09/2012 -29/09/2012 -30/09/2012 -01/10/2012 -02/10/2012 -03/10/2012 -04/10/2012 -05/10/2012 -06/10/2012 -07/10/2012 -08/10/2012 -09/10/2012 -10/10/2012 -11/10/2012 -12/10/2012 -13/10/2012 -14/10/2012 -15/10/2012 -16/10/2012 -17/10/2012 -18/10/2012 -19/10/2012 -20/10/2012 -21/10/2012 -22/10/2012 -23/10/2012 -24/10/2012 -25/10/2012 -26/10/2012 -27/10/2012 -28/10/2012 -29/10/2012 -30/10/2012 -31/10/2012 -01/11/2012 -02/11/2012 -03/11/2012 -04/11/2012 -05/11/2012 -06/11/2012 -07/11/2012 -08/11/2012 -09/11/2012 -10/11/2012 -11/11/2012 -12/11/2012 -13/11/2012 -14/11/2012 -15/11/2012 -16/11/2012 -17/11/2012 -18/11/2012 -19/11/2012 -20/11/2012 -21/11/2012 -22/11/2012 -23/11/2012 -24/11/2012 -25/11/2012 -26/11/2012 -27/11/2012 -28/11/2012 -29/11/2012 -30/11/2012 -01/12/2012 -02/12/2012 -03/12/2012 -04/12/2012 -05/12/2012 -06/12/2012 -07/12/2012 -08/12/2012 -09/12/2012 -10/12/2012 -11/12/2012 -12/12/2012 -13/12/2012 -14/12/2012 -15/12/2012 -16/12/2012 -17/12/2012 -18/12/2012 -19/12/2012 -20/12/2012 -21/12/2012 -22/12/2012 -23/12/2012 -24/12/2012 -25/12/2012 -26/12/2012 -27/12/2012 -28/12/2012 -29/12/2012 -30/12/2012 -31/12/2012 -01/01/2013 -02/01/2013 -03/01/2013 -04/01/2013 -05/01/2013 -06/01/2013 -07/01/2013 -08/01/2013 -09/01/2013 -10/01/2013 -11/01/2013 -12/01/2013 -13/01/2013 -14/01/2013 -15/01/2013 -16/01/2013 -17/01/2013 -18/01/2013 -19/01/2013 -20/01/2013 -21/01/2013 -22/01/2013 -23/01/2013 -24/01/2013 -25/01/2013 -26/01/2013 -27/01/2013 -28/01/2013 -29/01/2013 -30/01/2013 -31/01/2013 -01/02/2013 -02/02/2013 -03/02/2013 -04/02/2013 -05/02/2013 -06/02/2013 -07/02/2013 -08/02/2013 -09/02/2013 -10/02/2013 -11/02/2013 -12/02/2013 -13/02/2013 -14/02/2013 -15/02/2013 -16/02/2013 -17/02/2013 -18/02/2013 -19/02/2013 -20/02/2013 -21/02/2013 -22/02/2013 -23/02/2013 -24/02/2013 -25/02/2013 -26/02/2013 -27/02/2013 -28/02/2013 -01/03/2013 -02/03/2013 -03/03/2013 -04/03/2013 -05/03/2013 -06/03/2013 -07/03/2013 -08/03/2013 -09/03/2013 -10/03/2013 -11/03/2013 -12/03/2013 -13/03/2013 -14/03/2013 -15/03/2013 -16/03/2013 -17/03/2013 -18/03/2013 -19/03/2013 -20/03/2013 -21/03/2013 -22/03/2013 -23/03/2013 -24/03/2013 -25/03/2013 -26/03/2013 -27/03/2013 -28/03/2013 -29/03/2013 -30/03/2013 -31/03/2013 -01/04/2013 -02/04/2013 -03/04/2013 -04/04/2013 -05/04/2013 -06/04/2013 -07/04/2013 -08/04/2013 -09/04/2013 -10/04/2013 -11/04/2013 -12/04/2013 -13/04/2013 -14/04/2013 -15/04/2013 -16/04/2013 -17/04/2013 -18/04/2013 -19/04/2013 -20/04/2013 -21/04/2013 -22/04/2013 -23/04/2013 -24/04/2013 -25/04/2013 -26/04/2013 -27/04/2013 -28/04/2013 -29/04/2013 -30/04/2013 -01/05/2013 -02/05/2013 -03/05/2013 -04/05/2013 -05/05/2013 -06/05/2013 -07/05/2013 -08/05/2013 -09/05/2013 -10/05/2013 -11/05/2013 -12/05/2013 -13/05/2013 -14/05/2013 -15/05/2013 -16/05/2013 -17/05/2013 -18/05/2013 -19/05/2013 -20/05/2013 -21/05/2013 -22/05/2013 -23/05/2013 -24/05/2013 -25/05/2013 -26/05/2013 -27/05/2013 -28/05/2013 -29/05/2013 -30/05/2013 -31/05/2013 -01/06/2013 -02/06/2013 -03/06/2013 -04/06/2013 -05/06/2013 -06/06/2013 -07/06/2013 -08/06/2013 -09/06/2013 -10/06/2013 -11/06/2013 -12/06/2013 -13/06/2013 -14/06/2013 -15/06/2013 -16/06/2013 -17/06/2013 -18/06/2013 -19/06/2013 -20/06/2013 -21/06/2013 -22/06/2013 -23/06/2013 -24/06/2013 -25/06/2013 -26/06/2013 -27/06/2013 -28/06/2013 -29/06/2013 -30/06/2013 -01/07/2013 -02/07/2013 -03/07/2013 -04/07/2013 -05/07/2013 -06/07/2013 -07/07/2013 -08/07/2013 -09/07/2013 -10/07/2013 -11/07/2013 -12/07/2013 -13/07/2013 -14/07/2013 -15/07/2013 -16/07/2013 -17/07/2013 -18/07/2013 -19/07/2013 -20/07/2013 -21/07/2013 -22/07/2013 -23/07/2013 -24/07/2013 -25/07/2013 -26/07/2013 -27/07/2013 -28/07/2013 -29/07/2013 -30/07/2013 -31/07/2013 -01/08/2013 -02/08/2013 -03/08/2013 -04/08/2013 -05/08/2013 -06/08/2013 -07/08/2013 -08/08/2013 -09/08/2013 -10/08/2013 -11/08/2013 -12/08/2013 -13/08/2013 -14/08/2013 -15/08/2013 -16/08/2013 -17/08/2013 -18/08/2013 -19/08/2013 -20/08/2013 -21/08/2013 -22/08/2013 -23/08/2013 -24/08/2013 -25/08/2013 -26/08/2013 -27/08/2013 -28/08/2013 -29/08/2013 -30/08/2013 -31/08/2013 -01/09/2013 -02/09/2013 -03/09/2013 -04/09/2013 -05/09/2013 -06/09/2013 -07/09/2013 -08/09/2013 -09/09/2013 -10/09/2013 -11/09/2013 -12/09/2013 -13/09/2013 -14/09/2013 -15/09/2013 -16/09/2013 -17/09/2013 -18/09/2013 -19/09/2013 -20/09/2013 -21/09/2013 -22/09/2013 -23/09/2013 -24/09/2013 -25/09/2013 -26/09/2013 -27/09/2013 -28/09/2013 -29/09/2013 -30/09/2013 -01/10/2013 -02/10/2013 -03/10/2013 -04/10/2013 -05/10/2013 -06/10/2013 -07/10/2013 -08/10/2013 -09/10/2013 -10/10/2013 -11/10/2013 -12/10/2013 -13/10/2013 -14/10/2013 -15/10/2013 -16/10/2013 -17/10/2013 -18/10/2013 -19/10/2013 -20/10/2013 -21/10/2013 -22/10/2013 -23/10/2013 -24/10/2013 -25/10/2013 -26/10/2013 -27/10/2013 -28/10/2013 -29/10/2013 -30/10/2013 -31/10/2013 -01/11/2013 -02/11/2013 -03/11/2013 -04/11/2013 -05/11/2013 -06/11/2013 -07/11/2013 -08/11/2013 -09/11/2013 -10/11/2013 -11/11/2013 -12/11/2013 -13/11/2013 -14/11/2013 -15/11/2013 -16/11/2013 -17/11/2013 -18/11/2013 -19/11/2013 -20/11/2013 -21/11/2013 -22/11/2013 -23/11/2013 -24/11/2013 -25/11/2013 -26/11/2013 -27/11/2013 -28/11/2013 -29/11/2013 -30/11/2013 -01/12/2013 -02/12/2013 -03/12/2013 -04/12/2013 -05/12/2013 -06/12/2013 -07/12/2013 -08/12/2013 -09/12/2013 -10/12/2013 -11/12/2013 -12/12/2013 -13/12/2013 -14/12/2013 -15/12/2013 -16/12/2013 -17/12/2013 -18/12/2013 -19/12/2013 -20/12/2013 -21/12/2013 -22/12/2013 -23/12/2013 -24/12/2013 -25/12/2013 -26/12/2013 -27/12/2013 -28/12/2013 -29/12/2013 -30/12/2013 -31/12/2013 -01/01/2014 -02/01/2014 -03/01/2014 -04/01/2014 -05/01/2014 -06/01/2014 -07/01/2014 -08/01/2014 -09/01/2014 -10/01/2014 -11/01/2014 -12/01/2014 -13/01/2014 -14/01/2014 -15/01/2014 -16/01/2014 -17/01/2014 -18/01/2014 -19/01/2014 -20/01/2014 -21/01/2014 -22/01/2014 -23/01/2014 -24/01/2014 -25/01/2014 -26/01/2014 -27/01/2014 -28/01/2014 -29/01/2014 -30/01/2014 -31/01/2014 -01/02/2014 -02/02/2014 -03/02/2014 -04/02/2014 -05/02/2014 -06/02/2014 -07/02/2014 -08/02/2014 -09/02/2014 -10/02/2014 -11/02/2014 -12/02/2014 -13/02/2014 -14/02/2014 -15/02/2014 -16/02/2014 -17/02/2014 -18/02/2014 -19/02/2014 -20/02/2014 -21/02/2014 -22/02/2014 -23/02/2014 -24/02/2014 -25/02/2014 -26/02/2014 -27/02/2014 -28/02/2014 -01/03/2014 -02/03/2014 -03/03/2014 -04/03/2014 -05/03/2014 -06/03/2014 -07/03/2014 -08/03/2014 -09/03/2014 -10/03/2014 -11/03/2014 -12/03/2014 -13/03/2014 -14/03/2014 -15/03/2014 -16/03/2014 -17/03/2014 -18/03/2014 -19/03/2014 -20/03/2014 -21/03/2014 -22/03/2014 -23/03/2014 -24/03/2014 -25/03/2014 -26/03/2014 -27/03/2014 -28/03/2014 -29/03/2014 -30/03/2014 -31/03/2014 -01/04/2014 -02/04/2014 -03/04/2014 -04/04/2014 -05/04/2014 -06/04/2014 -07/04/2014 -08/04/2014 -09/04/2014 -10/04/2014 -11/04/2014 -12/04/2014 -13/04/2014 -14/04/2014 -15/04/2014 -16/04/2014 -17/04/2014 -18/04/2014 -19/04/2014 -20/04/2014 -21/04/2014 -22/04/2014 -23/04/2014 -24/04/2014 -25/04/2014 -26/04/2014 -27/04/2014 -28/04/2014 -29/04/2014 -30/04/2014 -01/05/2014 -02/05/2014 -03/05/2014 -04/05/2014 -05/05/2014 -06/05/2014 -07/05/2014 -08/05/2014 -09/05/2014 -10/05/2014 -11/05/2014 -12/05/2014 -13/05/2014 -14/05/2014 -15/05/2014 -16/05/2014 -17/05/2014 -18/05/2014 -19/05/2014 -20/05/2014 -21/05/2014 -22/05/2014 -23/05/2014 -24/05/2014 -25/05/2014 -26/05/2014 -27/05/2014 -28/05/2014 -29/05/2014 -30/05/2014 -31/05/2014 -01/06/2014 -02/06/2014 -03/06/2014 -04/06/2014 -05/06/2014 -06/06/2014 -07/06/2014 -08/06/2014 -09/06/2014 -10/06/2014 -11/06/2014 -12/06/2014 -13/06/2014 -14/06/2014 -15/06/2014 -16/06/2014 -17/06/2014 -18/06/2014 -19/06/2014 -20/06/2014 -21/06/2014 -22/06/2014 -23/06/2014 -24/06/2014 -25/06/2014 -26/06/2014 -27/06/2014 -28/06/2014 -29/06/2014 -30/06/2014 -01/07/2014 -02/07/2014 -03/07/2014 -04/07/2014 -05/07/2014 -06/07/2014 -07/07/2014 -08/07/2014 -09/07/2014 -10/07/2014 -11/07/2014 -12/07/2014 -13/07/2014 -14/07/2014 -15/07/2014 -16/07/2014 -17/07/2014 -18/07/2014 -19/07/2014 -20/07/2014 -21/07/2014 -22/07/2014 -23/07/2014 -24/07/2014 -25/07/2014 -26/07/2014 -27/07/2014 -28/07/2014 -29/07/2014 -30/07/2014 -31/07/2014 -01/08/2014 -02/08/2014 -03/08/2014 -04/08/2014 -05/08/2014 -06/08/2014 -07/08/2014 -08/08/2014 -09/08/2014 -10/08/2014 -11/08/2014 -12/08/2014 -13/08/2014 -14/08/2014 -15/08/2014 -16/08/2014 -17/08/2014 -18/08/2014 -19/08/2014 -20/08/2014 -21/08/2014 -22/08/2014 -23/08/2014 -24/08/2014 -25/08/2014 -26/08/2014 -27/08/2014 -28/08/2014 -29/08/2014 -30/08/2014 -31/08/2014 -01/09/2014 -02/09/2014 -03/09/2014 -04/09/2014 -05/09/2014 -06/09/2014 -07/09/2014 -08/09/2014 -09/09/2014 -10/09/2014 -11/09/2014 -12/09/2014 -13/09/2014 -14/09/2014 -15/09/2014 -16/09/2014 -17/09/2014 -18/09/2014 -19/09/2014 -20/09/2014 -21/09/2014 -22/09/2014 -23/09/2014 -24/09/2014 -25/09/2014 -26/09/2014 -27/09/2014 -28/09/2014 -29/09/2014 -30/09/2014 -01/10/2014 -02/10/2014 -03/10/2014 -04/10/2014 -05/10/2014 -06/10/2014 -07/10/2014 -08/10/2014 -09/10/2014 -10/10/2014 -11/10/2014 -12/10/2014 -13/10/2014 -14/10/2014 -15/10/2014 -16/10/2014 -17/10/2014 -18/10/2014 -19/10/2014 -20/10/2014 -21/10/2014 -22/10/2014 -23/10/2014 -24/10/2014 -25/10/2014 -26/10/2014 -27/10/2014 -28/10/2014 -29/10/2014 -30/10/2014 -31/10/2014 -01/11/2014 -02/11/2014 -03/11/2014 -04/11/2014 -05/11/2014 -06/11/2014 -07/11/2014 -08/11/2014 -09/11/2014 -10/11/2014 -11/11/2014 -12/11/2014 -13/11/2014 -14/11/2014 -15/11/2014 -16/11/2014 -17/11/2014 -18/11/2014 -19/11/2014 -20/11/2014 -21/11/2014 -22/11/2014 -23/11/2014 -24/11/2014 -25/11/2014 -26/11/2014 -27/11/2014 -28/11/2014 -29/11/2014 -30/11/2014 -01/12/2014 -02/12/2014 -03/12/2014 -04/12/2014 -05/12/2014 -06/12/2014 -07/12/2014 -08/12/2014 -09/12/2014 -10/12/2014 -11/12/2014 -12/12/2014 -13/12/2014 -14/12/2014 -15/12/2014 -16/12/2014 -17/12/2014 -18/12/2014 -19/12/2014 -20/12/2014 -21/12/2014 -22/12/2014 -23/12/2014 -24/12/2014 -25/12/2014 -26/12/2014 -27/12/2014 -28/12/2014 -29/12/2014 -30/12/2014 -31/12/2014 -01/01/2015 -02/01/2015 -03/01/2015 -04/01/2015 -05/01/2015 -06/01/2015 -07/01/2015 -08/01/2015 -09/01/2015 -10/01/2015 -11/01/2015 -12/01/2015 -13/01/2015 -14/01/2015 -15/01/2015 -16/01/2015 -17/01/2015 -18/01/2015 -19/01/2015 -20/01/2015 -21/01/2015 -22/01/2015 -23/01/2015 -24/01/2015 -25/01/2015 -26/01/2015 -27/01/2015 -28/01/2015 -29/01/2015 -30/01/2015 -31/01/2015 -01/02/2015 -02/02/2015 -03/02/2015 -04/02/2015 -05/02/2015 -06/02/2015 -07/02/2015 -08/02/2015 -09/02/2015 -10/02/2015 -11/02/2015 -12/02/2015 -13/02/2015 -14/02/2015 -15/02/2015 -16/02/2015 -17/02/2015 -18/02/2015 -19/02/2015 -20/02/2015 -21/02/2015 -22/02/2015 -23/02/2015 -24/02/2015 -25/02/2015 -26/02/2015 -27/02/2015 -28/02/2015 -01/03/2015 -02/03/2015 -03/03/2015 -04/03/2015 -05/03/2015 -06/03/2015 -07/03/2015 -08/03/2015 -09/03/2015 -10/03/2015 -11/03/2015 -12/03/2015 -13/03/2015 -14/03/2015 -15/03/2015 -16/03/2015 -17/03/2015 -18/03/2015 -19/03/2015 -20/03/2015 -21/03/2015 -22/03/2015 -23/03/2015 -24/03/2015 -25/03/2015 -26/03/2015 -27/03/2015 -28/03/2015 -29/03/2015 -30/03/2015 -31/03/2015 -01/04/2015 -02/04/2015 -03/04/2015 -04/04/2015 -05/04/2015 -06/04/2015 -07/04/2015 -08/04/2015 -09/04/2015 -10/04/2015 -11/04/2015 -12/04/2015 -13/04/2015 -14/04/2015 -15/04/2015 -16/04/2015 -17/04/2015 -18/04/2015 -19/04/2015 -20/04/2015 -21/04/2015 -22/04/2015 -23/04/2015 -24/04/2015 -25/04/2015 -26/04/2015 -27/04/2015 -28/04/2015 -29/04/2015 -30/04/2015 -01/05/2015 -02/05/2015 -03/05/2015 -04/05/2015 -05/05/2015 -06/05/2015 -07/05/2015 -08/05/2015 -09/05/2015 -10/05/2015 -11/05/2015 -12/05/2015 -13/05/2015 -14/05/2015 -15/05/2015 -16/05/2015 -17/05/2015 -18/05/2015 -19/05/2015 -20/05/2015 -21/05/2015 -22/05/2015 -23/05/2015 -24/05/2015 -25/05/2015 -26/05/2015 -27/05/2015 -28/05/2015 -29/05/2015 -30/05/2015 -31/05/2015 -01/06/2015 -02/06/2015 -03/06/2015 -04/06/2015 -05/06/2015 -06/06/2015 -07/06/2015 -08/06/2015 -09/06/2015 -10/06/2015 -11/06/2015 -12/06/2015 -13/06/2015 -14/06/2015 -15/06/2015 -16/06/2015 -17/06/2015 -18/06/2015 -19/06/2015 -20/06/2015 -21/06/2015 -22/06/2015 -23/06/2015 diff --git a/ThirdParty/Ert/docs/course/config/snake_oil.ert b/ThirdParty/Ert/docs/course/config/snake_oil.ert deleted file mode 100644 index 72fef586d0..0000000000 --- a/ThirdParty/Ert/docs/course/config/snake_oil.ert +++ /dev/null @@ -1,40 +0,0 @@ -QUEUE_SYSTEM LOCAL - -JOBNAME SNAKE_OIL_%d -NUM_REALIZATIONS 25 - -DEFINE storage/ - -STORE_SEED SEED -LOAD_SEED SEED - -RUNPATH_FILE directory/test_runpath_list.txt -RUNPATH /runpath/realisation-%d/iter-%d -ENSPATH /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 diff --git a/ThirdParty/Ert/docs/course/config/templates/seed_template.txt b/ThirdParty/Ert/docs/course/config/templates/seed_template.txt deleted file mode 100644 index a0bca49fbd..0000000000 --- a/ThirdParty/Ert/docs/course/config/templates/seed_template.txt +++ /dev/null @@ -1 +0,0 @@ -SEED: \ No newline at end of file diff --git a/ThirdParty/Ert/docs/course/config/templates/snake_oil_template.txt b/ThirdParty/Ert/docs/course/config/templates/snake_oil_template.txt deleted file mode 100644 index ad2c648a0b..0000000000 --- a/ThirdParty/Ert/docs/course/config/templates/snake_oil_template.txt +++ /dev/null @@ -1,10 +0,0 @@ -OP1_PERSISTENCE: -OP1_OCTAVES: -OP1_DIVERGENCE_SCALE: -OP1_OFFSET: -OP2_PERSISTENCE: -OP2_OCTAVES: -OP2_DIVERGENCE_SCALE: -OP2_OFFSET: -BPR_555_PERSISTENCE: -BPR_138_PERSISTENCE: diff --git a/ThirdParty/Ert/docs/course/ex1/ex1.txt b/ThirdParty/Ert/docs/course/ex1/ex1.txt deleted file mode 100644 index dadcc397eb..0000000000 --- a/ThirdParty/Ert/docs/course/ex1/ex1.txt +++ /dev/null @@ -1,7 +0,0 @@ -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. diff --git a/ThirdParty/Ert/docs/course/ex1/sol1.py b/ThirdParty/Ert/docs/course/ex1/sol1.py deleted file mode 100644 index 5c30971e1b..0000000000 --- a/ThirdParty/Ert/docs/course/ex1/sol1.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/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( ))) - diff --git a/ThirdParty/Ert/docs/course/ex2/ex2.txt b/ThirdParty/Ert/docs/course/ex2/ex2.txt deleted file mode 100644 index 32daa87560..0000000000 --- a/ThirdParty/Ert/docs/course/ex2/ex2.txt +++ /dev/null @@ -1 +0,0 @@ -Implement the [] operator for the gen_data class in GenData.py diff --git a/ThirdParty/Ert/docs/course/ex2/sol2.txt b/ThirdParty/Ert/docs/course/ex2/sol2.txt deleted file mode 100644 index e6b4474389..0000000000 --- a/ThirdParty/Ert/docs/course/ex2/sol2.txt +++ /dev/null @@ -1,35 +0,0 @@ -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))) - - - diff --git a/ThirdParty/Ert/docs/course/ex3/ex3.txt b/ThirdParty/Ert/docs/course/ex3/ex3.txt deleted file mode 100644 index e5c6750107..0000000000 --- a/ThirdParty/Ert/docs/course/ex3/ex3.txt +++ /dev/null @@ -1,2 +0,0 @@ -Iterate through all the forward models which have been installed and -get the configuration file and executable. diff --git a/ThirdParty/Ert/docs/course/ex3/sol3.py b/ThirdParty/Ert/docs/course/ex3/sol3.py deleted file mode 100644 index 044a865719..0000000000 --- a/ThirdParty/Ert/docs/course/ex3/sol3.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/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 diff --git a/ThirdParty/Ert/docs/course/ex4/ex4.txt b/ThirdParty/Ert/docs/course/ex4/ex4.txt deleted file mode 100644 index 38b16f1939..0000000000 --- a/ThirdParty/Ert/docs/course/ex4/ex4.txt +++ /dev/null @@ -1,13 +0,0 @@ -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. - - diff --git a/ThirdParty/Ert/docs/course/ex4/sol4.py b/ThirdParty/Ert/docs/course/ex4/sol4.py deleted file mode 100644 index d62277c6c2..0000000000 --- a/ThirdParty/Ert/docs/course/ex4/sol4.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/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 diff --git a/ThirdParty/Ert/docs/doxygen.cfg.in b/ThirdParty/Ert/docs/doxygen.cfg.in deleted file mode 100644 index 969caa1615..0000000000 --- a/ThirdParty/Ert/docs/doxygen.cfg.in +++ /dev/null @@ -1,42 +0,0 @@ -# This is a slightly modified standard doxygen config file - -DOXYFILE_ENCODING = UTF-8 -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}/documentation/doxy -CREATE_SUBDIRS = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -TAB_SIZE = 2 - -EXTRACT_ALL = YES -EXTRACT_PACKAGE = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO - -CASE_SENSE_NAMES = YES - -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = NO -WARN_IF_DOC_ERROR = NO -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" - -INPUT = ${DOXYGEN_INPUT} - -RECURSIVE = YES -EXCLUDE_PATTERNS = */test/* */build/* */test-data/* */docs/* */python*/ - -HAVE_DOT = ${DOXYGEN_HAVE_DOT} -DOT_GRAPH_MAX_NODES = 1000 -GENERATE_HTML = YES -CLASS_DIAGRAMS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = NO -CALL_GRAPH = YES - -DOT_IMAGE_FORMAT = png -INTERACTIVE_SVG = NO diff --git a/ThirdParty/Ert/docs/eclipse_restart_spe1.txt b/ThirdParty/Ert/docs/eclipse_restart_spe1.txt deleted file mode 100644 index fd08813163..0000000000 --- a/ThirdParty/Ert/docs/eclipse_restart_spe1.txt +++ /dev/null @@ -1,109 +0,0 @@ -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. - - - diff --git a/ThirdParty/Ert/docs/eclipse_restart_specification.txt b/ThirdParty/Ert/docs/eclipse_restart_specification.txt deleted file mode 100644 index 6630d4225f..0000000000 --- a/ThirdParty/Ert/docs/eclipse_restart_specification.txt +++ /dev/null @@ -1,268 +0,0 @@ -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 - - - - - - - - diff --git a/ThirdParty/Ert/docs/nexus.plt b/ThirdParty/Ert/docs/nexus.plt deleted file mode 100644 index 88b482631b..0000000000 --- a/ThirdParty/Ert/docs/nexus.plt +++ /dev/null @@ -1,51 +0,0 @@ - - -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 - -----> : This is the position of first timestep - -while classname != STOP: - 8*b : classname - 8*b : skipped - f : timestep (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 - 8*b : skipped diff --git a/ThirdParty/Ert/install/install.py b/ThirdParty/Ert/install/install.py index 6358d54de7..1a60337933 100644 --- a/ThirdParty/Ert/install/install.py +++ b/ThirdParty/Ert/install/install.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/lib/CMakeLists.txt b/ThirdParty/Ert/lib/CMakeLists.txt index b0fb796a1c..079eb127de 100644 --- a/ThirdParty/Ert/lib/CMakeLists.txt +++ b/ThirdParty/Ert/lib/CMakeLists.txt @@ -54,12 +54,6 @@ if (ZLIB_FOUND) list(APPEND opt_srcs util/util_zlib.cpp) endif () -if (ERT_BUILD_CXX) - list(APPEND opt_srcs ecl/FortIO.cpp - ecl/Smspec.cpp - ecl/EclFilename.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) @@ -145,6 +139,8 @@ add_library(ecl util/rng.cpp ecl/well_segment_collection.cpp ecl/well_branch_collection.cpp ecl/well_rseg_loader.cpp + ecl/FortIO.cpp + ecl/EclFilename.cpp geometry/geo_surface.cpp geometry/geo_util.cpp @@ -183,13 +179,6 @@ target_include_directories(ecl ${CMAKE_CURRENT_BINARY_DIR}/include ) - -if (NOT INSTALL_ERT) - # set git info to zero, to avoid recompile of libecl files at every commit - set(GIT_COMMIT 0) - set(GIT_COMMIT_SHORT 0) -endif() - target_compile_definitions(ecl PRIVATE -DGIT_COMMIT=${GIT_COMMIT} -DGIT_COMMIT_SHORT=${GIT_COMMIT_SHORT} @@ -211,7 +200,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} @@ -219,25 +208,11 @@ install(TARGETS ecl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(DIRECTORY include/ DESTINATION include - PATTERN *.h -) -install(DIRECTORY include/ - DESTINATION include - PATTERN *.hpp EXCLUDE ) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ DESTINATION include - PATTERN *.h ) -if (ERT_BUILD_CXX) - install(DIRECTORY include/ - DESTINATION include - PATTERN *.hpp -) -endif () -endif() - if (NOT BUILD_TESTS) return () endif () @@ -277,6 +252,7 @@ foreach (name ert_util_alloc_file_components ert_util_datetime ert_util_normal_path ert_util_mkdir_p + test_area ) add_executable(${name} util/tests/${name}.cpp) @@ -353,11 +329,14 @@ foreach (name ecl_alloc_cpgrid ecl_grid_copy ecl_grid_create ecl_grid_DEPTHZ + ecl_grid_fwrite ecl_grid_unit_system ecl_grid_export ecl_grid_init_fwrite ecl_grid_reset_actnum ecl_grid_ext_actnum + ecl_nnc_export_intersect + ecl_sum_restart ecl_sum_data_intermediate_test ecl_grid_cell_contains ecl_unsmry_loader_test @@ -436,26 +415,24 @@ foreach (name geo_util_xlines geo_polygon geo_polygon_collection) add_test(NAME ${name} COMMAND ${name}) endforeach () -if (ERT_BUILD_CXX) - foreach (test ert_util_unique_ptr) - add_executable(${test} util/tests/${test}.cpp) - target_link_libraries(${test} ecl) - add_test(NAME ${test} COMMAND ${test}) - endforeach() +foreach (test ert_util_unique_ptr) + add_executable(${test} util/tests/${test}.cpp) + target_link_libraries(${test} ecl) + add_test(NAME ${test} COMMAND ${test}) +endforeach() - foreach (test eclxx_kw eclxx_fortio eclxx_smspec eclxx_filename eclxx_types) - add_executable(${test} ecl/tests/${test}.cpp) - target_link_libraries(${test} ecl) - add_test(NAME ${test} COMMAND ${test}) - endforeach () -endif () +foreach (test eclxx_kw eclxx_fortio eclxx_filename eclxx_types) + add_executable(${test} ecl/tests/${test}.cpp) + target_link_libraries(${test} ecl) + add_test(NAME ${test} COMMAND ${test}) +endforeach () foreach(name ecl_coarse_test ecl_grid_layer_contains ecl_restart_test ecl_nnc_export ecl_nnc_export_get_tran - ecl_nnc_data_statoil_root + ecl_nnc_data_equinor_root ecl_sum_case_exists ecl_grid_lgr_name ecl_region @@ -467,19 +444,19 @@ foreach(name ecl_coarse_test ecl_grid_dims ecl_nnc_test ecl_lgr_test - ecl_layer_statoil + ecl_layer_equinor ecl_dualp ecl_grid_dx_dy_dz ecl_sum_test ecl_sum_report_step_equal ecl_sum_report_step_compatible - ecl_file_statoil + ecl_file_equinor ecl_fmt ecl_rsthead ecl_smspec ecl_rft - ecl_grid_copy_statoil - ecl_fault_block_layer_statoil + ecl_grid_copy_equinor + ecl_fault_block_layer_equinor well_state_load well_state_load_missing_RSEG well_segment_load @@ -497,7 +474,7 @@ foreach(name ecl_coarse_test endforeach() -if (NOT STATOIL_TESTDATA_ROOT) +if (NOT EQUINOR_TESTDATA_ROOT) return () endif() @@ -531,7 +508,7 @@ add_test(NAME ecl_nnc_export7 COMMAND ecl_nnc_export ${_eclpath}/TYRIHANS/BASE20 add_test(NAME ecl_nnc_export_get_tran COMMAND ecl_nnc_export_get_tran ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3) -add_test(NAME ecl_nnc_data_statoil_root COMMAND ecl_nnc_data_statoil_root +add_test(NAME ecl_nnc_data_equinor_root COMMAND ecl_nnc_data_equinor_root ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3 ${_eclpath}/flow-nnc/Simple4/SIMPLE_SUMMARY4 ${_eclpath}/flow-nnc/Gullfaks/GF_ACT_NEW_TEMP) @@ -572,7 +549,7 @@ add_test(NAME ecl_grid_simple COMMAND ecl_grid_simple ${_eclpath}/Gurbat/ECLIPSE add_test(NAME ecl_grid_ecl2015_2 COMMAND ecl_grid_simple ${_eclpath}/Eclipse2015_NNC_BUG/FF15_2015B2_LGRM_RDI15_HIST_RDIREAL1_20142.EGRID) -add_test(NAME ecl_grid_export_statoil +add_test(NAME ecl_grid_export_equinor COMMAND ecl_grid_export ${_eclpath}/Gurbat/ECLIPSE.EGRID) add_test(NAME ecl_grid_volume1 COMMAND ecl_grid_volume ${_eclpath}/Gurbat/ECLIPSE) @@ -600,7 +577,7 @@ add_test(NAME ecl_nnc_test3 COMMAND ecl_nnc_test ${_eclpath}/Troll/MSW_LGR/2BRAN add_test(NAME ecl_nnc_test4 COMMAND ecl_nnc_test ${_eclpath}/DualPoro/DUAL_DIFF.EGRID ) add_test(NAME ecl_nnc_test5 COMMAND ecl_nnc_test ${_eclpath}/nestedLGRcase/TESTCASE_NESTEDLGR.EGRID) -add_test(NAME ecl_layer_statoil COMMAND ecl_layer_statoil +add_test(NAME ecl_layer_equinor COMMAND ecl_layer_equinor ${_eclpath}/Mariner/MARINER.EGRID ${_eclpath}/Mariner/faultblock.grdecl) @@ -622,8 +599,8 @@ add_test(NAME ecl_sum_report_step_compatible4 COMMAND ecl_sum_report_step_compat add_test(NAME ecl_sum_report_step_compatible5 COMMAND ecl_sum_report_step_compatible ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/modGurbat/enkf/ECLIPSE TRUE) add_test(NAME ecl_sum_report_step_compatible6 COMMAND ecl_sum_report_step_equal ${_eclpath}/Snorre/SNORRE ${_eclpath}/Snorre2/SNORRE2 FALSE) -add_test(NAME ecl_file_statoil - COMMAND ecl_file_statoil ${_eclpath}/Gurbat/ECLIPSE.UNRST ECLIPSE.UNRST) +add_test(NAME ecl_file_equinor + COMMAND ecl_file_equinor ${_eclpath}/Gurbat/ECLIPSE.UNRST ECLIPSE.UNRST) add_test(NAME ecl_fmt COMMAND ecl_fmt ${_eclpath}/Gurbat/ECLIPSE.UNRST @@ -645,12 +622,12 @@ 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_test(NAME ecl_grid_copy_statoil1 COMMAND ecl_grid_copy_statoil ${_eclpath}/Gurbat/ECLIPSE.EGRID) -add_test(NAME ecl_grid_copy_statoil2 COMMAND ecl_grid_copy_statoil ${_eclpath}/Mariner/MARINER.EGRID) -add_test(NAME ecl_grid_copy_statoil3 COMMAND ecl_grid_copy_statoil ${_eclpath}/LGCcase/LGC_TESTCASE2.EGRID) -add_test(NAME ecl_grid_copy_statoil4 COMMAND ecl_grid_copy_statoil ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.EGRID) +add_test(NAME ecl_grid_copy_equinor1 COMMAND ecl_grid_copy_equinor ${_eclpath}/Gurbat/ECLIPSE.EGRID) +add_test(NAME ecl_grid_copy_equinor2 COMMAND ecl_grid_copy_equinor ${_eclpath}/Mariner/MARINER.EGRID) +add_test(NAME ecl_grid_copy_equinor3 COMMAND ecl_grid_copy_equinor ${_eclpath}/LGCcase/LGC_TESTCASE2.EGRID) +add_test(NAME ecl_grid_copy_equinor4 COMMAND ecl_grid_copy_equinor ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.EGRID) -add_test(NAME ecl_fault_block_layer_statoil COMMAND ecl_fault_block_layer_statoil +add_test(NAME ecl_fault_block_layer_equinor COMMAND ecl_fault_block_layer_equinor ${_eclpath}/Mariner/MARINER.EGRID ${_eclpath}/Mariner/faultblock.grdecl) @@ -684,7 +661,9 @@ add_test(NAME well_segment_load add_test(NAME well_segment_branch_conn_load COMMAND well_segment_branch_conn_load ${_eclpath}/MSWcase/MSW_CASE.X0021) -add_test(NAME well_info COMMAND well_info ${_eclpath}/Gurbat/ECLIPSE.EGRID) +add_test(NAME well_info1 COMMAND well_info ${_eclpath}/Gurbat/ECLIPSE.EGRID) +add_test(NAME well_info2 COMMAND well_info ${_eclpath}/well_info_rio/BMS8_TMPL_1-BMS8_105DST_EMBED_T0_1.EGRID + ${_eclpath}/well_info_rio/BMS8_TMPL_1-BMS8_105DST_EMBED_T0_1.UNRST) add_test(NAME well_conn_CF COMMAND well_conn_CF ${_eclpath}/Gurbat/ECLIPSE.X0060) diff --git a/ThirdParty/Ert/lib/ecl/EclFilename.cpp b/ThirdParty/Ert/lib/ecl/EclFilename.cpp index 225ad52b46..f5db772659 100644 --- a/ThirdParty/Ert/lib/ecl/EclFilename.cpp +++ b/ThirdParty/Ert/lib/ecl/EclFilename.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/FortIO.cpp b/ThirdParty/Ert/lib/ecl/FortIO.cpp index c76985f173..edc5f1f92c 100644 --- a/ThirdParty/Ert/lib/ecl/FortIO.cpp +++ b/ThirdParty/Ert/lib/ecl/FortIO.cpp @@ -1,5 +1,5 @@ /* - Copyright 2015 Statoil ASA. + Copyright 2015 Equinor ASA. This file is part of the Open Porous Media project (OPM). diff --git a/ThirdParty/Ert/lib/ecl/Smspec.cpp b/ThirdParty/Ert/lib/ecl/Smspec.cpp deleted file mode 100644 index ba81341bef..0000000000 --- a/ThirdParty/Ert/lib/ecl/Smspec.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -namespace ERT { - - smspec_node::smspec_node( const smspec_node& rhs ) : - node( smspec_node_alloc_copy( rhs.node.get() ) ) - {} - - smspec_node::smspec_node( smspec_node&& rhs ) : - node( std::move( rhs.node ) ) - {} - - smspec_node& smspec_node::operator=( const smspec_node& rhs ) { - this->node.reset( smspec_node_alloc_copy( rhs.node.get() ) ); - return *this; - } - - smspec_node& smspec_node::operator=( smspec_node&& rhs ) { - this->node = std::move( rhs.node ); - return *this; - } - - int smspec_node::cmp( const smspec_node& node1, const smspec_node& node2) { - return smspec_node_cmp( node1.get() , node2.get() ); - } - - static const int dummy_dims[ 3 ] = { -1, -1, -1 }; - const auto default_join = ":"; - - static int global_index( const int dims[ 3 ], const int ijk[ 3 ] ) { - /* num is offset 1 global index */ - return 1 + ijk[ 0 ] + ( ijk[ 1 ] * dims[ 0 ] ) + ( ijk[ 2 ] * dims[ 1 ] * dims[ 0 ] ); - } - - smspec_node::smspec_node( - ecl_smspec_var_type var_type, - const std::string& name, - const std::string& kw - ) : smspec_node( var_type, name.c_str(), kw.c_str(), "", default_join, dummy_dims, 0 ) - {} - - smspec_node::smspec_node( const std::string& keyword ) : - smspec_node( ecl_smspec_identify_var_type( keyword.c_str() ), - "", - keyword.c_str(), - "", - default_join, - dummy_dims, - 0 ) - {} - - smspec_node::smspec_node( - const std::string& keyword, - const int dims[ 3 ], - const int ijk[ 3 ] ) : - smspec_node( - ECL_SMSPEC_BLOCK_VAR, "", keyword.c_str(), "", default_join, dims, global_index( dims, ijk ) - ) - {} - - smspec_node::smspec_node( - const std::string& keyword, - const std::string& wellname, - const int dims[ 3 ], - const int ijk[ 3 ] ) : - smspec_node( - ECL_SMSPEC_COMPLETION_VAR, wellname.c_str(), keyword.c_str(), "", default_join, dims, global_index( dims, ijk ) - ) - {} - - smspec_node::smspec_node( - const std::string& keyword, - const int dims[ 3 ], - int region ) : - smspec_node( - ECL_SMSPEC_REGION_VAR, "", keyword.c_str(), "", default_join, dims, region - ) - {} - - smspec_node::smspec_node( - ecl_smspec_var_type type, - const char* wgname, - const char* keyword, - const char* unit, - const char* join, - const int grid_dims[ 3 ], - int num, int index, float default_value ) : - node( smspec_node_alloc( type, wgname, keyword, unit, - join, grid_dims, num, index, default_value ) ) - {} - - int smspec_node::type() const { - return smspec_node_get_var_type( this->node.get() ); - } - - const char* smspec_node::wgname() const { - return smspec_node_get_wgname( this->node.get() ); - } - - const char* smspec_node::keyword() const { - return smspec_node_get_keyword( this->node.get() ); - } - - const char* smspec_node::key1() const { - return smspec_node_get_gen_key1( this->node.get() ); - } - - int smspec_node::num() const { - return smspec_node_get_num( this->node.get() ); - } - - smspec_node_type* smspec_node::get() { - return this->node.get(); - } - - const smspec_node_type* smspec_node::get() const { - return this->node.get(); - } -} diff --git a/ThirdParty/Ert/lib/ecl/ecl_box.cpp b/ThirdParty/Ert/lib/ecl/ecl_box.cpp index 292e7a78b5..de0c5b3e68 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_box.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_box.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_box.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp index 44fb620c58..09cd1a0d6b 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2012 statoil asa, norway. + Copyright (c) 2012 equinor asa, norway. The file 'ecl_coarse_cell.c' is part of ert - ensemble based reservoir tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_file.cpp index 6384912bf6..d99e468623 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -534,10 +534,13 @@ static void ecl_file_scan( ecl_file_type * ecl_file ) { if (read_status == ECL_KW_READ_OK) { ecl_file_kw_type * file_kw = ecl_file_kw_alloc( work_kw , current_offset); + if (ecl_file_kw_fskip_data( file_kw , ecl_file->fortio )) ecl_file_view_add_kw( ecl_file->global_view , file_kw ); - else + else { + ecl_file_kw_free( file_kw ); break; + } } } } diff --git a/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp b/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp index 5d5065c370..4bc20c32cc 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_file_kw.c' is part of ERT - Ensemble based Reservoir Tool. @@ -91,7 +91,7 @@ static void inv_map_assert_sort( inv_map_type * map ) { size_t_vector_permute( map->file_kw_ptr , perm ); map->sorted = true; - free( perm ); + perm_vector_free( perm ); } } diff --git a/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp b/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp index 0a6e0a7622..f8fdd15999 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_file_view.c' is part of ERT - Ensemble based Reservoir Tool. @@ -19,9 +19,7 @@ #include #include - -#include -#include +#include #include #include @@ -33,13 +31,13 @@ struct ecl_file_view_struct { - vector_type * kw_list; /* This is a vector of ecl_file_kw instances corresponding to the content of the file. */ - hash_type * kw_index; /* A hash table with integer vectors of indices - see comment below. */ + std::vector kw_list; + std::map> kw_index; std::vector distinct_kw; /* A list of the keywords occuring in the file - each string occurs ONLY ONCE. */ fortio_type * fortio; /* The same fortio instance pointer as in the ecl_file styructure. */ bool owner; /* Is this map the owner of the ecl_file_kw instances; only true for the global_map. */ inv_map_type * inv_map; /* Shared reference owned by the ecl_file structure. */ - vector_type * child_list; + std::vector child_list; int * flags; }; @@ -75,9 +73,6 @@ const char * ecl_file_view_get_src_file( const ecl_file_view_type * file_view ) ecl_file_view_type * ecl_file_view_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map , bool owner ) { ecl_file_view_type * ecl_file_view = new ecl_file_view_type(); - ecl_file_view->kw_list = vector_alloc_new(); - ecl_file_view->kw_index = hash_alloc(); - ecl_file_view->child_list = vector_alloc_new(); ecl_file_view->owner = owner; ecl_file_view->fortio = fortio; ecl_file_view->inv_map = inv_map; @@ -87,9 +82,8 @@ ecl_file_view_type * ecl_file_view_alloc( fortio_type * fortio , int * flags , i } int ecl_file_view_get_global_index( const ecl_file_view_type * ecl_file_view , const char * kw , int ith) { - const int_vector_type * index_vector = (const int_vector_type*)hash_get(ecl_file_view->kw_index , kw); - int global_index = int_vector_iget( index_vector , ith); - return global_index; + const auto& index_vector = ecl_file_view->kw_index.at(kw); + return index_vector[ith]; } @@ -105,34 +99,28 @@ int ecl_file_view_get_global_index( const ecl_file_view_type * ecl_file_view , c void ecl_file_view_make_index( ecl_file_view_type * ecl_file_view ) { ecl_file_view->distinct_kw.clear(); - hash_clear( ecl_file_view->kw_index ); + ecl_file_view->kw_index.clear(); { - int i; - for (i=0; i < vector_get_size( ecl_file_view->kw_list ); i++) { - const ecl_file_kw_type * file_kw = (const ecl_file_kw_type*)vector_iget_const( ecl_file_view->kw_list , i); - const char * header = ecl_file_kw_get_header( file_kw ); - if ( !hash_has_key( ecl_file_view->kw_index , header )) { - int_vector_type * index_vector = int_vector_alloc( 0 , -1 ); - hash_insert_hash_owned_ref( ecl_file_view->kw_index , header , index_vector , int_vector_free__); + int global_index = 0; + for (const auto& file_kw : ecl_file_view->kw_list) { + const std::string& header = ecl_file_kw_get_header( file_kw ); + if (ecl_file_view->kw_index.find(header) == ecl_file_view->kw_index.end()) ecl_file_view->distinct_kw.push_back(header); - } - { - int_vector_type * index_vector = (int_vector_type*)hash_get( ecl_file_view->kw_index , header); - int_vector_append( index_vector , i); - } + auto& index_vector = ecl_file_view->kw_index[header]; + index_vector.push_back(global_index); + global_index++; } } } bool ecl_file_view_has_kw( const ecl_file_view_type * ecl_file_view, const char * kw) { - return hash_has_key( ecl_file_view->kw_index , kw ); + return (ecl_file_view->kw_index.find(kw) != ecl_file_view->kw_index.end()); } ecl_file_kw_type * ecl_file_view_iget_file_kw( const ecl_file_view_type * ecl_file_view , int global_index) { - ecl_file_kw_type * file_kw = (ecl_file_kw_type*)vector_iget( ecl_file_view->kw_list , global_index); - return file_kw; + return ecl_file_view->kw_list[global_index]; } ecl_file_kw_type * ecl_file_view_iget_named_file_kw( const ecl_file_view_type * ecl_file_view , const char * kw, int ith) { @@ -188,12 +176,12 @@ void ecl_file_view_index_fload_kw(const ecl_file_view_type * ecl_file_view, cons int ecl_file_view_find_kw_value( const ecl_file_view_type * ecl_file_view , const char * kw , const void * value) { int global_index = -1; if ( ecl_file_view_has_kw( ecl_file_view , kw)) { - const int_vector_type * index_list = (const int_vector_type*)hash_get( ecl_file_view->kw_index , kw ); - int index = 0; - while (index < int_vector_size( index_list )) { - const ecl_kw_type * ecl_kw = ecl_file_view_iget_kw( ecl_file_view , int_vector_iget( index_list , index )); + const auto& index_list = ecl_file_view->kw_index.at(kw); + size_t index = 0; + while (index < index_list.size()) { + const ecl_kw_type * ecl_kw = ecl_file_view_iget_kw( ecl_file_view , index_list[index]); if (ecl_kw_data_equal( ecl_kw , value )) { - global_index = int_vector_iget( index_list , index ); + global_index = index_list[index]; break; } index++; @@ -212,7 +200,7 @@ int ecl_file_view_get_num_distinct_kw( const ecl_file_view_type * ecl_file_view } int ecl_file_view_get_size( const ecl_file_view_type * ecl_file_view ) { - return vector_get_size( ecl_file_view->kw_list ); + return ecl_file_view->kw_list.size(); } @@ -249,9 +237,9 @@ int ecl_file_view_iget_named_size( const ecl_file_view_type * ecl_file_view , co void ecl_file_view_replace_kw( ecl_file_view_type * ecl_file_view , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy) { - int index = 0; - while (index < vector_get_size( ecl_file_view->kw_list )) { - ecl_file_kw_type * ikw = (ecl_file_kw_type*)vector_iget( ecl_file_view->kw_list , index ); + size_t index = 0; + while (index < ecl_file_view->kw_list.size() ) { + auto * ikw = ecl_file_view->kw_list[index]; if (ecl_file_kw_ptr_eq( ikw , old_kw)) { /* Found it; observe that the vector_iset() function will @@ -276,11 +264,8 @@ bool ecl_file_view_load_all( ecl_file_view_type * ecl_file_view ) { bool loadOK = false; if (fortio_assert_stream_open( ecl_file_view->fortio )) { - int index; - for (index = 0; index < vector_get_size( ecl_file_view->kw_list); index++) { - ecl_file_kw_type * ikw = (ecl_file_kw_type*)vector_iget( ecl_file_view->kw_list , index ); - ecl_file_kw_get_kw( ikw , ecl_file_view->fortio , ecl_file_view->inv_map); - } + for (ecl_file_kw_type * file_kw : ecl_file_view->kw_list) + ecl_file_kw_get_kw( file_kw, ecl_file_view->fortio , ecl_file_view->inv_map); loadOK = true; } @@ -296,16 +281,18 @@ bool ecl_file_view_load_all( ecl_file_view_type * ecl_file_view ) { void ecl_file_view_add_kw( ecl_file_view_type * ecl_file_view , ecl_file_kw_type * file_kw) { - if (ecl_file_view->owner) - vector_append_owned_ref( ecl_file_view->kw_list , file_kw , ecl_file_kw_free__ ); - else - vector_append_ref( ecl_file_view->kw_list , file_kw); + ecl_file_view->kw_list.push_back( file_kw ); } void ecl_file_view_free( ecl_file_view_type * ecl_file_view ) { - vector_free( ecl_file_view->child_list ); - hash_free( ecl_file_view->kw_index ); - vector_free( ecl_file_view->kw_list ); + + for (auto& child_ptr : ecl_file_view->child_list) + ecl_file_view_free(child_ptr); + + if (ecl_file_view->owner) { + for (auto& kw_ptr : ecl_file_view->kw_list) + ecl_file_kw_free( kw_ptr ); + } delete ecl_file_view; } @@ -317,16 +304,15 @@ void ecl_file_view_free__( void * arg ) { int ecl_file_view_get_num_named_kw(const ecl_file_view_type * ecl_file_view , const char * kw) { - if (hash_has_key(ecl_file_view->kw_index , kw)) { - const int_vector_type * index_vector = (const int_vector_type*)hash_get(ecl_file_view->kw_index , kw); - return int_vector_size( index_vector ); + if (ecl_file_view_has_kw(ecl_file_view, kw)) { + const auto& index_vector = ecl_file_view->kw_index.at(kw); + return index_vector.size(); } else return 0; } void ecl_file_view_fwrite( const ecl_file_view_type * ecl_file_view , fortio_type * target , int offset) { - int index; - for (index = offset; index < vector_get_size( ecl_file_view->kw_list ); index++) { + for (size_t index = offset; index < ecl_file_view->kw_list.size(); index++) { ecl_kw_type * ecl_kw = ecl_file_view_iget_kw( ecl_file_view , index ); ecl_kw_fwrite( ecl_kw , target ); } @@ -336,18 +322,17 @@ void ecl_file_view_fwrite( const ecl_file_view_type * ecl_file_view , fortio_typ int ecl_file_view_iget_occurence( const ecl_file_view_type * ecl_file_view , int global_index) { - const ecl_file_kw_type * file_kw = (const ecl_file_kw_type*)vector_iget_const( ecl_file_view->kw_list , global_index); + const ecl_file_kw_type * file_kw = ecl_file_view->kw_list[global_index]; const char * header = ecl_file_kw_get_header( file_kw ); - const int_vector_type * index_vector = (const int_vector_type*)hash_get( ecl_file_view->kw_index , header ); - const int * index_data = int_vector_get_const_ptr( index_vector ); + const auto& index_vector = ecl_file_view->kw_index.at(header); int occurence = -1; { /* Manual reverse lookup. */ - int i; - for (i=0; i < int_vector_size( index_vector ); i++) - if (index_data[i] == global_index) + for (size_t i=0; i < index_vector.size(); i++) { + if (index_vector[i] == global_index) occurence = i; + } } if (occurence < 0) util_abort("%s: internal error ... \n" , __func__); @@ -356,9 +341,7 @@ int ecl_file_view_iget_occurence( const ecl_file_view_type * ecl_file_view , int } void ecl_file_view_fprintf_kw_list(const ecl_file_view_type * ecl_file_view , FILE * stream) { - int i; - for (i=0; i < vector_get_size( ecl_file_view->kw_list ); i++) { - const ecl_file_kw_type * file_kw = (const ecl_file_kw_type*)vector_iget_const( ecl_file_view->kw_list , i ); + for (auto& file_kw : ecl_file_view->kw_list) { char * type_name = ecl_type_alloc_name(ecl_file_kw_get_data_type(file_kw)); fprintf(stream , "%-8s %7d:%s\n", ecl_file_kw_get_header( file_kw ) , @@ -375,21 +358,21 @@ ecl_file_view_type * ecl_file_view_alloc_blockview2(const ecl_file_view_type * e ecl_file_view_type * block_map = ecl_file_view_alloc( ecl_file_view->fortio , ecl_file_view->flags , ecl_file_view->inv_map , false); - int kw_index = 0; + size_t kw_index = 0; if (start_kw) kw_index = ecl_file_view_get_global_index( ecl_file_view , start_kw , occurence ); { - ecl_file_kw_type * file_kw = (ecl_file_kw_type*)vector_iget( ecl_file_view->kw_list , kw_index ); + ecl_file_kw_type * file_kw = ecl_file_view->kw_list[kw_index]; while (true) { ecl_file_view_add_kw( block_map , file_kw ); kw_index++; - if (kw_index == vector_get_size( ecl_file_view->kw_list )) + if (kw_index == ecl_file_view->kw_list.size()) break; else { if (end_kw) { - file_kw = (ecl_file_kw_type*)vector_iget(ecl_file_view->kw_list , kw_index); + file_kw = ecl_file_view->kw_list[kw_index]; if (strcmp( end_kw , ecl_file_kw_get_header( file_kw )) == 0) break; } @@ -408,21 +391,21 @@ ecl_file_view_type * ecl_file_view_alloc_blockview(const ecl_file_view_type * ec } -ecl_file_view_type * ecl_file_view_add_blockview(const ecl_file_view_type * file_view , const char * header, int occurence) { +ecl_file_view_type * ecl_file_view_add_blockview(ecl_file_view_type * file_view , const char * header, int occurence) { ecl_file_view_type * child = ecl_file_view_alloc_blockview2(file_view, header, header, occurence); if (child) - vector_append_owned_ref( file_view->child_list , child , ecl_file_view_free__ ); + file_view->child_list.push_back(child); return child; } -ecl_file_view_type * ecl_file_view_add_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence) { +ecl_file_view_type * ecl_file_view_add_blockview2(ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence) { ecl_file_view_type * child = ecl_file_view_alloc_blockview2(ecl_file_view, start_kw , end_kw , occurence); if (child) - vector_append_owned_ref( ecl_file_view->child_list , child , ecl_file_view_free__ ); + ecl_file_view->child_list.push_back(child); return child; } @@ -593,10 +576,10 @@ double ecl_file_view_iget_restart_sim_days(const ecl_file_view_type * ecl_file_v int ecl_file_view_find_sim_time(const ecl_file_view_type * ecl_file_view , time_t sim_time) { int seqnum_index = -1; if ( ecl_file_view_has_kw( ecl_file_view , INTEHEAD_KW)) { - const int_vector_type * intehead_index_list = (const int_vector_type *)hash_get( ecl_file_view->kw_index , INTEHEAD_KW ); - int index = 0; - while (index < int_vector_size( intehead_index_list )) { - const ecl_kw_type * intehead_kw = ecl_file_view_iget_kw( ecl_file_view , int_vector_iget( intehead_index_list , index )); + const auto& intehead_index_list = ecl_file_view->kw_index.at(INTEHEAD_KW); + size_t index = 0; + while (index < intehead_index_list.size()) { + const ecl_kw_type * intehead_kw = ecl_file_view_iget_kw( ecl_file_view , intehead_index_list[index] ); if (ecl_rsthead_date( intehead_kw ) == sim_time) { seqnum_index = index; break; @@ -832,6 +815,8 @@ void ecl_file_view_end_transaction( ecl_file_view_type * file_view, ecl_file_tra ecl_file_kw_type * file_kw = ecl_file_view_iget_file_kw(file_view, i); ecl_file_kw_end_transaction(file_kw, ref_count[i]); } + free(transaction->ref_count); + free(transaction); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav.cpp index 42e96c240b..2503317369 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. @@ -20,9 +20,11 @@ #include #include +#include +#include +#include + #include -#include -#include #include #include @@ -69,12 +71,10 @@ struct ecl_grav_struct { const ecl_file_type * init_file; /* The init file - a shared reference owned by calling scope. */ ecl::ecl_grid_cache * grid_cache; /* An internal specialized structure to facilitate fast grid lookup. */ bool * aquifer_cell; /* Numerical aquifer cells should be ignored. */ - hash_type * surveys; /* A hash table containg ecl_grav_survey_type instances; one instance - for each interesting time. */ - hash_type * std_density; /* Hash table indexed with "SWAT" , "SGAS" and "SOIL"; each element - is a double_vector() instance which is indexed by PVTNUM - values. Used to lookup standard condition mass densities. Must - be suuplied by user __BEFORE__ adding a FIP based survey. */ + + std::unordered_map surveys; + std::unordered_map default_density; + std::unordered_map> std_density; }; @@ -90,10 +90,10 @@ struct ecl_grav_survey_struct { UTIL_TYPE_ID_DECLARATION; const ecl::ecl_grid_cache * grid_cache; const bool * aquifer_cell; - char * name; /* Name of the survey - arbitrary string. */ - double * porv; /* Reference shared by the ecl_grav_phase structures - i.e. it must not be updated. */ - vector_type * phase_list; /* ecl_grav_phase_type objects - one for each phase present in the model. */ - hash_type * phase_map; /* The same objects as in the phase_list vector - accessible by the "SWAT", "SGAS" and "SOIL" keys. */ + char * name; /* Name of the survey - arbitrary string. */ + double * porv; /* Reference shared by the ecl_grav_phase structures - i.e. it must not be updated. */ + std::vector phase_list; /* ecl_grav_phase_type objects - one for each phase present in the model. */ + std::unordered_map phase_map; /* The same objects as in the phase_list vector - accessible by the "SWAT", "SGAS" and "SOIL" keys. */ }; @@ -106,9 +106,9 @@ struct ecl_grav_phase_struct { UTIL_TYPE_ID_DECLARATION; const ecl::ecl_grid_cache * grid_cache; const bool * aquifer_cell; - double * fluid_mass; /* The total fluid in place (mass) of this phase - for each active cell.*/ - double * work; /* Temporary used in the summation over all cells. */ - ecl_phase_enum phase; + double * fluid_mass; /* The total fluid in place (mass) of this phase - for each active cell.*/ + double * work; /* Temporary used in the summation over all cells. */ + ecl_phase_enum phase; }; @@ -213,7 +213,7 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , const ecl::ecl_grid_cache * grid_cache = ecl_grav->grid_cache; const char * sat_kw_name = ecl_util_get_phase_name( phase ); { - ecl_grav_phase_type * grav_phase = (ecl_grav_phase_type*)util_malloc( sizeof * grav_phase ); + ecl_grav_phase_type * grav_phase = new ecl_grav_phase_type(); const int size = grid_cache->size(); UTIL_TYPE_ID_INIT( grav_phase , ECL_GRAV_PHASE_TYPE_ID ); @@ -225,7 +225,7 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , if (calc_type == GRAV_CALC_FIP) { ecl_kw_type * pvtnum_kw = ecl_file_iget_named_kw( init_file , PVTNUM_KW , 0 ); - double_vector_type * std_density = (double_vector_type*)hash_get( ecl_grav->std_density , ecl_util_get_phase_name( phase )); + const std::vector std_density = ecl_grav->std_density[std::string(ecl_util_get_phase_name(phase))]; ecl_kw_type * fip_kw; if ( phase == ECL_OIL_PHASE) @@ -240,7 +240,7 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , for (iactive=0; iactive < size; iactive++) { double fip = ecl_kw_iget_as_double( fip_kw , iactive ); int pvtnum = ecl_kw_iget_int( pvtnum_kw , iactive ); - grav_phase->fluid_mass[ iactive ] = fip * double_vector_safe_iget( std_density , pvtnum ); + grav_phase->fluid_mass[ iactive ] = fip * std_density[pvtnum]; } } } else { @@ -307,23 +307,18 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , static void ecl_grav_phase_free( ecl_grav_phase_type * grav_phase ) { free( grav_phase->work ); free( grav_phase->fluid_mass ); - free( grav_phase ); + delete grav_phase; } -static UTIL_SAFE_CAST_FUNCTION( ecl_grav_phase , ECL_GRAV_PHASE_TYPE_ID ) -static void ecl_grav_phase_free__( void * __grav_phase) { - ecl_grav_phase_type * grav_phase = ecl_grav_phase_safe_cast( __grav_phase ); - ecl_grav_phase_free( grav_phase ); -} /*****************************************************************/ static void ecl_grav_survey_add_phase( ecl_grav_survey_type * survey, ecl_phase_enum phase , ecl_grav_phase_type * grav_phase ) { - vector_append_owned_ref( survey->phase_list , grav_phase , ecl_grav_phase_free__ ); - hash_insert_ref( survey->phase_map , ecl_util_get_phase_name( phase ) , grav_phase ); + survey->phase_list.push_back(grav_phase); + survey->phase_map[std::string(ecl_util_get_phase_name(phase))] = grav_phase; } @@ -349,13 +344,11 @@ static void ecl_grav_survey_add_phases( ecl_grav_type * ecl_grav , ecl_grav_surv static ecl_grav_survey_type * ecl_grav_survey_alloc_empty(const ecl_grav_type * ecl_grav , const char * name , grav_calc_type calc_type) { - ecl_grav_survey_type * survey = (ecl_grav_survey_type*)util_malloc( sizeof * survey ); + ecl_grav_survey_type * survey = new ecl_grav_survey_type(); UTIL_TYPE_ID_INIT( survey , ECL_GRAV_SURVEY_ID ); survey->grid_cache = ecl_grav->grid_cache; survey->aquifer_cell = ecl_grav->aquifer_cell; survey->name = util_alloc_string_copy( name ); - survey->phase_list = vector_alloc_new(); - survey->phase_map = hash_alloc(); if (calc_type & GRAV_CALC_USE_PORV) survey->porv = (double*)util_calloc( ecl_grav->grid_cache->size() , sizeof * survey->porv ); @@ -365,8 +358,6 @@ static ecl_grav_survey_type * ecl_grav_survey_alloc_empty(const ecl_grav_type * return survey; } -static UTIL_SAFE_CAST_FUNCTION( ecl_grav_survey , ECL_GRAV_SURVEY_ID ) - /** Check that the rporv values are in the right ballpark. For ECLIPSE @@ -530,15 +521,12 @@ static ecl_grav_survey_type * ecl_grav_survey_alloc_RFIP(ecl_grav_type * ecl_gra static void ecl_grav_survey_free( ecl_grav_survey_type * grav_survey ) { free( grav_survey->name ); free( grav_survey->porv ); - vector_free( grav_survey->phase_list ); - hash_free( grav_survey->phase_map ); - free( grav_survey ); + for (auto * phase : grav_survey->phase_list) + ecl_grav_phase_free( phase ); + + delete grav_survey; } -static void ecl_grav_survey_free__( void * __grav_survey ) { - ecl_grav_survey_type * grav_survey = ecl_grav_survey_safe_cast( __grav_survey ); - ecl_grav_survey_free( grav_survey ); -} @@ -546,13 +534,12 @@ static double ecl_grav_survey_eval( const ecl_grav_survey_type * base_survey, const ecl_grav_survey_type * monitor_survey , ecl_region_type * region , double utm_x , double utm_y , double depth, int phase_mask) { - int phase_nr; double deltag = 0; - for (phase_nr = 0; phase_nr < vector_get_size( base_survey->phase_list ); phase_nr++) { - ecl_grav_phase_type * base_phase = (ecl_grav_phase_type*)vector_iget( base_survey->phase_list , phase_nr ); + for (std::size_t phase_nr = 0; phase_nr < base_survey->phase_list.size(); phase_nr++) { + ecl_grav_phase_type * base_phase = base_survey->phase_list[phase_nr]; if (base_phase->phase & phase_mask) { if (monitor_survey != NULL) { - const ecl_grav_phase_type * monitor_phase = (const ecl_grav_phase_type*)vector_iget_const( monitor_survey->phase_list , phase_nr ); + const ecl_grav_phase_type * monitor_phase = monitor_survey->phase_list[phase_nr]; deltag += ecl_grav_phase_eval( base_phase , monitor_phase , region , utm_x , utm_y , depth ); } else deltag += ecl_grav_phase_eval( base_phase , NULL , region , utm_x , utm_y , depth ); @@ -570,20 +557,19 @@ static double ecl_grav_survey_eval( const ecl_grav_survey_type * base_survey, */ ecl_grav_type * ecl_grav_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file) { - ecl_grav_type * ecl_grav = (ecl_grav_type*)util_malloc( sizeof * ecl_grav ); + ecl_grav_type * ecl_grav = new ecl_grav_type(); + ecl_grav->init_file = init_file; ecl_grav->grid_cache = new ecl::ecl_grid_cache(ecl_grid); ecl_grav->aquifer_cell = ecl_grav_common_alloc_aquifer_cell( *(ecl_grav->grid_cache) , ecl_grav->init_file ); - ecl_grav->surveys = hash_alloc(); - ecl_grav->std_density = hash_alloc(); return ecl_grav; } static void ecl_grav_add_survey__( ecl_grav_type * grav , const char * name , ecl_grav_survey_type * survey) { - hash_insert_hash_owned_ref( grav->surveys , name , survey , ecl_grav_survey_free__ ); + grav->surveys[name] = survey; } @@ -618,17 +604,15 @@ static ecl_grav_survey_type * ecl_grav_get_survey( const ecl_grav_type * grav , if (name == NULL) return NULL; // Calling scope must determine if this is OK? else { - if (hash_has_key( grav->surveys , name)) - return (ecl_grav_survey_type*)hash_get( grav->surveys , name ); + if (grav->surveys.count(name) > 0) + return grav->surveys.at(name); else { - hash_iter_type * survey_iter = hash_iter_alloc( grav->surveys ); fprintf(stderr,"Survey name:%s not registered. Available surveys are: \n\n " , name); - while (!hash_iter_is_complete( survey_iter )) { - const char * survey = hash_iter_get_next_key( survey_iter ); - fprintf(stderr,"%s ",survey); - } + + for (const auto& survey_pair : grav->surveys) + fprintf(stderr,"%s ",survey_pair.first.c_str()); + fprintf(stderr,"\n\n"); - hash_iter_free( survey_iter ); exit(1); } } @@ -660,8 +644,7 @@ double ecl_grav_eval( const ecl_grav_type * grav , const char * base, const char void ecl_grav_new_std_density( ecl_grav_type * grav , ecl_phase_enum phase , double default_density) { const char * phase_key = ecl_util_get_phase_name( phase ); - if (!hash_has_key( grav->std_density , phase_key )) - hash_insert_hash_owned_ref( grav->std_density , phase_key , double_vector_alloc( 0 , default_density ) , double_vector_free__ ); + grav->default_density[std::string(phase_key)] = default_density; } /** @@ -680,8 +663,10 @@ void ecl_grav_new_std_density( ecl_grav_type * grav , ecl_phase_enum phase , dou void ecl_grav_add_std_density( ecl_grav_type * grav , ecl_phase_enum phase , int pvtnum , double density) { - double_vector_type * std_density = (double_vector_type*)hash_get( grav->std_density , ecl_util_get_phase_name( phase )); - double_vector_iset( std_density , pvtnum , density ); + std::vector& std_density = grav->std_density[ std::string(ecl_util_get_phase_name(phase)) ]; + if (std_density.size() <= static_cast(pvtnum)) + std_density.resize(pvtnum + 1, grav->default_density[ std::string(ecl_util_get_phase_name(phase)) ]); + std_density[pvtnum] = density; } @@ -689,7 +674,9 @@ void ecl_grav_add_std_density( ecl_grav_type * grav , ecl_phase_enum phase , int void ecl_grav_free( ecl_grav_type * ecl_grav ) { delete ecl_grav->grid_cache; free( ecl_grav->aquifer_cell ); - hash_free( ecl_grav->surveys ); - hash_free( ecl_grav->std_density ); - free( ecl_grav ); + + for (const auto& survey_pair : ecl_grav->surveys) + ecl_grav_survey_free( survey_pair.second ); + + delete ecl_grav; } diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp index 240fc64a87..1c758a4701 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grav.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp index 9f63c9583c..8b33bc0fc5 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grav_common.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid.cpp index c01ece639a..2b59611a63 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2011 statoil asa, norway. + Copyright (c) 2011 equinor asa, norway. The file 'ecl_grid.c' is part of ert - ensemble based reservoir tool. @@ -21,12 +21,14 @@ #include #include #include + #include +#include +#include #include #include #include -#include #include #include @@ -726,7 +728,7 @@ struct ecl_grid_struct { char * parent_name; /* the name of the parent for a nested lgr - for the main grid, and also a lgr descending directly from the main grid this will be NULL. */ - hash_type * children; /* a table of lgr children for this grid. */ + std::unordered_map children; const ecl_grid_type * parent_grid; /* the parent grid for this (lgr) - NULL for the main grid. */ const ecl_grid_type * global_grid; /* the global grid - NULL for the main grid. */ @@ -739,7 +741,7 @@ struct ecl_grid_struct { */ vector_type * LGR_list; /* a vector of ecl_grid instances for LGRs - the index corresponds to the order LGRs are read from file*/ int_vector_type * lgr_index_map; /* a vector that maps LGR-nr for EGRID files to index into the LGR_list.*/ - hash_type * LGR_hash; /* a hash of pointers to ecl_grid instances - for name based lookup of lgr. */ + std::unordered_map LGR_hash; /* a hash of pointers to ecl_grid instances - for name based lookup of lgr. */ int parent_box[6]; /* integers i1,i2, j1,j2, k1,k2 of the parent grid region containing this lgr. the indices are inclusive - zero offset */ /* not used yet .. */ @@ -1534,7 +1536,7 @@ static ecl_grid_type * ecl_grid_alloc_empty(ecl_grid_type * global_grid, int nz, int lgr_nr, bool init_valid) { - ecl_grid_type * grid = (ecl_grid_type*)util_malloc(sizeof * grid ); + ecl_grid_type * grid = new ecl_grid_type(); UTIL_TYPE_ID_INIT(grid , ECL_GRID_ID); grid->total_active = 0; grid->total_active_fracture = 0; @@ -1586,16 +1588,13 @@ static ecl_grid_type * ecl_grid_alloc_empty(ecl_grid_type * global_grid, if (ECL_GRID_MAINGRID_LGR_NR == lgr_nr) { /* this is the main grid */ grid->LGR_list = vector_alloc_new(); grid->lgr_index_map = int_vector_alloc(0,0); - grid->LGR_hash = hash_alloc(); } else { grid->LGR_list = NULL; grid->lgr_index_map = NULL; - grid->LGR_hash = NULL; } grid->name = NULL; grid->parent_name = NULL; grid->parent_grid = NULL; - grid->children = hash_alloc(); grid->coarse_cells = vector_alloc_new(); grid->eclipse_version = 0; @@ -2104,13 +2103,15 @@ static void ecl_grid_init_mapaxes( ecl_grid_type * ecl_grid , bool apply_mapaxes static void ecl_grid_add_lgr( ecl_grid_type * main_grid , ecl_grid_type * lgr_grid) { vector_append_owned_ref( main_grid->LGR_list , lgr_grid , ecl_grid_free__); + if ( lgr_grid->lgr_nr >= int_vector_size(main_grid->lgr_index_map) ) + int_vector_resize( main_grid->lgr_index_map, lgr_grid->lgr_nr+1 , 0); int_vector_iset(main_grid->lgr_index_map, lgr_grid->lgr_nr, vector_get_size(main_grid->LGR_list)-1); - hash_insert_ref( main_grid->LGR_hash , lgr_grid->name , lgr_grid); + main_grid->LGR_hash[lgr_grid->name] = lgr_grid; } static void ecl_grid_install_lgr_common(ecl_grid_type * host_grid , ecl_grid_type * lgr_grid) { - hash_insert_ref( host_grid->children , lgr_grid->name , lgr_grid); + host_grid->children[lgr_grid->name] = lgr_grid; lgr_grid->parent_grid = host_grid; } @@ -3027,12 +3028,12 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const */ const int * actnum_data = NULL; if (ext_actnum) - actnum_data = ext_actnum; + actnum_data = ext_actnum; else { - if (ecl_file_get_num_named_kw(ecl_file, ACTNUM_KW) > grid_nr) { - actnum_kw = ecl_file_iget_named_kw(ecl_file, ACTNUM_KW, grid_nr); - actnum_data = ecl_kw_get_int_ptr(actnum_kw); - } + if (ecl_file_get_num_named_kw(ecl_file , ACTNUM_KW) > grid_nr) { + actnum_kw = ecl_file_iget_named_kw( ecl_file , ACTNUM_KW , grid_nr); + actnum_data = ecl_kw_get_int_ptr(actnum_kw); + } } if (grid_nr == 0) { @@ -4625,17 +4626,15 @@ void ecl_grid_free(ecl_grid_type * grid) { if (ECL_GRID_MAINGRID_LGR_NR == grid->lgr_nr) { /* This is the main grid. */ vector_free( grid->LGR_list ); int_vector_free( grid->lgr_index_map); - hash_free( grid->LGR_hash ); } if (grid->coord_kw != NULL) ecl_kw_free( grid->coord_kw ); vector_free( grid->coarse_cells ); - hash_free( grid->children ); free( grid->parent_name ); free( grid->visited ); free( grid->name ); - free( grid ); + delete grid; } @@ -5284,7 +5283,7 @@ ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * _ __assert_main_grid( main_grid ); { char * lgr_name = util_alloc_strip_copy( __lgr_name ); - ecl_grid_type * lgr_grid = (ecl_grid_type*)hash_get(main_grid->LGR_hash , lgr_name); + ecl_grid_type * lgr_grid = main_grid->LGR_hash.at(lgr_name); free(lgr_name); return lgr_grid; } @@ -5303,7 +5302,7 @@ bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name) __assert_main_grid( main_grid ); { char * lgr_name = util_alloc_strip_copy( __lgr_name ); - bool has_lgr = hash_has_key( main_grid->LGR_hash , lgr_name ); + bool has_lgr = main_grid->LGR_hash.count(lgr_name ) > 0; free(lgr_name); return has_lgr; } @@ -5425,7 +5424,10 @@ const ecl_grid_type * ecl_grid_get_global_grid( const ecl_grid_type * grid ) { stringlist_type * ecl_grid_alloc_lgr_name_list(const ecl_grid_type * ecl_grid) { __assert_main_grid( ecl_grid ); { - return hash_alloc_stringlist( ecl_grid->LGR_hash ); + stringlist_type * s = stringlist_alloc_new(); + for (const auto& lgr_pair : ecl_grid->LGR_hash) + stringlist_append_copy(s, lgr_pair.first.c_str()); + return s; } } @@ -5892,14 +5894,12 @@ static bool ecl_grid_test_lgr_consistency2( const ecl_grid_type * parent , const bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid ) { - hash_iter_type * lgr_iter = hash_iter_alloc( ecl_grid->children ); bool consistent = true; - while (!hash_iter_is_complete( lgr_iter )) { - const ecl_grid_type * lgr = (const ecl_grid_type*)hash_iter_get_next_value( lgr_iter ); + for (const auto& lgr_pair : ecl_grid->children) { + const ecl_grid_type * lgr = lgr_pair.second; consistent &= ecl_grid_test_lgr_consistency2( ecl_grid , lgr ); consistent &= ecl_grid_test_lgr_consistency( lgr ); } - hash_iter_free( lgr_iter ); return consistent; } @@ -6208,6 +6208,8 @@ static void ecl_grid_fwrite_GRID__( const ecl_grid_type * grid , int coords_size } } } + ecl_kw_free(coords_kw); + ecl_kw_free(corners_kw); } } @@ -6217,7 +6219,7 @@ void ecl_grid_fwrite_GRID2( const ecl_grid_type * grid , const char * filename, bool fmt_file = false; fortio_type * fortio = fortio_open_writer( filename , fmt_file , ECL_ENDIAN_FLIP ); - if (hash_get_size( grid->children ) > 0) + if (grid->children.size() > 0) coords_size = 7; if (grid->coarsening_active) @@ -6852,6 +6854,12 @@ static void ecl_grid_fwrite_EGRID__( ecl_grid_type * grid , fortio_type * fortio void ecl_grid_fwrite_EGRID2( ecl_grid_type * grid , const char * filename, ert_ecl_unit_enum output_unit) { bool fmt_file = false; + { + bool is_fmt; + + if (ecl_util_get_file_type( filename , &is_fmt, NULL ) != ECL_OTHER_FILE) + fmt_file = is_fmt; + } fortio_type * fortio = fortio_open_writer( filename , fmt_file , ECL_ENDIAN_FLIP ); ecl_grid_fwrite_EGRID__( grid , fortio, output_unit); diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp index 46dd0d9db5..7b2e394537 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grid_cache.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp index 8df249dcf1..f5fbeb2d69 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp index f8b1bc656f..dbca59ab56 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_init_file.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp b/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp index 9ad54c46be..893ff6f985 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_io_config.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_kw.cpp b/ThirdParty/Ert/lib/ecl/ecl_kw.cpp index b71c0c0ac6..abf24340ea 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_kw.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_kw.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp b/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp index 5d76c7f36d..3e60d55dc0 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp index 1e9f813927..434dfc4664 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_file_view.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_nnc_export.cpp b/ThirdParty/Ert/lib/ecl/ecl_nnc_export.cpp index 79cec6dabb..af05f4c3ac 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_nnc_export.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_nnc_export.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool. @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include @@ -26,11 +26,47 @@ #include -int ecl_nnc_export_get_size( const ecl_grid_type * grid ) { - return ecl_grid_get_num_nnc( grid ); + +/** + * Return true if the NNC information is stored in the Intersect format, false otherwise. + * In the Intersect format, the NNC information stored in the grid is unrealiable. + * The correct NNC data is stored in the init file instead + */ +bool ecl_nnc_intersect_format(const ecl_grid_type * grid, const ecl_file_type * init_file) { + if( !ecl_file_has_kw(init_file, NNC1_KW) || + !ecl_file_has_kw(init_file, NNC2_KW) || + !ecl_file_has_kw(init_file, TRANNNC_KW)) + return false; + // In the specific case we are treating, there should be just 1 occurrence of the kw + const auto nnc1_num = ecl_kw_get_size(ecl_file_iget_named_kw(init_file, NNC1_KW, 0)); + const auto nnc2_num = ecl_kw_get_size(ecl_file_iget_named_kw(init_file, NNC2_KW, 0)); + const auto tran_num = ecl_kw_get_size(ecl_file_iget_named_kw(init_file, TRANNNC_KW, 0)); + return nnc1_num == tran_num && nnc2_num == tran_num; } +int ecl_nnc_export_get_size( const ecl_grid_type * grid , const ecl_file_type * init_file ) { + return ecl_nnc_intersect_format(grid, init_file) ? + ecl_kw_get_size(ecl_file_iget_named_kw(init_file, TRANNNC_KW, 0)) : // Intersect format + ecl_grid_get_num_nnc( grid ); // Eclipse format +} + +static int ecl_nnc_export_intersect__(const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) { + const auto nnc1_kw = ecl_file_iget_named_kw(init_file, NNC1_KW, 0); + const auto nnc2_kw = ecl_file_iget_named_kw(init_file, NNC2_KW, 0); + const auto tran_kw = ecl_file_iget_named_kw(init_file, TRANNNC_KW, 0); + + auto nnc_index = *nnc_offset; + for(int i = 0; i < ecl_kw_get_size(tran_kw); ++i) { + auto const nnc1 = ecl_kw_iget_int(nnc1_kw, i); + auto const nnc2 = ecl_kw_iget_int(nnc2_kw, i); + auto const tran = ecl_kw_iget_as_double(tran_kw, i); + nnc_data[nnc_index] = ecl_nnc_type{0, nnc1, 0, nnc2, i, tran}; + ++nnc_index; + } + *nnc_offset = nnc_index; + return ecl_kw_get_size(tran_kw); // Assume all valid +} static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) { @@ -50,8 +86,8 @@ static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , cons int lgr_index2; for (lgr_index2=0; lgr_index2 < nnc_info_get_size( nnc_info ); lgr_index2++) { const nnc_vector_type * nnc_vector = nnc_info_iget_vector( nnc_info , lgr_index2 ); - const int_vector_type * grid2_index_list = nnc_vector_get_grid_index_list( nnc_vector ); - const int_vector_type * nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector ); + const std::vector& grid2_index_list = nnc_vector_get_grid_index_list( nnc_vector ); + const std::vector& nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector ); int lgr_nr2 = nnc_vector_get_lgr_nr( nnc_vector ); const ecl_kw_type * tran_kw = ecl_nnc_export_get_tranx_kw(global_grid , init_file , lgr_nr1 , lgr_nr2 ); @@ -63,8 +99,8 @@ static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , cons nnc.global_index1 = global_index1; for (index2 = 0; index2 < nnc_vector_get_size( nnc_vector ); index2++) { - nnc.global_index2 = int_vector_iget( grid2_index_list , index2 ); - nnc.input_index = int_vector_iget( nnc_index_list, index2 ); + nnc.global_index2 = grid2_index_list[index2]; + nnc.input_index = nnc_index_list[index2]; if(tran_kw) { nnc.trans = ecl_kw_iget_as_double(tran_kw, nnc.input_index); valid_trans++; @@ -86,15 +122,21 @@ static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , cons int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data) { int nnc_index = 0; int total_valid_trans = 0; - total_valid_trans = ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index ); - { - int lgr_index; - for (lgr_index = 0; lgr_index < ecl_grid_get_num_lgr(grid); lgr_index++) { - ecl_grid_type * igrid = ecl_grid_iget_lgr( grid , lgr_index ); - total_valid_trans += ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index ); - } + if(ecl_nnc_intersect_format(grid, init_file)) { + // Intersect format + total_valid_trans = ecl_nnc_export_intersect__(init_file, nnc_data, &nnc_index); + } + else { + // Eclipse format + total_valid_trans = ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index ); + { + for (int lgr_index = 0; lgr_index < ecl_grid_get_num_lgr(grid); lgr_index++) { + ecl_grid_type * igrid = ecl_grid_iget_lgr( grid , lgr_index ); + total_valid_trans += ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index ); + } + } + nnc_index = ecl_grid_get_num_nnc( grid ); } - nnc_index = ecl_nnc_export_get_size( grid ); ecl_nnc_sort( nnc_data , nnc_index ); return total_valid_trans; } diff --git a/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp b/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp index 36899a4824..a3f620e42c 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2017 statoil asa, norway. + Copyright (c) 2017 equinor asa, norway. The file 'ecl_nnc_geometry.c' is part of ert - ensemble based reservoir tool. @@ -61,8 +61,8 @@ static void ecl_nnc_geometry_add_pairs( const ecl_nnc_geometry_type * nnc_geo , for (int lgr_index2 = 0; lgr_index2 < nnc_info_get_size( nnc_info ); lgr_index2++) { const nnc_vector_type * nnc_vector = nnc_info_iget_vector( nnc_info , lgr_index2 ); - const int_vector_type * grid2_index_list = nnc_vector_get_grid_index_list( nnc_vector ); - const int_vector_type * nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector ); + const std::vector& grid2_index_list = nnc_vector_get_grid_index_list( nnc_vector ); + const std::vector& nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector ); int lgr_nr2 = nnc_vector_get_lgr_nr( nnc_vector ); for (int index2 = 0; index2 < nnc_vector_get_size( nnc_vector ); index2++) { @@ -70,8 +70,8 @@ static void ecl_nnc_geometry_add_pairs( const ecl_nnc_geometry_type * nnc_geo , pair.grid_nr1 = lgr_nr1; pair.global_index1 = global_index1; pair.grid_nr2 = lgr_nr2; - pair.global_index2 = int_vector_iget( grid2_index_list , index2 ); - pair.input_index = int_vector_iget( nnc_index_list, index2 ); + pair.global_index2 = grid2_index_list[index2]; + pair.input_index = nnc_index_list[index2]; nnc_geo->data->push_back(pair); } } diff --git a/ThirdParty/Ert/lib/ecl/ecl_region.cpp b/ThirdParty/Ert/lib/ecl/ecl_region.cpp index db63184266..ad92928efa 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_region.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_region.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_region.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp index b5c023689f..e70833514f 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. @@ -366,3 +366,9 @@ int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2) { const ecl_rft_cell_type * cell2 = ecl_rft_cell_safe_cast_const( arg2 ); return ecl_rft_cell_cmp( cell1 , cell2 ); } + + +bool ecl_rft_cell_lt( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2) { + return (ecl_rft_cell_cmp(cell1, cell2) < 0); +} + diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp index 553cb1c56d..adbb0e81b3 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -25,10 +25,12 @@ #include #endif +#include +#include +#include +#include + #include -#include -#include -#include #include #include @@ -55,19 +57,19 @@ struct ecl_rft_file_struct { UTIL_TYPE_ID_DECLARATION; - char * filename; - vector_type * data; /* This vector just contains all the rft nodes in one long vector. */ - hash_type * well_index; /* This indexes well names into the data vector - very similar to the scheme used in ecl_file. */ + std::string filename; + std::vector data; /* This vector just contains all the rft nodes in one long vector. */ + std::map> well_index; }; static ecl_rft_file_type * ecl_rft_file_alloc_empty(const char * filename) { - ecl_rft_file_type * rft_vector = (ecl_rft_file_type*)util_malloc(sizeof * rft_vector ); + ecl_rft_file_type * rft_vector = new ecl_rft_file_type(); + UTIL_TYPE_ID_INIT( rft_vector , ECL_RFT_FILE_ID ); - rft_vector->data = vector_alloc_new(); - rft_vector->filename = util_alloc_string_copy(filename); - rft_vector->well_index = hash_alloc(); + rft_vector->filename = std::string(filename); + return rft_vector; } @@ -82,8 +84,8 @@ UTIL_SAFE_CAST_FUNCTION( ecl_rft_file , ECL_RFT_FILE_ID ); UTIL_IS_INSTANCE_FUNCTION( ecl_rft_file , ECL_RFT_FILE_ID ); -static void ecl_rft_file_add_node(ecl_rft_file_type * rft_vector , const ecl_rft_node_type * rft_node) { - vector_append_owned_ref( rft_vector->data , rft_node , ecl_rft_node_free__); +static void ecl_rft_file_add_node(ecl_rft_file_type * rft_vector , ecl_rft_node_type * rft_node) { + rft_vector->data.push_back(rft_node); } @@ -100,15 +102,12 @@ ecl_rft_file_type * ecl_rft_file_alloc(const char * filename) { if (rft_view) { ecl_rft_node_type * rft_node = ecl_rft_node_alloc( rft_view ); - if (rft_node != NULL) { + if (rft_node) { const char * well_name = ecl_rft_node_get_well_name( rft_node ); ecl_rft_file_add_node(rft_vector , rft_node); - if (!hash_has_key( rft_vector->well_index , well_name)) - hash_insert_hash_owned_ref( rft_vector->well_index , well_name , int_vector_alloc( 0 , 0 ) , int_vector_free__); - { - int_vector_type * index_list = (int_vector_type*)hash_get( rft_vector->well_index , well_name ); - int_vector_append(index_list , global_index); - } + + auto& index_vector = rft_vector->well_index[well_name]; + index_vector.push_back(global_index); global_index++; } } else @@ -194,10 +193,10 @@ bool ecl_rft_file_case_has_rft( const char * case_input ) { void ecl_rft_file_free(ecl_rft_file_type * rft_vector) { - vector_free(rft_vector->data); - hash_free( rft_vector->well_index ); - free(rft_vector->filename); - free(rft_vector); + for (auto node_ptr : rft_vector->data) + ecl_rft_node_free( node_ptr ); + + delete rft_vector; } @@ -223,12 +222,11 @@ void ecl_rft_file_free__(void * arg) { int ecl_rft_file_get_size__( const ecl_rft_file_type * rft_file, const char * well_pattern , time_t recording_time) { if ((well_pattern == NULL) && (recording_time < 0)) - return vector_get_size( rft_file->data ); + return rft_file->data.size(); else { int match_count = 0; - int i; - for ( i=0; i < vector_get_size( rft_file->data ); i++) { - const ecl_rft_node_type * rft = (const ecl_rft_node_type*)vector_iget_const( rft_file->data , i); + for (size_t i=0; i < rft_file->data.size(); i++) { + const ecl_rft_node_type * rft = rft_file->data[i]; if (well_pattern) { if (util_fnmatch( well_pattern , ecl_rft_node_get_well_name( rft )) != 0) @@ -260,7 +258,7 @@ int ecl_rft_file_get_size( const ecl_rft_file_type * rft_file) { const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ) { - return rft_file->filename; + return rft_file->filename.c_str(); } @@ -274,7 +272,7 @@ const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ) { */ ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index) { - return (ecl_rft_node_type*)vector_iget( rft_file->data , index ); + return rft_file->data[index]; } @@ -306,30 +304,32 @@ ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index) { - const int_vector_type * index_vector = (const int_vector_type*)hash_get(rft_file->well_index , well); - return ecl_rft_file_iget_node( rft_file , int_vector_iget(index_vector , index)); + const auto& index_vector = rft_file->well_index.at(well); + return ecl_rft_file_iget_node( rft_file , index_vector[index]); } static int ecl_rft_file_get_node_index_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) { + const auto& pair_iter = rft_file->well_index.find(well); + if (pair_iter == rft_file->well_index.end()) + return -1; + int global_index = -1; - if (hash_has_key( rft_file->well_index , well)) { - const int_vector_type * index_vector = (const int_vector_type*)hash_get(rft_file->well_index , well); - int well_index = 0; - while (true) { - if (well_index == int_vector_size( index_vector )) + size_t well_index = 0; + const auto& index_vector = pair_iter->second; + while (true) { + if (well_index == index_vector.size()) + break; + + { + const ecl_rft_node_type * node = ecl_rft_file_iget_node( rft_file , index_vector[well_index]); + if (ecl_rft_node_get_date( node ) == recording_time) { + global_index = index_vector[well_index]; break; - - { - const ecl_rft_node_type * node = ecl_rft_file_iget_node( rft_file , int_vector_iget( index_vector , well_index )); - if (ecl_rft_node_get_date( node ) == recording_time) { - global_index = int_vector_iget( index_vector , well_index ); - break; - } } - - well_index++; } + + well_index++; } return global_index; } @@ -355,7 +355,7 @@ ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rf bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well) { - return hash_has_key(rft_file->well_index , well); + return (rft_file->well_index.find(well) != rft_file->well_index.end()); } @@ -364,8 +364,11 @@ bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * we */ int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const char * well) { - const int_vector_type * index_vector = (const int_vector_type*)hash_get(rft_file->well_index , well); - return int_vector_size( index_vector ); + const auto& pair_iter = rft_file->well_index.find(well); + if (pair_iter == rft_file->well_index.end()) + return 0; + else + return pair_iter->second.size(); } @@ -373,13 +376,18 @@ int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const Returns the number of distinct wells in RFT file. */ int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file ) { - return hash_get_size( rft_file->well_index ); + return rft_file->well_index.size(); } stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file ) { - return hash_alloc_stringlist( rft_file->well_index ); + stringlist_type * well_list = stringlist_alloc_new(); + + for (const auto& pair : rft_file->well_index) + stringlist_append_copy(well_list, pair.first.c_str()); + + return well_list; } @@ -396,7 +404,8 @@ void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes, if (storage_index == -1) { ecl_rft_file_add_node(rft_file, new_node); } else { - vector_iset_owned_ref(rft_file->data, storage_index, new_node,ecl_rft_node_free__); + ecl_rft_node_free(rft_file->data[storage_index]); + rft_file->data[storage_index] = new_node; } } }else{ @@ -410,7 +419,6 @@ void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes, { bool fmt_file = false; fortio_type * fortio = fortio_open_writer( rft_file_name , fmt_file , ECL_ENDIAN_FLIP ); - int node_index; /** The sorting here works directly on the internal node storage @@ -421,9 +429,9 @@ void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes, avoided for the rest of this function. */ - vector_sort(rft_file->data,(vector_cmp_ftype *) ecl_rft_node_cmp); - for(node_index=0; node_index < vector_get_size( rft_file->data ); node_index++) { - const ecl_rft_node_type *new_node = (const ecl_rft_node_type*)vector_iget_const(rft_file->data, node_index); + std::sort(rft_file->data.begin(), rft_file->data.end(), ecl_rft_node_lt); + for(size_t node_index=0; node_index < rft_file->data.size(); node_index++) { + const ecl_rft_node_type *new_node = rft_file->data[node_index]; ecl_rft_node_fwrite(new_node, fortio, unit_set); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp index 7290dccb73..48d4c58130 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_node.c' is part of ERT - Ensemble based Reservoir Tool. @@ -23,10 +23,11 @@ #include #include +#include +#include +#include + #include -#include -#include -#include #include #include @@ -57,16 +58,14 @@ #define ECL_RFT_NODE_ID 887195 struct ecl_rft_node_struct { UTIL_TYPE_ID_DECLARATION; - char * well_name; /* Name of the well. */ + std::string well_name; ecl_rft_enum data_type; /* What type of data: RFT|PLT|SEGMENT */ time_t recording_date; /* When was the RFT recorded - date.*/ double days; /* When was the RFT recorded - days after simulaton start. */ bool MSW; - bool sort_perm_in_sync ; - int_vector_type * sort_perm; - vector_type *cells; + std::vector cells; }; @@ -106,15 +105,13 @@ static ecl_rft_enum translate_from_sting_to_ecl_rft_enum(const char * data_type_ ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days){ ecl_rft_enum data_type = translate_from_sting_to_ecl_rft_enum(data_type_string); - ecl_rft_node_type * rft_node = (ecl_rft_node_type*)util_malloc(sizeof * rft_node ); + ecl_rft_node_type * rft_node = new ecl_rft_node_type(); + UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID ); - rft_node->well_name = util_alloc_string_copy(well_name); - rft_node->cells = vector_alloc_new(); + rft_node->well_name = std::string(well_name); rft_node->recording_date = recording_date; rft_node->days = days; rft_node->data_type = data_type; - rft_node->sort_perm = NULL; - rft_node->sort_perm_in_sync = false; return rft_node; } @@ -130,13 +127,10 @@ static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_strin } { - ecl_rft_node_type * rft_node = (ecl_rft_node_type*)util_malloc(sizeof * rft_node ); - UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID ); + ecl_rft_node_type * rft_node = new ecl_rft_node_type(); - rft_node->cells = vector_alloc_new(); + UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID ); rft_node->data_type = data_type; - rft_node->sort_perm = NULL; - rft_node->sort_perm_in_sync = false; return rft_node; } @@ -148,8 +142,11 @@ UTIL_IS_INSTANCE_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID ); void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) { - vector_append_owned_ref( rft_node->cells , cell , ecl_rft_cell_free__ ); - rft_node->sort_perm_in_sync = false; + if (rft_node->MSW) { + auto pos_iter = std::upper_bound(rft_node->cells.begin(), rft_node->cells.end(), cell, ecl_rft_cell_lt); + rft_node->cells.insert(pos_iter, cell); + } else + rft_node->cells.push_back( cell ); } @@ -273,8 +270,11 @@ ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_view_type * rft_view) { if (rft_node != NULL) { ecl_kw_type * date_kw = ecl_file_view_iget_named_kw( rft_view , DATE_KW , 0); - rft_node->well_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr(welletc , WELLETC_NAME_INDEX)); - + { + char * tmp = util_alloc_strip_copy( (const char*) ecl_kw_iget_ptr(welletc, WELLETC_NAME_INDEX)); + rft_node->well_name = std::string( tmp ); + free(tmp); + } /* Time information. */ { int * time = ecl_kw_get_int_ptr( date_kw ); @@ -293,18 +293,15 @@ ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_view_type * rft_view) { const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) { - return rft_node->well_name; + return rft_node->well_name.c_str(); } void ecl_rft_node_free(ecl_rft_node_type * rft_node) { + for (auto cell_ptr : rft_node->cells) + ecl_rft_cell_free( cell_ptr ); - free(rft_node->well_name); - vector_free( rft_node->cells ); - if (rft_node->sort_perm) - int_vector_free( rft_node->sort_perm ); - - free(rft_node); + delete rft_node; } void ecl_rft_node_free__(void * void_node) { @@ -316,7 +313,7 @@ void ecl_rft_node_free__(void * void_node) { -int ecl_rft_node_get_size(const ecl_rft_node_type * rft_node) { return vector_get_size( rft_node->cells ); } +int ecl_rft_node_get_size(const ecl_rft_node_type * rft_node) { return rft_node->cells.size(); } time_t ecl_rft_node_get_date(const ecl_rft_node_type * rft_node) { return rft_node->recording_date; } ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node) { return rft_node->data_type; } @@ -325,32 +322,13 @@ ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node) { return /* various functions to access properties at the cell level */ const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index) { - return (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index ); + return rft_node->cells[index]; } -static void ecl_rft_node_create_sort_perm( ecl_rft_node_type * rft_node ) { - if (rft_node->sort_perm) - int_vector_free( rft_node->sort_perm ); - - rft_node->sort_perm = vector_alloc_sort_perm( rft_node->cells , ecl_rft_cell_cmp__ ); - rft_node->sort_perm_in_sync = true; -} - -void ecl_rft_node_inplace_sort_cells( ecl_rft_node_type * rft_node ) { - vector_sort( rft_node->cells , ecl_rft_cell_cmp__ ); - rft_node->sort_perm_in_sync = false; // The permutation is no longer sorted; however the vector itself is sorted .... -} const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft_node , int index) { - if (ecl_rft_node_is_RFT( rft_node )) - return ecl_rft_node_iget_cell( rft_node , index ); - else { - if (!rft_node->sort_perm_in_sync) - ecl_rft_node_create_sort_perm( rft_node ); - - return (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , int_vector_iget( rft_node->sort_perm , index )); - } + return rft_node->cells[index]; } @@ -396,14 +374,14 @@ static void assert_type_and_index( const ecl_rft_node_type * rft_node , ecl_rft_ if (rft_node->data_type != target_type) util_abort("%s: wrong type \n",__func__); - if ((index < 0) || (index >= vector_get_size( rft_node->cells ))) + if ((index < 0) || (index >= static_cast(rft_node->cells.size()))) util_abort("%s: invalid index:%d \n",__func__ , index); } double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , RFT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index ); + const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell(rft_node, index); return ecl_rft_cell_get_sgas( cell ); } } @@ -412,7 +390,7 @@ double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index) { double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , RFT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index ); + const ecl_rft_cell_type * cell = rft_node->cells[index]; return ecl_rft_cell_get_swat( cell ); } } @@ -424,7 +402,7 @@ double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ){ double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , RFT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index ); + const ecl_rft_cell_type * cell = rft_node->cells[index]; return ecl_rft_cell_get_soil( cell ); } } @@ -435,7 +413,7 @@ double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index) { double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , PLT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index ); + const ecl_rft_cell_type * cell = rft_node->cells[index]; return ecl_rft_cell_get_orat( cell ); } } @@ -444,7 +422,7 @@ double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index) { double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , PLT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index); + const ecl_rft_cell_type * cell = rft_node->cells[index]; return ecl_rft_cell_get_wrat( cell ); } } @@ -453,7 +431,7 @@ double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index) { double ecl_rft_node_iget_grat( const ecl_rft_node_type * rft_node , int index) { assert_type_and_index( rft_node , PLT , index ); { - const ecl_rft_cell_type * cell = (const ecl_rft_cell_type*)vector_iget_const( rft_node->cells , index); + const ecl_rft_cell_type * cell = rft_node->cells[index]; return ecl_rft_cell_get_grat( cell ); } } @@ -591,10 +569,9 @@ void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * forti ecl_kw_type * pressure = ecl_kw_alloc(PRESSURE_KW, size_cells, ECL_FLOAT); ecl_kw_type * swat = ecl_kw_alloc(SWAT_KW, size_cells, ECL_FLOAT); ecl_kw_type * sgas = ecl_kw_alloc(SGAS_KW, size_cells, ECL_FLOAT); - int i; - for(i =0;icells , i); + for(int i =0;icells[i]; ecl_kw_iset_int(conipos, i, ecl_rft_cell_get_i(cell)+1); ecl_kw_iset_int(conjpos, i, ecl_rft_cell_get_j(cell)+1); ecl_kw_iset_int(conkpos, i, ecl_rft_cell_get_k(cell)+1); @@ -636,4 +613,6 @@ int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n } - +bool ecl_rft_node_lt(const ecl_rft_node_type * n1, const ecl_rft_node_type * n2) { + return (ecl_rft_node_cmp(n1, n2) < 0); +} diff --git a/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp index 4c3e903f6e..484e11b237 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp @@ -1,6 +1,6 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_rst_file.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp b/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp index 3c002cb9c5..d7bbb00e38 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rsthead.c' is part of ERT - Ensemble based Reservoir Tool. @@ -88,10 +88,7 @@ ecl_rsthead_type * ecl_rsthead_alloc_from_kw( int report_step , const ecl_kw_typ // The only derived quantity rsthead->sim_time = rsthead_date( rsthead->day , rsthead->month , rsthead->year ); } - - if (doubhead_kw) - rsthead->sim_days = ecl_kw_iget_double( doubhead_kw , DOUBHEAD_DAYS_INDEX ); - + rsthead->sim_days = ecl_kw_iget_double( doubhead_kw , DOUBHEAD_DAYS_INDEX ); if (logihead_kw) rsthead->dualp = ecl_kw_iget_bool( logihead_kw , LOGIHEAD_DUALP_INDEX); @@ -112,15 +109,12 @@ ecl_rsthead_type * ecl_rsthead_alloc_from_kw( int report_step , const ecl_kw_typ ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_view_type * rst_view, int report_step) { const ecl_kw_type * intehead_kw = ecl_file_view_iget_named_kw( rst_view , INTEHEAD_KW , 0); - const ecl_kw_type * doubhead_kw = NULL; + const ecl_kw_type * doubhead_kw = ecl_file_view_iget_named_kw( rst_view , DOUBHEAD_KW , 0); const ecl_kw_type * logihead_kw = NULL; if (ecl_file_view_has_kw(rst_view, LOGIHEAD_KW)) logihead_kw = ecl_file_view_iget_named_kw( rst_view , LOGIHEAD_KW , 0); - if (ecl_file_view_has_kw(rst_view, DOUBHEAD_KW)) - doubhead_kw = ecl_file_view_iget_named_kw(rst_view, DOUBHEAD_KW, 0); - if (ecl_file_view_has_kw( rst_view , SEQNUM_KW)) { const ecl_kw_type * seqnum_kw = ecl_file_view_iget_named_kw( rst_view , SEQNUM_KW , 0); report_step = ecl_kw_iget_int( seqnum_kw , 0); diff --git a/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp b/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp index dbefb53bd9..ea0a095368 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_smspec.c' is part of ERT - Ensemble based Reservoir Tool. @@ -22,12 +22,18 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include -#include -#include #include #include +#include "detail/util/path.hpp" #include #include @@ -52,7 +58,7 @@ ------------------------------- 1. The function smspec_node_alloc() must be updated to return a valid - smspec_node_type instance when called with the new var_type. + ecl::smspec_node instance when called with the new var_type. 2. Update the function ecl_smpec_install_gen_key() to install smpec_index instances of this particular type. The format of the general key is @@ -95,7 +101,7 @@ #define ECL_SMSPEC_ID 806647 #define PARAMS_GLOBAL_DEFAULT -99 - +typedef std::map node_map; struct ecl_smspec_struct { UTIL_TYPE_ID_DECLARATION; @@ -104,31 +110,33 @@ struct ecl_smspec_struct { smspec_node instances. The actual smspec_node instances are owned by the smspec_nodes vector; */ - hash_type * well_var_index; /* Indexes for all well variables: {well1: {var1: index1 , var2: index2} , well2: {var1: index1 , var2: index2}} */ - hash_type * well_completion_var_index; /* Indexes for completion indexes .*/ - hash_type * group_var_index; /* Indexes for group variables.*/ - hash_type * field_var_index; - hash_type * region_var_index; /* The stored index is an offset. */ - hash_type * misc_var_index; /* Variables like 'TCPU' and 'NEWTON'. */ - hash_type * block_var_index; /* Block variables like BPR */ - hash_type * gen_var_index; /* This is "everything" - things can either be found as gen_var("WWCT:OP_X") or as well_var("WWCT" , "OP_X") */ + node_map field_var_index; + node_map misc_var_index; /* Variables like 'TCPU' and 'NEWTON'. */ + node_map gen_var_index /* This is "everything" - things can either be found as gen_var("WWCT:OP_X") or as well_var("WWCT" , "OP_X") */; + + std::map well_var_index; /* Indexes for all well variables: + {well1: {var1: index1 , var2: index2} , well2: {var1: index1 , var2: index2}} */ + std::map group_var_index; /* Indexes for group variables.*/ + std::map region_var_index; /* The stored index is an offset. */ + std::map block_var_index; /* Block variables like BPR */ + std::map> well_completion_var_index; /* Indexes for completion indexes .*/ - vector_type * smspec_nodes; + std::vector> smspec_nodes; bool write_mode; bool need_nums; - int_vector_type * index_map; - + std::vector index_map; + std::map inv_index_map; + int params_size; /*-----------------------------------------------------------------*/ int time_seconds; int grid_dims[3]; /* Grid dimensions - in DIMENS[1,2,3] */ int num_regions; int Nwells , param_offset; - int params_size; - const char * key_join_string; /* The string used to join keys when building gen_key keys - typically ":" - + std::string key_join_string; /* The string used to join keys when building gen_key keys - typically ":" - but arbitrary - NOT necessary to be able to invert the joining. */ - char * header_file; /* FULL path to the currenbtly loaded header_file. */ + std::string header_file; /* FULL path to the currenbtly loaded header_file. */ bool formatted; /* Has this summary instance been loaded from a formatted (i.e. FSMSPEC file) or unformatted (i.e. SMSPEC) file. */ time_t sim_start_time; /* When did the simulation start - worldtime. */ @@ -138,9 +146,9 @@ struct ecl_smspec_struct { int month_index; /* time information. */ int year_index; bool has_lgr; - float_vector_type * params_default; + std::vector params_default; - char * restart_case; + std::string restart_case; ert_ecl_unit_enum unit_system; int restart_step; }; @@ -201,33 +209,6 @@ Completion var: VAR_TYPE:WELL_NAME:NUM */ -/** - The special_vars list is used to associate keywords with special - types, when the kewyord name is in conflict with the default vector - naming convention; all the variables mentioned in the list below - are given the type ECL_SMSPEC_MISC_VAR. - - For instance the keyword 'NEWTON' starts with 'N' and is - classified as a NETWORK type variable. However it should rather - be classified as a MISC type variable. (What a fucking mess). - - The special_vars list is used in the functions - ecl_smspec_identify_special_var() and ecl_smspec_identify_var_type(). -*/ - -static const char* special_vars[] = {"NEWTON", - "NAIMFRAC", - "NLINEARS", - "NLINSMIN", - "NLINSMAX", - "ELAPSED", - "MAXDPR", - "MAXDSO", - "MAXDSG", - "MAXDSW", - "STEPTYPE", - "WNEWTON"}; - /* @@ -248,33 +229,69 @@ static const char* smspec_required_keywords[] = { DIMENS_KW }; +namespace { + +const ecl::smspec_node * ecl_smspec_get_var_node( const node_map& mp, const char * var) { + const auto it = mp.find(var); + if (it == mp.end()) + return nullptr; + + return it->second; + } + + const ecl::smspec_node * ecl_smspec_get_str_key_var_node( const std::map& mp , const char * key , const char * var) { + const auto key_it = mp.find(key); + if (key_it == mp.end()) + return nullptr; + + const node_map& var_map = key_it->second; + return ecl_smspec_get_var_node(var_map, var); + } + + const ecl::smspec_node * ecl_smspec_get_int_key_var_node(const std::map& mp , int key , const char * var) { + const auto key_it = mp.find(key); + if (key_it == mp.end()) + return nullptr; + + const auto& var_map = key_it->second; + return ecl_smspec_get_var_node(var_map, var); + } + +} //end namespace + +int ecl_smspec_num_nodes( const ecl_smspec_type * smspec) { + return smspec->smspec_nodes.size(); +} + +/* + When loading a summary case from file many of the nodes can be ignored, in + that case the size of PARAMS vector in the data files is larger than the + number of internalized nodes. Therefor we need to maintain the + params_size member. +*/ + +int ecl_smspec_get_params_size( const ecl_smspec_type * smspec ) { + return smspec->params_size; +} + + /*****************************************************************/ ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join_string) { - ecl_smspec_type *ecl_smspec; - ecl_smspec = (ecl_smspec_type*)util_malloc(sizeof *ecl_smspec ); + ecl_smspec_type * ecl_smspec = new ecl_smspec_type(); UTIL_TYPE_ID_INIT(ecl_smspec , ECL_SMSPEC_ID); - ecl_smspec->well_var_index = hash_alloc(); - ecl_smspec->well_completion_var_index = hash_alloc(); - ecl_smspec->group_var_index = hash_alloc(); - ecl_smspec->field_var_index = hash_alloc(); - ecl_smspec->region_var_index = hash_alloc(); - ecl_smspec->misc_var_index = hash_alloc(); - ecl_smspec->block_var_index = hash_alloc(); - ecl_smspec->gen_var_index = hash_alloc(); ecl_smspec->sim_start_time = -1; ecl_smspec->key_join_string = key_join_string; - ecl_smspec->header_file = NULL; - - ecl_smspec->smspec_nodes = vector_alloc_new(); + ecl_smspec->header_file = ""; ecl_smspec->time_index = -1; ecl_smspec->day_index = -1; ecl_smspec->year_index = -1; ecl_smspec->month_index = -1; ecl_smspec->time_seconds = -1; + ecl_smspec->params_size = -1; /* The unit system is given as an integer in the INTEHEAD keyword. The INTEHEAD @@ -283,10 +300,7 @@ ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join */ ecl_smspec->unit_system = ECL_METRIC_UNITS; - ecl_smspec->index_map = int_vector_alloc(0,0); - ecl_smspec->restart_case = NULL; ecl_smspec->restart_step = -1; - ecl_smspec->params_default = float_vector_alloc(0 , PARAMS_GLOBAL_DEFAULT); ecl_smspec->write_mode = write_mode; ecl_smspec->need_nums = false; @@ -296,19 +310,19 @@ ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_type * other) { int params_size = ecl_smspec_get_params_size( self ); - int * mapping = (int*)util_malloc( params_size * sizeof * mapping ); + int * mapping = (int*) util_malloc( params_size * sizeof * mapping ); for (int i = 0; i < params_size; i++) mapping[i] = -1; for (int i=0; i < ecl_smspec_num_nodes( self ); i++) { - const smspec_node_type * self_node = ecl_smspec_iget_node( self , i ); - int self_index = smspec_node_get_params_index( self_node ); - const char * key = smspec_node_get_gen_key1( self_node ); + const ecl::smspec_node& self_node = ecl_smspec_iget_node_w_node_index( self , i ); + int self_index = self_node.get_params_index(); + const char * key = self_node.get_gen_key1(); if (ecl_smspec_has_general_var( other , key)) { - const smspec_node_type * other_node = ecl_smspec_get_general_var_node( other , key); - int other_index = smspec_node_get_params_index(other_node); + const ecl::smspec_node& other_node = ecl_smspec_get_general_var_node( other , key); + int other_index = other_node.get_params_index(); mapping[ self_index ] = other_index; } } @@ -324,14 +338,25 @@ int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_t */ -const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index ) { - return (const smspec_node_type*)vector_safe_iget_const( smspec->smspec_nodes , index ); +const ecl::smspec_node& ecl_smspec_iget_node_w_node_index( const ecl_smspec_type * smspec , int node_index ) { + const auto& node = smspec->smspec_nodes[node_index]; + return *node.get(); } -int ecl_smspec_num_nodes( const ecl_smspec_type * smspec) { - return vector_get_size( smspec->smspec_nodes ); + +/* + The ecl_smspec_iget_node() function is only retained for compatibility; should be + replaced with calls to the more explicit: ecl_smspec_iget_node_w_node_index(). +*/ + +const ecl::smspec_node& ecl_smspec_iget_node(const ecl_smspec_type * smspec, int index) { + return ecl_smspec_iget_node_w_node_index(smspec, index); } +const ecl::smspec_node& ecl_smspec_iget_node_w_params_index( const ecl_smspec_type * smspec , int params_index ) { + int node_index = smspec->inv_index_map.at(params_index); + return ecl_smspec_iget_node_w_node_index(smspec, node_index); +} /** * Returns an ecl data type for which all names will fit. If the maximum name @@ -341,8 +366,8 @@ int ecl_smspec_num_nodes( const ecl_smspec_type * smspec) { static ecl_data_type get_wgnames_type(const ecl_smspec_type * smspec) { size_t max_len = 0; for(int i = 0; i < ecl_smspec_num_nodes(smspec); ++i) { - const smspec_node_type * node = ecl_smspec_iget_node(smspec, i); - const char * name = smspec_node_get_wgname( node ); + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(smspec, i); + const char * name = smspec_node_get_wgname( &node ); if(name) max_len = util_size_t_max(max_len, strlen(name)); } @@ -367,11 +392,11 @@ static void ecl_smspec_fwrite_RESTART(const ecl_smspec_type * smspec, fortio_typ for (int i=0; i < SUMMARY_RESTART_SIZE; i++) ecl_kw_iset_string8( restart_kw , i , ""); - if (smspec->restart_case != NULL) { - int restart_case_len = strlen(smspec->restart_case); + if (smspec->restart_case.size() > 0) { + size_t restart_case_len = smspec->restart_case.size(); - int offset = 0; - for (int i = 0; i < SUMMARY_RESTART_SIZE ; i++) { + size_t offset = 0; + for (size_t i = 0; i < SUMMARY_RESTART_SIZE ; i++) { if (offset < restart_case_len) ecl_kw_iset_string8( restart_kw , i , &smspec->restart_case[ offset ]); offset += ECL_STRING8_LENGTH; @@ -433,7 +458,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty nums_kw = ecl_kw_alloc( NUMS_KW , num_nodes , ECL_INT); for (int i=0; i < ecl_smspec_num_nodes( smspec ); i++) { - const smspec_node_type * smspec_node = ecl_smspec_iget_node( smspec , i ); + const ecl::smspec_node& smspec_node = ecl_smspec_iget_node_w_node_index( smspec , i ); /* It is possible to add variables with deferred initialisation with the ecl_sum_add_blank_var() function. Before these @@ -453,23 +478,23 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty ignored when/if this smspec file is read in at a later stage. */ - if (smspec_node_get_var_type( smspec_node ) == ECL_SMSPEC_INVALID_VAR) { + if (smspec_node.get_var_type() == ECL_SMSPEC_INVALID_VAR) { ecl_kw_iset_string8( keywords_kw , i , "WWCT" ); ecl_kw_iset_string8( units_kw , i , "????????"); ecl_kw_iset_string_ptr( wgnames_kw , i , DUMMY_WELL); } else { - ecl_kw_iset_string8( keywords_kw , i , smspec_node_get_keyword( smspec_node )); - ecl_kw_iset_string8( units_kw , i , smspec_node_get_unit( smspec_node )); + ecl_kw_iset_string8( keywords_kw , i , smspec_node_get_keyword( &smspec_node )); + ecl_kw_iset_string8( units_kw , i , smspec_node_get_unit( &smspec_node )); { const char * wgname = DUMMY_WELL; - if (smspec_node_get_wgname( smspec_node )) - wgname = smspec_node_get_wgname( smspec_node ); + if (smspec_node_get_wgname( &smspec_node )) + wgname = smspec_node_get_wgname( &smspec_node ); ecl_kw_iset_string_ptr( wgnames_kw , i , wgname); } } if (nums_kw != NULL) - ecl_kw_iset_int( nums_kw , i , smspec_node_get_num( smspec_node )); + ecl_kw_iset_int( nums_kw , i , smspec_node.get_num()); } ecl_kw_fwrite( keywords_kw , fortio ); ecl_kw_fwrite( wgnames_kw , fortio ); @@ -512,7 +537,7 @@ static ecl_smspec_type * ecl_smspec_alloc_writer__( const char * key_join_string */ if (restart_case) { if (strlen(restart_case) <= (SUMMARY_RESTART_SIZE * ECL_STRING8_LENGTH)) { - ecl_smspec->restart_case = util_alloc_string_copy( restart_case ); + ecl_smspec->restart_case = restart_case; ecl_smspec->restart_step = restart_step; } } @@ -522,33 +547,16 @@ static ecl_smspec_type * ecl_smspec_alloc_writer__( const char * key_join_string ecl_smspec->sim_start_time = sim_start; { - smspec_node_type * time_node; - if (time_in_days) { - time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , - NULL , - "TIME" , - "DAYS" , - key_join_string , - ecl_smspec->grid_dims , - 0 , - -1 , - 0 ); - ecl_smspec->time_seconds = 3600 * 24; - } else { - time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , - NULL , - "TIME" , - "HOURS" , - key_join_string , - ecl_smspec->grid_dims , - 0 , - -1 , - 0 ); - ecl_smspec->time_seconds = 3600; - } + const ecl::smspec_node * time_node; - ecl_smspec_add_node( ecl_smspec , time_node ); - ecl_smspec->time_index = smspec_node_get_params_index( time_node ); + if (time_in_days) { + ecl_smspec->time_seconds = 3600 * 24; + time_node = ecl_smspec_add_node(ecl_smspec, "TIME", "DAYS", 0); + } else { + ecl_smspec->time_seconds = 3600; + time_node = ecl_smspec_add_node(ecl_smspec, "TIME", "HOURS", 0); + } + ecl_smspec->time_index = time_node->get_params_index(); } return ecl_smspec; } @@ -564,131 +572,8 @@ ecl_smspec_type * ecl_smspec_alloc_writer(const char * key_join_string, time_t s UTIL_SAFE_CAST_FUNCTION( ecl_smspec , ECL_SMSPEC_ID ) - -/** - Goes through the special_vars static table to check if @var is one - the special variables which does not follow normal naming - convention. If the test eavulates to true the function will return - ECL_SMSPEC_MISC_VAR, otherwise the function will return - ECL_SMSPEC_INVALID_VAR and the variable type will be determined - from the var name according to standard naming conventions. - - It is important that this function is called before the standard - method. -*/ - -static ecl_smspec_var_type ecl_smspec_identify_special_var( const char * var ) { - ecl_smspec_var_type var_type = ECL_SMSPEC_INVALID_VAR; - - int num_special = sizeof( special_vars ) / sizeof( special_vars[0] ); - int i; - for (i=0; i < num_special; i++) { - if (strcmp( var , special_vars[i]) == 0) { - var_type = ECL_SMSPEC_MISC_VAR; - break; - } - } - - return var_type; -} - - -/* - See table 3.4 in the ECLIPSE file format reference manual. - - Observe that the combined ecl_sum style keys like e.g. WWCT:OP1 - should be formatted with the keyword first, so that this function - will identify both 'WWCT' and 'WWCT:OP_1' as a ECL_SMSPEC_WELL_VAR - instance. -*/ - - ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) { - ecl_smspec_var_type var_type = ecl_smspec_identify_special_var( var ); - if (var_type == ECL_SMSPEC_INVALID_VAR) { - switch(var[0]) { - case('A'): - var_type = ECL_SMSPEC_AQUIFER_VAR; - break; - case('B'): - var_type = ECL_SMSPEC_BLOCK_VAR; - break; - case('C'): - var_type = ECL_SMSPEC_COMPLETION_VAR; - break; - case('F'): - var_type = ECL_SMSPEC_FIELD_VAR; - break; - case('G'): - var_type = ECL_SMSPEC_GROUP_VAR; - break; - case('L'): - switch(var[1]) { - case('B'): - var_type = ECL_SMSPEC_LOCAL_BLOCK_VAR; - break; - case('C'): - var_type = ECL_SMSPEC_LOCAL_COMPLETION_VAR; - break; - case('W'): - var_type = ECL_SMSPEC_LOCAL_WELL_VAR; - break; - default: - /* - The documentation explicitly mentions keywords starting with - LB, LC and LW as special types, but keywords starting with - L[^BCW] are also valid. These come in the misceallaneous - category; at least the LLINEAR keyword is an example of such - a keyword. - */ - var_type = ECL_SMSPEC_MISC_VAR; - } - break; - case('N'): - var_type = ECL_SMSPEC_NETWORK_VAR; - break; - case('R'): - { - /* - The distinction between region-to-region variables and plain - region variables is less than clear: The current - interpretation is that the cases: - - 1. Any variable matching: - - a) Starts with 'R' - b) Has 'F' as the third character - - 2. The variable "RNLF" - - Get variable type ECL_SMSPEC_REGION_2_REGION_VAR. The rest - get the type ECL_SMSPEC_REGION_VAR. - */ - - if (util_string_equal( var , "RNLF")) - var_type = ECL_SMSPEC_REGION_2_REGION_VAR; - else if (var[2] == 'F') - var_type = ECL_SMSPEC_REGION_2_REGION_VAR; - else - var_type = ECL_SMSPEC_REGION_VAR; - - } - break; - case('S'): - var_type = ECL_SMSPEC_SEGMENT_VAR; - break; - case('W'): - var_type = ECL_SMSPEC_WELL_VAR; - break; - default: - /* - It is unfortunately impossible to recognize an error situation - - the rest just goes in "other" variables. - */ - var_type = ECL_SMSPEC_MISC_VAR; - } - } - return var_type; + return ecl::smspec_node::identify_var_type(var); } @@ -789,23 +674,23 @@ static int ecl_smspec_get_global_grid_index(const ecl_smspec_type * smspec , int defined through the format strings used in this function. */ -static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , smspec_node_type * smspec_node ) { +static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , const ecl::smspec_node& smspec_node ) { /* Insert the default general mapping. */ { - const char * gen_key1 = smspec_node_get_gen_key1( smspec_node ); - if (gen_key1 != NULL) - hash_insert_ref(smspec->gen_var_index , gen_key1 , smspec_node); + const char * gen_key1 = smspec_node.get_gen_key1(); + if (gen_key1) + smspec->gen_var_index[gen_key1] = &smspec_node; } /* Insert the (optional) extra mapping for block related variables and region_2_region variables: */ { - const char * gen_key2 = smspec_node_get_gen_key2( smspec_node ); - if (gen_key2 != NULL) - hash_insert_ref(smspec->gen_var_index , gen_key2 , smspec_node); + const char * gen_key2 = smspec_node.get_gen_key2(); + if (gen_key2) + smspec->gen_var_index[gen_key2] = &smspec_node; } } -static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) { +static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , const ecl::smspec_node& smspec_node) { /** This large switch is for installing keys which have custom lookup paths, in addition to the lookup based on general keys. Examples @@ -814,85 +699,35 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp ecl_smspec_get_well_var_index( smspec , well_name , var ); */ - const char * well = smspec_node_get_wgname( smspec_node ); + const char * well = smspec_node_get_wgname( &smspec_node ); const char * group = well; - const int num = smspec_node_get_num(smspec_node); - const char * keyword = smspec_node_get_keyword(smspec_node); - ecl_smspec_var_type var_type = smspec_node_get_var_type( smspec_node ); + const int num = smspec_node_get_num(&smspec_node); + const char * keyword = smspec_node_get_keyword(&smspec_node); + ecl_smspec_var_type var_type = smspec_node_get_var_type(&smspec_node ); switch(var_type) { case(ECL_SMSPEC_COMPLETION_VAR): - if (well) - { - /* Three level indexing: variable -> well -> string(cell_nr)*/ - if (!hash_has_key(ecl_smspec->well_completion_var_index , well)) - hash_insert_hash_owned_ref(ecl_smspec->well_completion_var_index , well , hash_alloc() , hash_free__); - { - hash_type * cell_hash = (hash_type*)hash_get(ecl_smspec->well_completion_var_index , well); - char cell_str[16]; - sprintf(cell_str , "%d" , num); - if (!hash_has_key(cell_hash , cell_str)) - hash_insert_hash_owned_ref(cell_hash , cell_str , hash_alloc() , hash_free__); - { - hash_type * var_hash = (hash_type*)hash_get(cell_hash , cell_str); - hash_insert_ref(var_hash , keyword , smspec_node ); - } - } - } + ecl_smspec->well_completion_var_index[well][num][keyword] = &smspec_node; break; case(ECL_SMSPEC_FIELD_VAR): - /* - Field variable - */ - hash_insert_ref( ecl_smspec->field_var_index , keyword , smspec_node ); + ecl_smspec->field_var_index[keyword] = &smspec_node; break; case(ECL_SMSPEC_GROUP_VAR): - if (group) - { - if (!hash_has_key(ecl_smspec->group_var_index , group)) - hash_insert_hash_owned_ref(ecl_smspec->group_var_index , group, hash_alloc() , hash_free__); - { - hash_type * var_hash = (hash_type*)hash_get(ecl_smspec->group_var_index , group); - hash_insert_ref(var_hash , keyword , smspec_node ); - } - } + ecl_smspec->group_var_index[group][keyword] = &smspec_node; break; case(ECL_SMSPEC_REGION_VAR): - if (!hash_has_key(ecl_smspec->region_var_index , keyword)) - hash_insert_hash_owned_ref( ecl_smspec->region_var_index , keyword , hash_alloc() , hash_free__); - { - hash_type * var_hash = (hash_type*)hash_get(ecl_smspec->region_var_index , keyword); - char num_str[16]; - sprintf( num_str , "%d" , num); - hash_insert_ref(var_hash , num_str , smspec_node); - } + ecl_smspec->region_var_index[num][keyword] = &smspec_node; ecl_smspec->num_regions = util_int_max(ecl_smspec->num_regions , num); break; case (ECL_SMSPEC_WELL_VAR): - if (well) - { - if (!hash_has_key(ecl_smspec->well_var_index , well)) - hash_insert_hash_owned_ref(ecl_smspec->well_var_index , well , hash_alloc() , hash_free__); - { - hash_type * var_hash = (hash_type*)hash_get(ecl_smspec->well_var_index , well); - hash_insert_ref(var_hash , keyword , smspec_node ); - } - } + ecl_smspec->well_var_index[well][keyword] = &smspec_node; break; case(ECL_SMSPEC_MISC_VAR): /* Misc variable - i.e. date or CPU time ... */ - hash_insert_ref(ecl_smspec->misc_var_index , keyword , smspec_node ); + ecl_smspec->misc_var_index[keyword] = &smspec_node; break; case(ECL_SMSPEC_BLOCK_VAR): - /* A block variable */ - if (!hash_has_key(ecl_smspec->block_var_index , keyword)) - hash_insert_hash_owned_ref(ecl_smspec->block_var_index , keyword , hash_alloc() , hash_free__); - { - hash_type * block_hash = (hash_type*)hash_get(ecl_smspec->block_var_index , keyword); - char block_nr[16]; - sprintf( block_nr , "%d" , num ); - hash_insert_ref(block_hash , block_nr , smspec_node); - } + ecl_smspec->block_var_index[num][keyword] = &smspec_node; break; /** The variables below are ONLY accesable through the gen_key @@ -913,9 +748,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp case(ECL_SMSPEC_AQUIFER_VAR): break; default: - smspec_node_fprintf(smspec_node, stderr); - util_abort("%: Internal error - should never be here ?? \n",__func__); - break; + throw std::invalid_argument("Internal error - should not be here \n"); } } @@ -1006,14 +839,14 @@ 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) { - if (vector_get_size( self->smspec_nodes ) != vector_get_size( other->smspec_nodes)) + if (self->smspec_nodes.size() != other->smspec_nodes.size()) return false; - for (int i=0; i < vector_get_size( self->smspec_nodes ); i++) { - const smspec_node_type * node1 = (const smspec_node_type*)vector_iget_const(self->smspec_nodes, i); - const smspec_node_type * node2 = (const smspec_node_type*)vector_iget_const(other->smspec_nodes, i); + for (size_t i=0; i < self->smspec_nodes.size(); i++) { + const ecl::smspec_node* node1 = self->smspec_nodes[i].get(); + const ecl::smspec_node* node2 = other->smspec_nodes[i].get(); - if (!smspec_node_equal(node1, node2)) + if (node1->cmp(*node2) != 0) return false; } @@ -1035,7 +868,6 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi restart_base = util_alloc_strip_copy( tmp_base ); if (strlen(restart_base)) { /* We ignore the empty ones. */ - char * path; char * smspec_header; /* @@ -1050,6 +882,7 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi This code block will translate '/' -> '\' in the restart keyword which is read from the summary file. */ + #ifdef ERT_WINDOWS for (int i=0; i < strlen(restart_base); i++) { if (restart_base[i] == UTIL_POSIX_PATH_SEP_CHAR) @@ -1057,20 +890,22 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi } #endif - util_alloc_file_components( ecl_smspec->header_file , &path , NULL , NULL ); - smspec_header = ecl_util_alloc_exfilename( path , restart_base , ECL_SUMMARY_HEADER_FILE , ecl_smspec->formatted , 0); - if (!util_same_file(smspec_header , ecl_smspec->header_file)) /* Restart from the current case is ignored. */ { - if (util_is_abs_path(restart_base)) - ecl_smspec->restart_case = util_alloc_string_copy( restart_base ); - else { - char * tmp_path = util_alloc_filename( path , restart_base , NULL ); - ecl_smspec->restart_case = util_alloc_abs_path(tmp_path); - free( tmp_path ); + std::string path = ecl::util::path::dirname( ecl_smspec->header_file ); + smspec_header = ecl_util_alloc_exfilename( path.c_str() , restart_base , ECL_SUMMARY_HEADER_FILE , ecl_smspec->formatted , 0); + if (smspec_header) { + if (!util_same_file(smspec_header , ecl_smspec->header_file.c_str())) /* Restart from the current case is ignored. */ { + if (util_is_abs_path(restart_base)) + ecl_smspec->restart_case = restart_base; + else { + char * tmp_path = util_alloc_filename( path.c_str() , restart_base , NULL ); + char * abs_path = util_alloc_abs_path(tmp_path); + ecl_smspec->restart_case = abs_path; + free( abs_path ); + free( tmp_path ); + } } + free( smspec_header ); } - - free( path ); - free( smspec_header ); } free( restart_base ); } @@ -1078,62 +913,139 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi -void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) { - ecl_smspec_install_gen_keys( ecl_smspec , smspec_node ); - ecl_smspec_install_special_keys( ecl_smspec , smspec_node ); - if (smspec_node_need_nums( smspec_node )) + + + + +static const ecl::smspec_node * ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, std::unique_ptr smspec_node){ + int params_index = smspec_node->get_params_index(); + + /* This indexing must be used when writing. */ + ecl_smspec->index_map.push_back(params_index); + ecl_smspec->params_default.resize( params_index+1, PARAMS_GLOBAL_DEFAULT ); + ecl_smspec->params_default[params_index] = smspec_node->get_default(); + ecl_smspec->inv_index_map.insert( std::make_pair(params_index, ecl_smspec->smspec_nodes.size())); + + ecl_smspec_install_gen_keys( ecl_smspec, *smspec_node.get() ); + ecl_smspec_install_special_keys( ecl_smspec, *smspec_node.get() ); + + if (smspec_node->need_nums()) ecl_smspec->need_nums = true; + + ecl_smspec->smspec_nodes.push_back(std::move(smspec_node)); + + if (params_index > ecl_smspec->params_size) + ecl_smspec->params_size = params_index + 1; + + if (static_cast(ecl_smspec->smspec_nodes.size()) > ecl_smspec->params_size) + ecl_smspec->params_size = ecl_smspec->smspec_nodes.size(); + + const auto& node = ecl_smspec->smspec_nodes.back(); + return node.get(); } -static void ecl_smspec_set_params_size( ecl_smspec_type * ecl_smspec , int params_size) { - ecl_smspec->params_size = params_size; - float_vector_iset( ecl_smspec->params_default , ecl_smspec->params_size - 1 , PARAMS_GLOBAL_DEFAULT); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, int num, const char * unit, float default_value) { + int params_index = ecl_smspec->smspec_nodes.size(); + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + num, + unit, + ecl_smspec->grid_dims, + default_value, + ecl_smspec->key_join_string.c_str()))); +} + +//copy given node with a new index +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const ecl::smspec_node& node) { + int params_index = ecl_smspec->smspec_nodes.size(); + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(node, params_index))); +} + + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, const char * unit, float default_value) { + int params_index = ecl_smspec->smspec_nodes.size(); + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + unit, + default_value))); +} + + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, const char * wgname, const char * unit, float default_value) { + int params_index = ecl_smspec->smspec_nodes.size(); + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + wgname, + unit, + default_value, + ecl_smspec->key_join_string.c_str()))); +} + + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, + const char * keyword, + const char * wgname, + int num, + const char * unit, + float default_value) +{ + int params_index = ecl_smspec->smspec_nodes.size(); + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + wgname, + num, + unit, + ecl_smspec->grid_dims, + default_value, + ecl_smspec->key_join_string.c_str()))); +} + + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, + int params_index, + const char * keyword, + const char * wgname, + int num, + const char * unit, + float default_value) +{ + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + wgname, + num, + unit, + ecl_smspec->grid_dims, + default_value, + ecl_smspec->key_join_string.c_str()))); +} + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, + int params_index, + const char * keyword, + const char * wgname, + int num, + const char * unit, + const char * lgr, + int lgr_i, int lgr_j, int lgr_k, + float default_value) +{ + return ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + keyword, + wgname, + unit, + lgr, + lgr_i, lgr_j, lgr_k, + default_value, + ecl_smspec->key_join_string.c_str()))); } -void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){ - int internal_index = vector_get_size( ecl_smspec->smspec_nodes ); - /* This IF test should only apply in write_mode. */ - if (smspec_node_get_params_index( smspec_node ) < 0) { - if (!ecl_smspec->write_mode) - util_abort("%s: internal error \n",__func__); - smspec_node_set_params_index( smspec_node , internal_index); - - if (internal_index >= ecl_smspec->params_size) - ecl_smspec_set_params_size( ecl_smspec , internal_index + 1); - } - vector_append_owned_ref( ecl_smspec->smspec_nodes , smspec_node , smspec_node_free__ ); - - { - int params_index = smspec_node_get_params_index( smspec_node ); - - /* This indexing must be used when writing. */ - int_vector_iset( ecl_smspec->index_map , internal_index , params_index); - - float_vector_iset( ecl_smspec->params_default , params_index , smspec_node_get_default(smspec_node) ); - } -} - - -void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node ) { - ecl_smspec_insert_node( ecl_smspec , smspec_node ); - ecl_smspec_index_node( ecl_smspec , smspec_node ); -} - - - -void ecl_smspec_init_var( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num, const char * unit ) { - smspec_node_init( smspec_node , ecl_smspec_identify_var_type( keyword ) , wgname , keyword , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num ); - ecl_smspec_index_node( ecl_smspec , smspec_node ); -} - - -const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ) { - return smspec->index_map; +const int * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ) { + return smspec->index_map.data(); } /** @@ -1178,6 +1090,7 @@ static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h int params_index; ecl_smspec->num_regions = 0; + ecl_smspec->params_size = ecl_kw_get_size(keywords); if (startdat == NULL) util_abort("%s: could not locate STARTDAT keyword in header - aborting \n",__func__); @@ -1214,7 +1127,6 @@ static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h ecl_smspec->grid_dims[1] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NY_INDEX ); ecl_smspec->grid_dims[2] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NZ_INDEX ); ecl_smspec->restart_step = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_RESTART_STEP_INDEX); - ecl_smspec_set_params_size( ecl_smspec , ecl_kw_get_size(keywords)); ecl_util_get_file_type( header_file , &ecl_smspec->formatted , NULL ); @@ -1225,31 +1137,51 @@ static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h char * well = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr(wells , params_index)); char * kw = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr(keywords , params_index)); char * unit = (char*)util_alloc_strip_copy((const char*)ecl_kw_iget_ptr(units , params_index)); - char * lgr_name = NULL; - smspec_node_type * smspec_node; - ecl_smspec_var_type var_type = ecl_smspec_identify_var_type( kw ); + ecl_smspec_var_type var_type; if (nums != NULL) num = ecl_kw_iget_int(nums , params_index); + var_type = ecl::smspec_node::valid_type(kw, well, num); + if (var_type == ECL_SMSPEC_INVALID_VAR) { + free( kw ); + free( well ); + free( unit ); + continue; + } + if (ecl_smspec_lgr_var_type( var_type )) { int lgr_i = ecl_kw_iget_int( numlx , params_index ); int lgr_j = ecl_kw_iget_int( numly , params_index ); int lgr_k = ecl_kw_iget_int( numlz , params_index ); - lgr_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr( lgrs , params_index )); - smspec_node = smspec_node_alloc_lgr( var_type , well , kw , unit , lgr_name , ecl_smspec->key_join_string , lgr_i , lgr_j , lgr_k , params_index, default_value); - } else - smspec_node = smspec_node_alloc( var_type , well , kw , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num , params_index , default_value); + char * lgr_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr( lgrs , params_index )); - if (smspec_node) - ecl_smspec_add_node( ecl_smspec , smspec_node ); + ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + kw, + well, + unit, + lgr_name, + lgr_i, lgr_j, lgr_k, + default_value, + ecl_smspec->key_join_string.c_str()))); + free(lgr_name); + } else + ecl_smspec_insert_node(ecl_smspec, std::unique_ptr( new ecl::smspec_node(params_index, + kw, + well, + num, + unit, + ecl_smspec->grid_dims, + default_value, + ecl_smspec->key_join_string.c_str()))); free( kw ); free( well ); free( unit ); - free( lgr_name ); } } - ecl_smspec->header_file = util_alloc_realpath( header_file ); + char * header_str = util_alloc_realpath( header_file ); + ecl_smspec->header_file = header_str; + free(header_str); if (include_restart) ecl_smspec_load_restart( ecl_smspec , header ); @@ -1274,10 +1206,10 @@ ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * k if (ecl_smspec_fread_header(ecl_smspec , header_file , include_restart)) { - if (hash_has_key( ecl_smspec->misc_var_index , "TIME")) { - const smspec_node_type * time_node = (const smspec_node_type*)hash_get(ecl_smspec->misc_var_index , "TIME"); - const char * time_unit = smspec_node_get_unit( time_node ); - ecl_smspec->time_index = smspec_node_get_params_index( time_node ); + const ecl::smspec_node * time_node = ecl_smspec_get_var_node(ecl_smspec->misc_var_index, "TIME"); + if (time_node) { + const char * time_unit = time_node->get_unit(); + ecl_smspec->time_index = time_node->get_params_index(); if (util_string_equal( time_unit , "DAYS")) ecl_smspec->time_seconds = 3600 * 24; @@ -1285,12 +1217,14 @@ ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * k ecl_smspec->time_seconds = 3600; else util_abort("%s: time_unit:%s not recognized \n",__func__ , time_unit); + } - if (hash_has_key(ecl_smspec->misc_var_index , "DAY")) { - ecl_smspec->day_index = smspec_node_get_params_index( (const smspec_node_type*)hash_get(ecl_smspec->misc_var_index , "DAY") ); - ecl_smspec->month_index = smspec_node_get_params_index( (const smspec_node_type*)hash_get(ecl_smspec->misc_var_index , "MONTH") ); - ecl_smspec->year_index = smspec_node_get_params_index( (const smspec_node_type*)hash_get(ecl_smspec->misc_var_index , "YEAR") ); + const ecl::smspec_node * day_node = ecl_smspec_get_var_node(ecl_smspec->misc_var_index, "DAY"); + if (day_node != NULL) { + ecl_smspec->day_index = smspec_node_get_params_index( day_node ); + ecl_smspec->month_index = smspec_node_get_params_index( &ecl_smspec->misc_var_index["MONTH"] ); + ecl_smspec->year_index = smspec_node_get_params_index( &ecl_smspec->misc_var_index["YEAR"] ); } if ((ecl_smspec->time_index == -1) && ( ecl_smspec->day_index == -1)) { @@ -1313,13 +1247,13 @@ ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * k int ecl_smspec_get_num_groups(const ecl_smspec_type * ecl_smspec) { - return hash_get_size(ecl_smspec->group_var_index); + return ecl_smspec->group_var_index.size(); } -char ** ecl_smspec_alloc_group_names(const ecl_smspec_type * ecl_smspec) { +/*char ** ecl_smspec_alloc_group_names(const ecl_smspec_type * ecl_smspec) { return hash_alloc_keylist(ecl_smspec->group_var_index); -} +}*/ int ecl_smspec_get_num_regions(const ecl_smspec_type * ecl_smspec) { return ecl_smspec->num_regions; @@ -1353,15 +1287,15 @@ int ecl_smspec_get_num_regions(const ecl_smspec_type * ecl_smspec) { /*****************************************************************/ -#define NODE_RETURN_INDEX(node) \ - if (node == NULL) \ +#define NODE_RETURN_INDEX(node_ptr) \ + if (!node_ptr) \ return -1; \ - else \ - return smspec_node_get_params_index( node ); + else \ + return smspec_node_get_params_index( node_ptr ); -#define NODE_RETURN_EXISTS(node) \ - if (node == NULL) \ +#define NODE_RETURN_EXISTS(node_ptr) \ + if (!node_ptr) \ return false; \ else \ return true; @@ -1371,26 +1305,24 @@ int ecl_smspec_get_num_regions(const ecl_smspec_type * ecl_smspec) { /******************************************************************/ /* Well variables */ -const smspec_node_type * ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var) { - const smspec_node_type * node = NULL; - if (hash_has_key( smspec->well_var_index , well)) { - hash_type * var_hash = (hash_type*)hash_get(smspec->well_var_index , well); - if (hash_has_key(var_hash , var)) - node = (const smspec_node_type*)hash_get(var_hash , var); - } - return node; +const ecl::smspec_node& ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var) { + const auto node_ptr = ecl_smspec_get_str_key_var_node(smspec->well_var_index, well, var); + if (!node_ptr) + throw std::out_of_range("The well: " + std::string(well) + " variable: " + std::string(var) + " combination does not exist."); + + return *node_ptr; } int ecl_smspec_get_well_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var) { - const smspec_node_type * node = ecl_smspec_get_well_var_node( ecl_smspec , well , var ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_str_key_var_node(ecl_smspec->well_var_index, well, var); + NODE_RETURN_INDEX(node_ptr); } bool ecl_smspec_has_well_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var) { - const smspec_node_type * node = ecl_smspec_get_well_var_node(ecl_smspec , well ,var); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_str_key_var_node(ecl_smspec->well_var_index, well, var); + NODE_RETURN_EXISTS(node_ptr); } @@ -1398,52 +1330,50 @@ bool ecl_smspec_has_well_var(const ecl_smspec_type * ecl_smspec , const char * w /*****************************************************************/ /* Group variables */ -const smspec_node_type * ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var) { - const smspec_node_type * node = NULL; - if (hash_has_key(smspec->group_var_index , group)) { - hash_type * var_hash = (hash_type*)hash_get(smspec->group_var_index , group); - if (hash_has_key(var_hash , var)) - node = (const smspec_node_type*)hash_get(var_hash , var); - } - return node; +const ecl::smspec_node& ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var) { + const auto node_ptr = ecl_smspec_get_str_key_var_node(smspec->group_var_index, group, var); + if (!node_ptr) + throw std::out_of_range("The group: " + std::string(group) + " variable: " + std::string(var) + " combination does not exist."); + + return *node_ptr; } int ecl_smspec_get_group_var_params_index(const ecl_smspec_type * ecl_smspec , const char * group , const char *var) { - const smspec_node_type * node = ecl_smspec_get_group_var_node( ecl_smspec , group , var ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_str_key_var_node(ecl_smspec->group_var_index, group, var); + NODE_RETURN_INDEX(node_ptr); } bool ecl_smspec_has_group_var(const ecl_smspec_type * ecl_smspec , const char * group , const char *var) { - const smspec_node_type * node = ecl_smspec_get_group_var_node(ecl_smspec , group ,var); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_str_key_var_node(ecl_smspec->group_var_index, group, var); + NODE_RETURN_EXISTS(node_ptr); } /*****************************************************************/ /* Field variables */ -const smspec_node_type * ecl_smspec_get_field_var_node(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = NULL; - if (hash_has_key(ecl_smspec->field_var_index , var)) - node = (const smspec_node_type*)hash_get(ecl_smspec->field_var_index , var); +const ecl::smspec_node& ecl_smspec_get_field_var_node(const ecl_smspec_type * ecl_smspec , const char *var) { + const auto node_ptr = ecl_smspec_get_var_node( ecl_smspec->field_var_index, var); + if (!node_ptr) + throw std::out_of_range("The field variable: " + std::string(var) + " does not exist."); - return node; + return *node_ptr; } int ecl_smspec_get_field_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = ecl_smspec_get_field_var_node( ecl_smspec , var ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->field_var_index, var); + NODE_RETURN_INDEX(node_ptr); } bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = ecl_smspec_get_field_var_node( ecl_smspec , var ); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->field_var_index, var); + NODE_RETURN_EXISTS(node_ptr); } /*****************************************************************/ @@ -1457,54 +1387,40 @@ bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *v hash tables. */ -static const smspec_node_type * ecl_smspec_get_block_var_node_string(const ecl_smspec_type * ecl_smspec , const char * block_var , const char * block_str) { - const smspec_node_type * node = NULL; - if (hash_has_key(ecl_smspec->block_var_index , block_var)) { - hash_type * block_hash = (hash_type*)hash_get(ecl_smspec->block_var_index , block_var); - if (hash_has_key(block_hash , block_str)) - node = (const smspec_node_type*)hash_get(block_hash , block_str); - } +const ecl::smspec_node& ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) { + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->block_var_index, block_nr, block_var); + if (!node_ptr) + throw std::out_of_range("No such block variable"); - return node; + return *node_ptr; } -const smspec_node_type * ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) { - const smspec_node_type * node; - char * block_str = util_alloc_sprintf("%d" , block_nr); - node = ecl_smspec_get_block_var_node_string(ecl_smspec , block_var , block_str); - free( block_str ); - return node; -} - - -const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) { +const ecl::smspec_node& ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) { return ecl_smspec_get_block_var_node( ecl_smspec , block_var , ecl_smspec_get_global_grid_index( ecl_smspec , i,j,k) ); } bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) { - const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr ); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->block_var_index, block_nr, block_var); + NODE_RETURN_EXISTS(node_ptr); } bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) { - const smspec_node_type * node = ecl_smspec_get_block_var_node_ijk( ecl_smspec , block_var , i,j,k ); - NODE_RETURN_EXISTS(node); + return ecl_smspec_has_block_var(ecl_smspec, block_var, ecl_smspec_get_global_grid_index(ecl_smspec, i, j, k)); } int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) { - const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->block_var_index, block_nr, block_var); + NODE_RETURN_INDEX(node_ptr); } int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) { - const smspec_node_type * node = ecl_smspec_get_block_var_node_ijk( ecl_smspec , block_var , i,j,k ); - NODE_RETURN_INDEX(node); + return ecl_smspec_get_block_var_params_index(ecl_smspec, block_var, ecl_smspec_get_global_grid_index(ecl_smspec, i, j, k)); } @@ -1516,53 +1432,46 @@ int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec -const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr) { - const smspec_node_type * node = NULL; +const ecl::smspec_node& ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr) { + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->region_var_index, region_nr, region_var); + if (!node_ptr) + throw std::out_of_range("No such block variable"); - if (hash_has_key(ecl_smspec->region_var_index , region_var)) { - char * nr_str = util_alloc_sprintf( "%d" , region_nr ); - hash_type * nr_hash = (hash_type*)hash_get(ecl_smspec->region_var_index , region_var); - if (hash_has_key( nr_hash , nr_str)) - node = (const smspec_node_type*)hash_get( nr_hash , nr_str ); - free( nr_str ); - } - - return node; + return *node_ptr; } bool ecl_smspec_has_region_var(const ecl_smspec_type * ecl_smspec , const char *region_var, int region_nr) { - const smspec_node_type * node = ecl_smspec_get_region_var_node( ecl_smspec , region_var , region_nr ); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->region_var_index, region_nr, region_var); + NODE_RETURN_EXISTS(node_ptr); } int ecl_smspec_get_region_var_params_index(const ecl_smspec_type * ecl_smspec , const char *region_var, int region_nr) { - const smspec_node_type * node = ecl_smspec_get_region_var_node( ecl_smspec , region_var , region_nr ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_int_key_var_node(ecl_smspec->region_var_index, region_nr, region_var); + NODE_RETURN_INDEX(node_ptr); } /*****************************************************************/ /* Misc variables */ -const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = NULL; +const ecl::smspec_node& ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var) { + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->misc_var_index, var); + if (!node_ptr) + throw std::out_of_range("No such misc variable"); - if (hash_has_key(ecl_smspec->misc_var_index , var)) - node = (const smspec_node_type*)hash_get(ecl_smspec->misc_var_index , var); - - return node; + return *node_ptr; } bool ecl_smspec_has_misc_var(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = ecl_smspec_get_misc_var_node( ecl_smspec , var ); - NODE_RETURN_EXISTS(node); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->misc_var_index , var ); + NODE_RETURN_EXISTS(node_ptr); } int ecl_smspec_get_misc_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var) { - const smspec_node_type * node = ecl_smspec_get_misc_var_node( ecl_smspec , var ); - NODE_RETURN_INDEX(node); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->misc_var_index , var ); + NODE_RETURN_INDEX(node_ptr); } @@ -1570,33 +1479,33 @@ int ecl_smspec_get_misc_var_params_index(const ecl_smspec_type * ecl_smspec , co /* Well completion - not fully implemented ?? */ -const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr) { - const smspec_node_type * node = NULL; +const ecl::smspec_node * ecl_smspec_get_well_completion_var_node__(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr) { + const auto well_iter = ecl_smspec->well_completion_var_index.find(well); + if (well_iter == ecl_smspec->well_completion_var_index.end()) + return nullptr; - char * cell_str = util_alloc_sprintf("%d" , cell_nr); - if (hash_has_key(ecl_smspec->well_completion_var_index , well)) { - hash_type * cell_hash = (hash_type*)hash_get(ecl_smspec->well_completion_var_index , well); + const auto& num_map = well_iter->second; + return ecl_smspec_get_int_key_var_node( num_map, cell_nr, var ); +} - if (hash_has_key(cell_hash , cell_str)) { - hash_type * var_hash = (hash_type*)hash_get(cell_hash , cell_str); - if (hash_has_key(var_hash , var)) - node = (const smspec_node_type*)hash_get( var_hash , var); - } - } - free(cell_str); - return node; +const ecl::smspec_node& ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr) { + const auto node_ptr = ecl_smspec_get_well_completion_var_node__(ecl_smspec, well, var, cell_nr); + if (!node_ptr) + throw std::out_of_range("No such well/var/completion"); + + return *node_ptr; } bool ecl_smspec_has_well_completion_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr) { - const smspec_node_type * node = ecl_smspec_get_well_completion_var_node( ecl_smspec , well , var , cell_nr ); - NODE_RETURN_EXISTS( node ); + const auto node_ptr = ecl_smspec_get_well_completion_var_node__( ecl_smspec , well , var , cell_nr ); + NODE_RETURN_EXISTS( node_ptr ); } int ecl_smspec_get_well_completion_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr) { - const smspec_node_type * node = ecl_smspec_get_well_completion_var_node( ecl_smspec , well , var , cell_nr ); - NODE_RETURN_INDEX( node ); + const auto node_ptr = ecl_smspec_get_well_completion_var_node__( ecl_smspec , well , var , cell_nr ); + NODE_RETURN_INDEX( node_ptr ); } @@ -1610,31 +1519,31 @@ int ecl_smspec_get_well_completion_var_params_index(const ecl_smspec_type * ecl -const smspec_node_type * ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ) { - if (hash_has_key( smspec->gen_var_index , lookup_kw )) { - const smspec_node_type * smspec_node = (const smspec_node_type*)hash_get( smspec->gen_var_index , lookup_kw ); - return smspec_node; - } else - return NULL; +const ecl::smspec_node& ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ) { + const auto node_ptr = ecl_smspec_get_var_node(smspec->gen_var_index, lookup_kw); + if (!node_ptr) + throw std::out_of_range("No such variable: " + std::string(lookup_kw)); + + return *node_ptr; } int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec , const char * lookup_kw) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_smspec , lookup_kw ); - NODE_RETURN_INDEX( node ); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->gen_var_index , lookup_kw ); + NODE_RETURN_INDEX( node_ptr ); } bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_smspec , lookup_kw ); - NODE_RETURN_EXISTS( node ); + const auto node_ptr = ecl_smspec_get_var_node(ecl_smspec->gen_var_index , lookup_kw ); + NODE_RETURN_EXISTS( node_ptr ); } /** DIES if the lookup_kw is not present. */ const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec , const char * lookup_kw) { - const smspec_node_type * smspec_node = (const smspec_node_type*)hash_get( ecl_smspec->gen_var_index , lookup_kw ); - return smspec_node_get_unit( smspec_node ); + const auto smspec_node = ecl_smspec_get_general_var_node(ecl_smspec, lookup_kw); + return smspec_node_get_unit( &smspec_node ); } @@ -1645,22 +1554,22 @@ const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec */ //const char * ecl_smspec_iget_unit( const ecl_smspec_type * smspec , int node_index ) { -// const smspec_node_type * smspec_node = ecl_smspec_iget_node( smspec , node_index ); +// const ecl::smspec_node * smspec_node = ecl_smspec_iget_node( smspec , node_index ); // return smspec_node_get_unit( smspec_node ); //} // //int ecl_smspec_iget_num( const ecl_smspec_type * smspec , int node_index ) { -// const smspec_node_type * smspec_node = ecl_smspec_iget_node( smspec , node_index ); +// const ecl::smspec_node * smspec_node = ecl_smspec_iget_node( smspec , node_index ); // return smspec_node_get_num( smspec_node ); //} // //const char * ecl_smspec_iget_wgname( const ecl_smspec_type * smspec , int node_index ) { -// const smspec_node_type * smspec_node = ecl_smspec_iget_node( smspec , node_index ); +// const ecl::smspec_node * smspec_node = ecl_smspec_iget_node( smspec , node_index ); // return smspec_node_get_wgname( smspec_node ); //} // //const char * ecl_smspec_iget_keyword( const ecl_smspec_type * smspec , int index ) { -// const smspec_node_type * smspec_node = ecl_smspec_iget_node( smspec , index ); +// const ecl::smspec_node * smspec_node = ecl_smspec_iget_node( smspec , index ); // return smspec_node_get_keyword( smspec_node ); //} @@ -1684,7 +1593,7 @@ bool ecl_smspec_get_formatted( const ecl_smspec_type * ecl_smspec) { } const char * ecl_smspec_get_header_file( const ecl_smspec_type * ecl_smspec ) { - return ecl_smspec->header_file; + return ecl_smspec->header_file.c_str(); } @@ -1701,31 +1610,18 @@ int ecl_smspec_get_first_step(const ecl_smspec_type * ecl_smspec) { const char * ecl_smspec_get_restart_case( const ecl_smspec_type * ecl_smspec) { - return ecl_smspec->restart_case; + if (ecl_smspec->restart_case.size() > 0) + return ecl_smspec->restart_case.c_str(); + else + return NULL; } - -const float_vector_type * ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ) { +const std::vector& ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ) { return ecl_smspec->params_default; } - - void ecl_smspec_free(ecl_smspec_type *ecl_smspec) { - hash_free(ecl_smspec->well_var_index); - hash_free(ecl_smspec->well_completion_var_index); - hash_free(ecl_smspec->group_var_index); - hash_free(ecl_smspec->field_var_index); - hash_free(ecl_smspec->region_var_index); - hash_free(ecl_smspec->misc_var_index); - hash_free(ecl_smspec->block_var_index); - hash_free(ecl_smspec->gen_var_index); - free( ecl_smspec->header_file ); - int_vector_free( ecl_smspec->index_map ); - float_vector_free( ecl_smspec->params_default ); - vector_free( ecl_smspec->smspec_nodes ); - free( ecl_smspec->restart_case ); - free( ecl_smspec ); + delete ecl_smspec; } @@ -1757,8 +1653,8 @@ int ecl_smspec_get_date_year_index( const ecl_smspec_type * smspec ) { bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char * gen_key) { - const smspec_node_type * smspec_node = (const smspec_node_type*)hash_get( smspec->gen_var_index , gen_key ); - return smspec_node_is_total( smspec_node ); + const ecl::smspec_node& smspec_node = ecl_smspec_get_general_var_node(smspec, gen_key); + return smspec_node_is_total( &smspec_node ); } @@ -1786,15 +1682,13 @@ bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char * void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys) { - hash_type * ex_keys = hash_alloc( ); - int i; - for (i=0; i < stringlist_get_size( keys ); i++) - hash_insert_int( ex_keys , stringlist_iget( keys , i ) , 1); + std::set ex_keys; + for (int i=0; i < stringlist_get_size( keys ); i++) + ex_keys.insert( stringlist_iget(keys, i)); { - hash_iter_type * iter = hash_iter_alloc( smspec->gen_var_index ); - while (!hash_iter_is_complete( iter )) { - const char * key = hash_iter_get_next_key( iter ); + for (const auto& pair : smspec->gen_var_index) { + const char * key = pair.first.c_str(); /* The TIME is typically special cased by output and will not @@ -1807,14 +1701,12 @@ void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec if ((pattern == NULL) || (util_fnmatch( pattern , key ) == 0)) { - if (!hash_has_key( ex_keys , key)) + if (ex_keys.find(key) == ex_keys.end()) stringlist_append_copy( keys , key ); } } - hash_iter_free( iter ); } - hash_free( ex_keys ); stringlist_sort( keys , (string_cmp_ftype *) util_strcmp_int ); } @@ -1833,7 +1725,7 @@ stringlist_type * ecl_smspec_alloc_matching_general_var_list(const ecl_smspec_ty const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec) { - return smspec->key_join_string; + return smspec->key_join_string.c_str(); } @@ -1850,24 +1742,25 @@ const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec) { i.e. standard shell wildcards. */ -stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , const char * pattern) { - stringlist_type * well_list = stringlist_alloc_new( ); - { - hash_iter_type * iter = hash_iter_alloc( smspec->well_var_index ); +static stringlist_type * ecl_smspec_alloc_map_list( const std::map& mp , const char * pattern) { + stringlist_type * map_list = stringlist_alloc_new( ); + + for (const auto& pair : mp) { + const char * map_name = pair.first.c_str(); + + if (pattern == NULL) + stringlist_append_copy( map_list , map_name ); + else if (util_fnmatch( pattern , map_name) == 0) + stringlist_append_copy( map_list , map_name ); - while (!hash_iter_is_complete( iter )) { - const char * well_name = hash_iter_get_next_key( iter ); - if (pattern == NULL) - stringlist_append_copy( well_list , well_name ); - else if (util_fnmatch( pattern , well_name) == 0) - stringlist_append_copy( well_list , well_name ); - } - hash_iter_free(iter); } - stringlist_sort( well_list , (string_cmp_ftype *) util_strcmp_int ); - return well_list; + stringlist_sort( map_list , (string_cmp_ftype *) util_strcmp_int ); + return map_list; } +stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , const char * pattern) { + return ecl_smspec_alloc_map_list( smspec->well_var_index, pattern ); +} /** Returns a stringlist instance with all the (valid) group names. It @@ -1876,21 +1769,7 @@ stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , c */ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec , const char * pattern) { - stringlist_type * group_list = stringlist_alloc_new( ); - { - hash_iter_type * iter = hash_iter_alloc( smspec->group_var_index ); - - while (!hash_iter_is_complete( iter )) { - const char * group_name = hash_iter_get_next_key( iter ); - if (pattern == NULL) - stringlist_append_copy( group_list , group_name ); - else if (util_fnmatch( pattern , group_name) == 0) - stringlist_append_copy( group_list , group_name ); - } - hash_iter_free(iter); - } - stringlist_sort( group_list , (string_cmp_ftype *) util_strcmp_int ); - return group_list; + return ecl_smspec_alloc_map_list( smspec->group_var_index, pattern ); } @@ -1902,18 +1781,15 @@ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec , */ stringlist_type * ecl_smspec_alloc_well_var_list( const ecl_smspec_type * smspec ) { - hash_iter_type * well_iter = hash_iter_alloc( smspec->well_var_index ); - hash_type * var_hash = (hash_type*)hash_iter_get_next_value( well_iter ); - hash_iter_free( well_iter ); - return hash_alloc_stringlist( var_hash ); + stringlist_type * stringlist = stringlist_alloc_new(); + for (const auto& pair : smspec->well_var_index) + stringlist_append_copy(stringlist, pair.first.c_str()); + + return stringlist; } -int ecl_smspec_get_params_size( const ecl_smspec_type * smspec ) { - return smspec->params_size; -} - const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ) { @@ -1926,19 +1802,19 @@ const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ) { /*****************************************************************/ char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname) { - return smspec_alloc_well_key( smspec->key_join_string , keyword , wgname ); + return smspec_alloc_well_key( smspec->key_join_string.c_str() , keyword , wgname ); } -void ecl_smspec_sort( ecl_smspec_type * smspec ) { - vector_sort( smspec->smspec_nodes , smspec_node_cmp__); +/*void ecl_smspec_sort( ecl_smspec_type * smspec ) { + std::sort(smspec->smspec_nodes.begin(), smspec->smspec_nodes.end(), smspec_node_lt); - for (int i=0; i < vector_get_size( smspec->smspec_nodes ); i++) { - smspec_node_type * node = (smspec_node_type*)vector_iget( smspec->smspec_nodes , i ); - smspec_node_set_params_index( node , i ); + for (int i=0; i < static_cast(smspec->smspec_nodes.size()); i++) { + ecl::smspec_node& node = *smspec->smspec_nodes[i].get(); + smspec_node_set_params_index( &node , i ); } - } +*/ ert_ecl_unit_enum ecl_smspec_get_unit_system(const ecl_smspec_type * smspec) { return smspec->unit_system; diff --git a/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp b/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp index 1e06968afd..faec3f3fc3 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_subsidence.c' is part of ERT - Ensemble based Reservoir Tool. @@ -75,6 +75,7 @@ struct ecl_subsidence_survey_struct { char * name; /* Name of the survey - arbitrary string. */ double * porv; /* Reference pore volume */ double * pressure; /* Pressure in each grid cell at survey time */ + double * dynamic_porevolume; /* Porevolume in each grid cell at survey time */ }; @@ -92,6 +93,7 @@ static ecl_subsidence_survey_type * ecl_subsidence_survey_alloc_empty(const ecl_ survey->porv = (double*) util_calloc( sub->grid_cache->size() , sizeof * survey->porv ); survey->pressure = (double*) util_calloc( sub->grid_cache->size() , sizeof * survey->pressure ); + survey->dynamic_porevolume = NULL; return survey; } @@ -111,9 +113,18 @@ static ecl_subsidence_survey_type * ecl_subsidence_survey_alloc_PRESSURE(ecl_sub ecl_kw_type * init_porv_kw = ecl_file_iget_named_kw( ecl_subsidence->init_file , PORV_KW , 0); /*Global indexing*/ ecl_kw_type * pressure_kw = ecl_file_view_iget_named_kw( restart_view , PRESSURE_KW , 0); /*Active indexing*/ + ecl_kw_type * rporv_kw = NULL; + if(ecl_file_view_has_kw(restart_view, RPORV_KW)) { + survey->dynamic_porevolume = (double*) util_calloc( ecl_subsidence->grid_cache->size() , sizeof * survey->dynamic_porevolume); + rporv_kw = ecl_file_view_iget_named_kw(restart_view, RPORV_KW, 0); + } + for (active_index = 0; active_index < size; active_index++){ survey->porv[ active_index ] = ecl_kw_iget_float( init_porv_kw , global_index[active_index] ); survey->pressure[ active_index ] = ecl_kw_iget_float( pressure_kw , active_index ); + + if(rporv_kw) + survey->dynamic_porevolume[ active_index ] = ecl_kw_iget_float(rporv_kw, active_index); } return survey; } @@ -126,6 +137,7 @@ static void ecl_subsidence_survey_free( ecl_subsidence_survey_type * subsidence_ free( subsidence_survey->name ); free( subsidence_survey->porv ); free( subsidence_survey->pressure ); + free( subsidence_survey->dynamic_porevolume ); free( subsidence_survey ); } @@ -193,6 +205,47 @@ static double ecl_subsidence_survey_eval_geertsma( const ecl_subsidence_survey_t } +static double ecl_subsidence_survey_eval_geertsma_rporv( const ecl_subsidence_survey_type * base_survey , + const ecl_subsidence_survey_type * monitor_survey, + ecl_region_type * region , + double utm_x , double utm_y , double depth, + double youngs_modulus, double poisson_ratio, double seabed) { + + const ecl::ecl_grid_cache& grid_cache = *(base_survey->grid_cache); + std::vector weight(grid_cache.size()); + + if(!base_survey->dynamic_porevolume) { + util_abort( + "%s: Keyword RPORV not defined in .UNRST file for %s. Please add RPORV keyword to output in RPTRST clause in .DATA file.\n", + __func__, base_survey->name); + } + + if(monitor_survey && !monitor_survey->dynamic_porevolume) { + util_abort( + "%s: Keyword RPORV not defined in .UNRST file for %s. Please add RPORV keyword to output in RPTRST clause in .DATA file.\n", + __func__, monitor_survey->name); + } + + for (size_t index = 0; index < weight.size(); ++index) { + if (monitor_survey) + weight[index] = (base_survey->dynamic_porevolume[index] - monitor_survey->dynamic_porevolume[index]) / (4*M_PI); + else + weight[index] = base_survey->dynamic_porevolume[index] / (4*M_PI); + } + + return ecl_grav_common_eval_geertsma( + grid_cache, + region, + base_survey->aquifer_cell, + weight.data(), + utm_x, + utm_y, + depth, + poisson_ratio, + seabed + ); +} + /*****************************************************************/ /** @@ -254,6 +307,14 @@ double ecl_subsidence_eval_geertsma( const ecl_subsidence_type * subsidence , co return ecl_subsidence_survey_eval_geertsma( base_survey , monitor_survey , region , utm_x , utm_y , depth , youngs_modulus, poisson_ratio, seabed); } +double ecl_subsidence_eval_geertsma_rporv( const ecl_subsidence_type * subsidence , const char * base, const char * monitor , ecl_region_type * region , + double utm_x, double utm_y , double depth, + double youngs_modulus, double poisson_ratio, double seabed) { + ecl_subsidence_survey_type * base_survey = ecl_subsidence_get_survey( subsidence , base ); + ecl_subsidence_survey_type * monitor_survey = ecl_subsidence_get_survey( subsidence , monitor ); + return ecl_subsidence_survey_eval_geertsma_rporv( base_survey , monitor_survey , region , utm_x , utm_y , depth , youngs_modulus, poisson_ratio, seabed); +} + void ecl_subsidence_free( ecl_subsidence_type * ecl_subsidence ) { delete ecl_subsidence->grid_cache; diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum.cpp index c5c27b58ee..a64e2e4bd8 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum.c' is part of ERT - Ensemble based Reservoir Tool. @@ -290,32 +290,16 @@ void ecl_sum_set_fmt_case( ecl_sum_type * ecl_sum , bool fmt_case ) { -smspec_node_type * ecl_sum_add_var( ecl_sum_type * ecl_sum , const char * keyword , const char * wgname , int num , const char * unit , float default_value) { +const ecl::smspec_node * ecl_sum_add_var( ecl_sum_type * ecl_sum , const char * keyword , const char * wgname , int num , const char * unit , float default_value) { if (ecl_sum_data_get_length(ecl_sum->data) > 0) throw std::invalid_argument("Can not interchange variable adding and timesteps.\n"); - - smspec_node_type * smspec_node = smspec_node_alloc( ecl_smspec_identify_var_type(keyword), - wgname, - keyword, - unit, - ecl_sum->key_join_string, - ecl_smspec_get_grid_dims(ecl_sum->smspec), - num, - -1, - default_value); - ecl_smspec_add_node(ecl_sum->smspec, smspec_node); - ecl_sum_data_reset_self_map( ecl_sum->data ); - return smspec_node; + return ecl_smspec_add_node( ecl_sum->smspec, keyword, wgname, num, unit, default_value); } -smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_node_type * node) { - return ecl_sum_add_var(ecl_sum, - smspec_node_get_keyword(node), - smspec_node_get_wgname(node), - smspec_node_get_num(node), - smspec_node_get_unit(node), - smspec_node_get_default(node)); + +const ecl::smspec_node * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const ecl::smspec_node * node) { + return ecl_smspec_add_node(ecl_sum->smspec, *node); } @@ -335,7 +319,8 @@ smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_ */ ecl_sum_tstep_type * ecl_sum_add_tstep( ecl_sum_type * ecl_sum , int report_step , double sim_seconds) { - return ecl_sum_data_add_new_tstep( ecl_sum->data , report_step , sim_seconds ); + ecl_sum_tstep_type * new_tstep = ecl_sum_data_add_new_tstep( ecl_sum->data , report_step , sim_seconds ); + return new_tstep; } static ecl_sum_type * ecl_sum_alloc_writer__( const char * ecl_case , const char * restart_case , int restart_step, bool fmt_output , bool unified , const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz) { @@ -516,12 +501,12 @@ bool ecl_sum_case_exists( const char * input_file ) { /*****************************************************************/ -double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const smspec_node_type * node) { - return ecl_sum_data_get_from_sim_time( ecl_sum->data , sim_time , node ); +double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const ecl::smspec_node * node) { + return ecl_sum_data_get_from_sim_time( ecl_sum->data , sim_time , *node ); } -double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const smspec_node_type * node) { - return ecl_sum_data_get_from_sim_days( ecl_sum->data , sim_days , node ); +double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const ecl::smspec_node * node) { + return ecl_sum_data_get_from_sim_days( ecl_sum->data , sim_days , *node ); } double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time) { @@ -559,13 +544,13 @@ double ecl_sum_get_well_var(const ecl_sum_type * ecl_sum , int time_index , con } double ecl_sum_get_well_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * well , const char * var) { - const smspec_node_type * node = ecl_smspec_get_well_var_node( ecl_sum->smspec , well , var ); - return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); + const ecl::smspec_node& node = ecl_smspec_get_well_var_node( ecl_sum->smspec , well , var ); + return ecl_sum_get_from_sim_time( ecl_sum , sim_time , &node ); } double ecl_sum_get_well_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * well , const char * var) { - const smspec_node_type * node = ecl_smspec_get_well_var_node( ecl_sum->smspec , well , var ); - return ecl_sum_get_from_sim_days( ecl_sum , sim_days , node ); + const ecl::smspec_node& node = ecl_smspec_get_well_var_node( ecl_sum->smspec , well , var ); + return ecl_sum_get_from_sim_days( ecl_sum , sim_days , &node ); } @@ -583,13 +568,13 @@ double ecl_sum_get_group_var(const ecl_sum_type * ecl_sum , int time_index , co double ecl_sum_get_group_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * group , const char * var) { - const smspec_node_type * node = ecl_smspec_get_group_var_node( ecl_sum->smspec , group , var ); - return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); + const ecl::smspec_node& node = ecl_smspec_get_group_var_node( ecl_sum->smspec , group , var ); + return ecl_sum_get_from_sim_time( ecl_sum , sim_time , &node ); } double ecl_sum_get_group_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * group , const char * var) { - const smspec_node_type * node = ecl_smspec_get_group_var_node( ecl_sum->smspec , group , var ); - return ecl_sum_get_from_sim_days( ecl_sum , sim_days , node ); + const ecl::smspec_node& node = ecl_smspec_get_group_var_node( ecl_sum->smspec , group , var ); + return ecl_sum_get_from_sim_days( ecl_sum , sim_days , &node ); } @@ -605,13 +590,13 @@ double ecl_sum_get_field_var(const ecl_sum_type * ecl_sum , int time_index , con } double ecl_sum_get_field_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var) { - const smspec_node_type * node = ecl_smspec_get_field_var_node( ecl_sum->smspec , var ); - return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); + const ecl::smspec_node& node = ecl_smspec_get_field_var_node( ecl_sum->smspec , var ); + return ecl_sum_get_from_sim_time( ecl_sum , sim_time , &node ); } double ecl_sum_get_field_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var) { - const smspec_node_type * node = ecl_smspec_get_field_var_node( ecl_sum->smspec , var ); - return ecl_sum_get_from_sim_days( ecl_sum , sim_days , node ); + const ecl::smspec_node& node = ecl_smspec_get_field_var_node( ecl_sum->smspec , var ); + return ecl_sum_get_from_sim_days( ecl_sum , sim_days , &node ); } @@ -641,13 +626,13 @@ double ecl_sum_get_block_var_ijk(const ecl_sum_type * ecl_sum , int time_index , } double ecl_sum_get_block_var_ijk_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * block_var, int i , int j , int k) { - const smspec_node_type * node = ecl_smspec_get_block_var_node_ijk( ecl_sum->smspec , block_var , i ,j , k); - return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); + const ecl::smspec_node& node = ecl_smspec_get_block_var_node_ijk( ecl_sum->smspec , block_var , i ,j , k); + return ecl_sum_get_from_sim_time( ecl_sum , sim_time , &node ); } double ecl_sum_get_block_var_ijk_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * block_var, int i , int j , int k) { - const smspec_node_type * node = ecl_smspec_get_block_var_node_ijk( ecl_sum->smspec , block_var , i ,j , k); - return ecl_sum_get_from_sim_days( ecl_sum , sim_days , node ); + const ecl::smspec_node& node = ecl_smspec_get_block_var_node_ijk( ecl_sum->smspec , block_var , i ,j , k); + return ecl_sum_get_from_sim_days( ecl_sum , sim_days , &node ); } @@ -668,13 +653,13 @@ double ecl_sum_get_region_var(const ecl_sum_type * ecl_sum , int time_index , co } double ecl_sum_get_region_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var , int region_nr) { - const smspec_node_type * node = ecl_smspec_get_region_var_node( ecl_sum->smspec , var , region_nr); - return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); + const ecl::smspec_node& node = ecl_smspec_get_region_var_node( ecl_sum->smspec , var , region_nr); + return ecl_sum_get_from_sim_time( ecl_sum , sim_time , &node ); } double ecl_sum_get_region_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var , int region_nr) { - const smspec_node_type * node = ecl_smspec_get_region_var_node( ecl_sum->smspec , var , region_nr); - return ecl_sum_get_from_sim_days( ecl_sum , sim_days , node ); + const ecl::smspec_node& node = ecl_smspec_get_region_var_node( ecl_sum->smspec , var , region_nr); + return ecl_sum_get_from_sim_days( ecl_sum , sim_days , &node ); } @@ -715,14 +700,9 @@ double ecl_sum_get_well_completion_var(const ecl_sum_type * ecl_sum , int time_i /*****************************************************************/ /* General variables - this means WWCT:OP_1 - i.e. composite variables*/ -const smspec_node_type * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_sum->smspec , lookup_kw ); - if (node != NULL) - return node; - else { - util_abort("%s: summary case:%s does not contain key:%s\n",__func__ , ecl_sum_get_case( ecl_sum ) , lookup_kw ); - return NULL; - } +const ecl::smspec_node * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw) { + const ecl::smspec_node& node = ecl_smspec_get_general_var_node( ecl_sum->smspec , lookup_kw ); + return &node; } int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const char * lookup_kw) { @@ -761,30 +741,38 @@ void ecl_sum_fwrite_interp_csv_line(const ecl_sum_type * ecl_sum, time_t sim_tim double ecl_sum_get_general_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , var ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , var ); return ecl_sum_get_from_sim_time( ecl_sum , sim_time , node ); } double ecl_sum_get_general_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , var ); - return ecl_sum_data_get_from_sim_days( ecl_sum->data , sim_days , node ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , var ); + return ecl_sum_data_get_from_sim_days( ecl_sum->data , sim_days , *node ); } const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const char * var) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , var ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , var ); return smspec_node_get_unit( node ); } /*****************************************************************/ -ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times) { - time_t start_time = ecl_sum_get_data_start(ecl_sum); +ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation) { + /* + If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation + or in the case of derivate / rate then it gets zero. if these are set to false, we jus throw exception + */ - if ( time_t_vector_get_first(times) < start_time ) + time_t start_time = ecl_sum_get_data_start(ecl_sum); + time_t end_time = ecl_sum_get_end_time(ecl_sum); + time_t input_start = time_t_vector_get_first( times ); + time_t input_end = time_t_vector_get_last( times ); + + if ( !lower_extrapolation && input_start < start_time ) return NULL; - if ( time_t_vector_get_last(times) > ecl_sum_get_end_time(ecl_sum) ) + if ( !upper_extrapolation && input_end > end_time) return NULL; if ( !time_t_vector_is_sorted(times, false) ) return NULL; @@ -792,38 +780,57 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * const int * grid_dims = ecl_smspec_get_grid_dims(ecl_sum->smspec); bool time_in_days = false; - const smspec_node_type * node = ecl_smspec_iget_node(ecl_sum->smspec, 0); - if ( util_string_equal(smspec_node_get_unit(node), "DAYS" ) ) + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, 0); + if ( util_string_equal(smspec_node_get_unit(&node), "DAYS" ) ) time_in_days = true; - ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_writer( ecl_case , ecl_sum->fmt_case , ecl_sum->unified , ecl_sum->key_join_string , start_time , time_in_days , grid_dims[0] , grid_dims[1] , grid_dims[2] ); - - + //create elc_sum_resampled with TIME node only + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_writer( ecl_case , ecl_sum->fmt_case , ecl_sum->unified , ecl_sum->key_join_string , input_start , time_in_days , grid_dims[0] , grid_dims[1] , grid_dims[2] ); + //add remaining nodes for (int i = 0; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { - const smspec_node_type * node = ecl_smspec_iget_node(ecl_sum->smspec, i); - if (util_string_equal(smspec_node_get_gen_key1(node), "TIME")) + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); + if (util_string_equal(smspec_node_get_gen_key1(&node), "TIME")) continue; - ecl_sum_add_smspec_node( ecl_sum_resampled, node ); + ecl_sum_add_smspec_node( ecl_sum_resampled, &node ); } /* The SMSPEC header structure has been completely initialized, it is time to start filling it up with data. + */ ecl_sum_vector_type * ecl_sum_vector = ecl_sum_vector_alloc(ecl_sum, true); double_vector_type * data = double_vector_alloc( ecl_sum_vector_get_size(ecl_sum_vector) , 0); - for (int report_step = 0; report_step < time_t_vector_size(times); report_step++) { - time_t t = time_t_vector_iget(times, report_step); - - /* Look up interpolated data in the original case. */ - ecl_sum_get_interp_vector( ecl_sum, t, ecl_sum_vector, data); + time_t input_t = time_t_vector_iget(times, report_step); + if (input_t < start_time) { + //clamping to the first value for t < start_time or if it is a rate than derivative is 0 + for (int i=1; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { + double value = 0; + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); + if (!node.is_rate()) + value = ecl_sum_iget_first_value(ecl_sum, node.get_params_index()); + double_vector_iset(data, i-1, value); + } + } else if (input_t > end_time) { + //clamping to the last value for t > end_time or if it is a rate than derivative is 0 + for (int i=1; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { + double value = 0; + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); + if (!node.is_rate()) + value = ecl_sum_iget_last_value(ecl_sum, node.get_params_index()); + double_vector_iset(data, i-1, value); + } + } else { + /* Look up interpolated data in the original case. */ + ecl_sum_get_interp_vector( ecl_sum, input_t, ecl_sum_vector, data); + } /* Add timestep corresponding to the interpolated data in the resampled case. */ - ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum_resampled , report_step , t - start_time); + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum_resampled , report_step , input_t - input_start); for (int data_index = 0; data_index < ecl_sum_vector_get_size(ecl_sum_vector); data_index++) { double value = double_vector_iget(data,data_index); int params_index = data_index + 1; // The +1 shift is because the first element in the tstep is time value. @@ -844,12 +851,12 @@ double ecl_sum_iget( const ecl_sum_type * ecl_sum , int time_index , int param_i /* Simple get functions which take a general var key as input */ bool ecl_sum_var_is_rate( const ecl_sum_type * ecl_sum , const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_is_rate( node ); } bool ecl_sum_var_is_total( const ecl_sum_type * ecl_sum , const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_is_total( node ); } @@ -859,27 +866,27 @@ ecl_smspec_var_type ecl_sum_identify_var_type( const char * var ) { } ecl_smspec_var_type ecl_sum_get_var_type( const ecl_sum_type * ecl_sum , const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_get_var_type( node ); } const char * ecl_sum_get_unit( const ecl_sum_type * ecl_sum , const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_get_unit( node ); } int ecl_sum_get_num( const ecl_sum_type * ecl_sum , const char * gen_key ) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_get_num( node ); } const char * ecl_sum_get_wgname( const ecl_sum_type * ecl_sum , const char * gen_key ) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_get_wgname( node ); } const char * ecl_sum_get_keyword( const ecl_sum_type * ecl_sum , const char * gen_key ) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return smspec_node_get_keyword( node ); } @@ -932,7 +939,7 @@ void ecl_sum_init_double_vector(const ecl_sum_type * ecl_sum, const char * gen_k } void ecl_sum_init_double_vector_interp(const ecl_sum_type * ecl_sum, const char * gen_key, const time_t_vector_type * time_points, double * data) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); + const ecl::smspec_node& node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); ecl_sum_data_init_double_vector_interp(ecl_sum->data, node, time_points, data); } @@ -1305,7 +1312,7 @@ stringlist_type * ecl_sum_alloc_well_var_list( const ecl_sum_type * ecl_sum ) { void ecl_sum_resample_from_sim_time( const ecl_sum_type * ecl_sum , const time_t_vector_type * sim_time , double_vector_type * value , const char * gen_key) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); + const ecl::smspec_node& node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); double_vector_reset( value ); { int i; @@ -1316,7 +1323,7 @@ void ecl_sum_resample_from_sim_time( const ecl_sum_type * ecl_sum , const time_t void ecl_sum_resample_from_sim_days( const ecl_sum_type * ecl_sum , const double_vector_type * sim_days , double_vector_type * value , const char * gen_key) { - const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); + const ecl::smspec_node& node = ecl_smspec_get_general_var_node( ecl_sum->smspec , gen_key); double_vector_reset( value ); { int i; @@ -1377,7 +1384,7 @@ int ecl_sum_get_report_step_from_days( const ecl_sum_type * sum , double sim_day /*****************************************************************/ -const ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ) { +ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ) { return ecl_sum->smspec; } @@ -1430,8 +1437,8 @@ bool ecl_sum_report_step_compatible( const ecl_sum_type * ecl_sum1 , const ecl_s double_vector_type * ecl_sum_alloc_seconds_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key); - return ecl_sum_data_alloc_seconds_solution( ecl_sum->data , node , cmp_value , rates_clamp_lower); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key); + return ecl_sum_data_alloc_seconds_solution( ecl_sum->data , *node , cmp_value , rates_clamp_lower); } @@ -1467,11 +1474,11 @@ double ecl_sum_iget_last_value(const ecl_sum_type * ecl_sum, int param_index) { } double ecl_sum_get_last_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return ecl_sum_iget_last_value(ecl_sum, smspec_node_get_params_index(node)); } -double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node) { +double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const ecl::smspec_node *node) { return ecl_sum_iget_last_value(ecl_sum, smspec_node_get_params_index(node)); } @@ -1480,10 +1487,10 @@ double ecl_sum_iget_first_value(const ecl_sum_type * ecl_sum, int param_index) { } double ecl_sum_get_first_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum , gen_key ); return ecl_sum_iget_first_value(ecl_sum, smspec_node_get_params_index(node)); } -double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node) { +double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const ecl::smspec_node *node) { return ecl_sum_iget_first_value(ecl_sum, smspec_node_get_params_index(node)); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp index b1bc8dba62..e525a6f680 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum_data.c' is part of ERT - Ensemble based Reservoir Tool. @@ -458,16 +458,24 @@ bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_da sequence has no holes. */ +static void fprintf_date_utc(time_t t , FILE * stream) { + int mday,year,month; + + util_set_datetime_values_utc(t , NULL , NULL , NULL , &mday , &month , &year); + fprintf(stream , "%02d/%02d/%4d", mday,month,year); +} + + static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data , time_t sim_time) { if (!ecl_sum_data_check_sim_time(data, sim_time)) { time_t start_time = ecl_sum_data_get_data_start(data); time_t end_time = ecl_sum_data_get_sim_end(data); - fprintf(stderr , "Simulation start: "); util_fprintf_date_utc( ecl_smspec_get_start_time( data->smspec ) , stderr ); - fprintf(stderr , "Data start......: "); util_fprintf_date_utc( start_time , stderr ); - fprintf(stderr , "Simulation end .: "); util_fprintf_date_utc( end_time , stderr ); - fprintf(stderr , "Requested date .: "); util_fprintf_date_utc( sim_time , stderr ); + fprintf(stderr , "Simulation start: "); fprintf_date_utc( ecl_smspec_get_start_time( data->smspec ) , stderr ); + fprintf(stderr , "Data start......: "); fprintf_date_utc( start_time , stderr ); + fprintf(stderr , "Simulation end .: "); fprintf_date_utc( end_time , stderr ); + fprintf(stderr , "Requested date .: "); fprintf_date_utc( sim_time , stderr ); util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , start_time, end_time); } @@ -569,9 +577,9 @@ void ecl_sum_data_init_interp_from_sim_days( const ecl_sum_data_type * data , do } -double_vector_type * ecl_sum_data_alloc_seconds_solution(const ecl_sum_data_type * data, const smspec_node_type * node, double cmp_value, bool rates_clamp_lower) { +double_vector_type * ecl_sum_data_alloc_seconds_solution(const ecl_sum_data_type * data, const ecl::smspec_node& node, double cmp_value, bool rates_clamp_lower) { double_vector_type * solution = double_vector_alloc(0, 0); - const int param_index = smspec_node_get_params_index(node); + const int param_index = smspec_node_get_params_index(&node); const int size = ecl_sum_data_get_length(data); if (size <= 1) @@ -593,7 +601,7 @@ double_vector_type * ecl_sum_data_alloc_seconds_solution(const ecl_sum_data_type double prev_time = ecl_sum_data_iget_sim_seconds(data, prev_index); double time = ecl_sum_data_iget_sim_seconds(data, index); - if (smspec_node_is_rate(node)) { + if (smspec_node_is_rate(&node)) { double_vector_append(solution, rates_clamp_lower ? prev_time + 1 : time); } else { double slope = (value - prev_value) / (time - prev_time); @@ -811,8 +819,8 @@ double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int if (params_map[params_index] >= 0) return file_data->iget( time_index - index_node.offset, params_map[params_index] ); else { - const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, params_index); - return smspec_node_get_default(smspec_node); + const ecl::smspec_node& smspec_node = ecl_smspec_iget_node_w_params_index(data->smspec, params_index); + return smspec_node.get_default(); } } @@ -905,9 +913,9 @@ void ecl_sum_data_get_interp_vector( const ecl_sum_data_type * data , time_t sim } } -double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node) { - int params_index = smspec_node_get_params_index( smspec_node ); - if (smspec_node_is_rate( smspec_node )) { +double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const ecl::smspec_node& smspec_node) { + int params_index = smspec_node_get_params_index( &smspec_node ); + if (smspec_node_is_rate( &smspec_node )) { /* In general the mapping from sim_time to index is based on half open intervals, which are closed in the upper end: @@ -986,7 +994,7 @@ double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time) return util_difftime_days( start_time , sim_time ); } -double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node) { +double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const ecl::smspec_node& smspec_node) { time_t sim_time = ecl_smspec_get_start_time( data->smspec ); util_inplace_forward_days_utc( &sim_time , sim_days ); return ecl_sum_data_get_from_sim_time( data , sim_time , smspec_node ); @@ -1076,22 +1084,18 @@ static void ecl_sum_data_init_double_vector__(const ecl_sum_data_type * data, in const auto& params_map = index_node.params_map; int params_index = params_map[main_params_index]; - if (report_only) { - const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, main_params_index); - double default_value = smspec_node_get_default(smspec_node); + const ecl::smspec_node& smspec_node = ecl_smspec_iget_node_w_params_index(data->smspec, main_params_index); + double default_value = smspec_node.get_default(); offset += data_file->get_data_report(params_index, index_node.length, &output_data[offset], default_value); } else { if (params_index >= 0) data_file->get_data(params_index, index_node.length, &output_data[offset]); else { - const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, main_params_index); - if (smspec_node) - { - for (int i=0; i < index_node.length; i++) - output_data[offset + i] = smspec_node_get_default(smspec_node); - } + const ecl::smspec_node& smspec_node = ecl_smspec_iget_node_w_params_index(data->smspec, main_params_index); + for (int i=0; i < index_node.length; i++) + output_data[offset + i] = smspec_node.get_default(); } offset += index_node.length; } @@ -1118,6 +1122,9 @@ double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * d else output_data.resize( ecl_sum_data_get_length(data) ); + if (params_index >= ecl_smspec_get_params_size(data->smspec)) + throw std::out_of_range("Out of range"); + ecl_sum_data_init_double_vector__(data, params_index, output_data.data(), report_only); double_vector_type * data_vector = double_vector_alloc(output_data.size(), 0); { @@ -1129,11 +1136,11 @@ double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * d void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, - const smspec_node_type * smspec_node, + const ecl::smspec_node& smspec_node, const time_t_vector_type * time_points, double * output_data) { - bool is_rate = smspec_node_is_rate(smspec_node); - int params_index = smspec_node_get_params_index(smspec_node); + bool is_rate = smspec_node_is_rate(&smspec_node); + int params_index = smspec_node_get_params_index(&smspec_node); time_t start_time = ecl_sum_data_get_data_start(data); time_t end_time = ecl_sum_data_get_sim_end(data); double start_value = 0; diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp index b0367e2ec5..19c6fa28cd 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp @@ -471,7 +471,8 @@ void ecl_sum_file_data::fwrite_report( int report_step , fortio_type * fortio) c auto range = this->report_range( report_step ); for (int index = range.first; index <= range.second; index++) { const ecl_sum_tstep_type * tstep = iget_ministep( index ); - ecl_sum_tstep_fwrite( tstep , ecl_smspec_get_index_map( ecl_smspec ) , fortio ); + //ecl_sum_tstep_fwrite( tstep , ecl_smspec_get_index_map( ecl_smspec ) , fortio ); + ecl_sum_tstep_fwrite( tstep , ecl_smspec_get_index_map(ecl_smspec) , ecl_smspec_num_nodes(ecl_smspec), fortio ); } } } @@ -553,7 +554,7 @@ bool ecl_sum_file_data::check_file( ecl_file_type * ecl_file ) { calling routine will read the unified summary file partly. */ -void ecl_sum_file_data::add_ecl_file(int report_step, const ecl_file_view_type * summary_view, const ecl_smspec_type * smspec) { +void ecl_sum_file_data::add_ecl_file(int report_step, const ecl_file_view_type * summary_view) { int num_ministep = ecl_file_view_get_num_named_kw( summary_view , PARAMS_KW); if (num_ministep > 0) { @@ -569,7 +570,7 @@ void ecl_sum_file_data::add_ecl_file(int report_step, const ecl_file_view_type * ministep_nr , params_kw , ecl_file_view_get_src_file( summary_view ), - smspec ); + this->ecl_smspec ); if (tstep) append_tstep( tstep ); @@ -600,7 +601,7 @@ bool ecl_sum_file_data::fread(const stringlist_type * filelist, bool lazy_load, { ecl_file_type * ecl_file = ecl_file_open( data_file , 0); if (ecl_file && check_file( ecl_file )) { - add_ecl_file( report_step , ecl_file_get_global_view( ecl_file ) , ecl_smspec); + this->add_ecl_file( report_step , ecl_file_get_global_view( ecl_file )); ecl_file_close( ecl_file ); } } @@ -632,7 +633,7 @@ bool ecl_sum_file_data::fread(const stringlist_type * filelist, bool lazy_load, */ ecl_file_view_type * summary_view = ecl_file_get_summary_view(ecl_file , block_index); if (summary_view) { - add_ecl_file(block_index + first_report_step , summary_view , ecl_smspec); + this->add_ecl_file(block_index + first_report_step , summary_view); block_index++; } else break; } diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp index 3211baac34..ff3694f32f 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum_index.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp index 380b7e5732..6e565e7e16 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp @@ -1,5 +1,5 @@ - /* - Copyright (C) 2012 Statoil ASA, Norway. +/* + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_sum_tstep.c' is part of ERT - Ensemble based Reservoir Tool. @@ -19,6 +19,8 @@ #include #include +#include + #include #include @@ -59,12 +61,11 @@ Header direction: ecl_smspec DAYS WWCT:OP_3 FOPT BPR:15,10,25 struct ecl_sum_tstep_struct { UTIL_TYPE_ID_DECLARATION; - float * data; /* A memcpy copy of the PARAMS vector in ecl_kw instance - the raw data. */ + std::vector data; /* A memcpy copy of the PARAMS vector in ecl_kw instance - the raw data. */ time_t sim_time; /* The true time (i.e. 20.th of october 2010) of corresponding to this timestep. */ int ministep; /* The ECLIPSE internal time-step number; one ministep per numerical timestep. */ int report_step; /* The report step this time-step is part of - in general there can be many timestep for each report step. */ double sim_seconds; /* Accumulated simulation time up to this ministep. */ - int data_size; /* Number of elements in data - only used for checking indices. */ int internal_index; /* Used for lookups of the next / previous ministep based on an existing ministep. */ const ecl_smspec_type * smspec; /* The smespec header information for this tstep - must be compatible. */ }; @@ -72,11 +73,13 @@ struct ecl_sum_tstep_struct { ecl_sum_tstep_type * ecl_sum_tstep_alloc_remap_copy( const ecl_sum_tstep_type * src , const ecl_smspec_type * new_smspec, float default_value , const int * params_map) { int params_size = ecl_smspec_get_params_size( new_smspec ); - ecl_sum_tstep_type * target = (ecl_sum_tstep_type*)util_alloc_copy(src , sizeof * src ); + ecl_sum_tstep_type * target = new ecl_sum_tstep_type(); + UTIL_TYPE_ID_INIT( target , ECL_SUM_TSTEP_ID); + target->report_step = src->report_step; + target->ministep = src->ministep; target->smspec = new_smspec; - target->data = (float*)util_malloc( params_size * sizeof * target->data ); - target->data_size = params_size; + target->data.resize(params_size); for (int i=0; i < params_size; i++) { if (params_map[i] >= 0) @@ -89,20 +92,23 @@ ecl_sum_tstep_type * ecl_sum_tstep_alloc_remap_copy( const ecl_sum_tstep_type * } ecl_sum_tstep_type * ecl_sum_tstep_alloc_copy( const ecl_sum_tstep_type * src ) { - ecl_sum_tstep_type * target = (ecl_sum_tstep_type*)util_alloc_copy(src , sizeof * src ); - target->data = (float*)util_alloc_copy( src->data , src->data_size * sizeof * src->data ); + ecl_sum_tstep_type * target = new ecl_sum_tstep_type(); + UTIL_TYPE_ID_INIT( target , ECL_SUM_TSTEP_ID); + target->smspec = src->smspec; + target->report_step = src->report_step; + target->ministep = src->ministep; + target->data = src->data; return target; } static ecl_sum_tstep_type * ecl_sum_tstep_alloc( int report_step , int ministep_nr , const ecl_smspec_type * smspec) { - ecl_sum_tstep_type * tstep = (ecl_sum_tstep_type*)util_malloc( sizeof * tstep ); + ecl_sum_tstep_type * tstep = new ecl_sum_tstep_type(); UTIL_TYPE_ID_INIT( tstep , ECL_SUM_TSTEP_ID); tstep->smspec = smspec; tstep->report_step = report_step; tstep->ministep = ministep_nr; - tstep->data_size = ecl_smspec_get_params_size( smspec ); - tstep->data = (float*)util_calloc( tstep->data_size , sizeof * tstep->data ); + tstep->data.resize( ecl_smspec_get_params_size( smspec ) ); return tstep; } @@ -112,8 +118,7 @@ UTIL_SAFE_CAST_FUNCTION_CONST( ecl_sum_tstep , ECL_SUM_TSTEP_ID) void ecl_sum_tstep_free( ecl_sum_tstep_type * ministep ) { - free( ministep->data ); - free( ministep ); + delete ministep; } @@ -201,7 +206,7 @@ ecl_sum_tstep_type * ecl_sum_tstep_alloc_from_file( int report_step , if (data_size == ecl_smspec_get_params_size( smspec )) { ecl_sum_tstep_type * ministep = ecl_sum_tstep_alloc( report_step , ministep_nr , smspec); - ecl_kw_get_memcpy_data( params_kw , ministep->data ); + ecl_kw_get_memcpy_data( params_kw , ministep->data.data() ); ecl_sum_tstep_set_time_info( ministep , smspec ); return ministep; } else { @@ -211,7 +216,11 @@ ecl_sum_tstep_type * ecl_sum_tstep_alloc_from_file( int report_step , ecl_smspec_load_restart() function and the restart case discarded. */ - fprintf(stderr , "** Warning size mismatch between timestep loaded from:%s and header:%s - timestep discarded.\n" , src_file , ecl_smspec_get_header_file( smspec )); + fprintf(stderr , "** Warning size mismatch between timestep loaded from:%s(%d) and header:%s(%d) - timestep discarded.\n" , + src_file , + data_size, + ecl_smspec_get_header_file( smspec ), + ecl_smspec_get_params_size( smspec )); return NULL; } } @@ -223,8 +232,7 @@ ecl_sum_tstep_type * ecl_sum_tstep_alloc_from_file( int report_step , ecl_sum_tstep_type * ecl_sum_tstep_alloc_new( int report_step , int ministep , float sim_seconds , const ecl_smspec_type * smspec ) { ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc( report_step , ministep , smspec ); - const float_vector_type * default_data = ecl_smspec_get_params_default( smspec ); - float_vector_memcpy_data( tstep->data , default_data ); + tstep->data = ecl_smspec_get_params_default( smspec ); ecl_sum_tstep_set_time_info_from_seconds( tstep , ecl_smspec_get_start_time( smspec ) , sim_seconds ); ecl_sum_tstep_iset( tstep , ecl_smspec_get_time_index( smspec ) , sim_seconds / ecl_smspec_get_time_seconds( smspec ) ); @@ -235,10 +243,10 @@ ecl_sum_tstep_type * ecl_sum_tstep_alloc_new( int report_step , int ministep , f double ecl_sum_tstep_iget(const ecl_sum_tstep_type * ministep , int index) { - if ((index >= 0) && (index < ministep->data_size)) + if ((index >= 0) && (index < (int)ministep->data.size())) return ministep->data[index]; else { - util_abort("%s: param index:%d invalid: Valid range: [0,%d) \n",__func__ , index , ministep->data_size); + util_abort("%s: param index:%d invalid: Valid range: [0,%d) \n",__func__ , index , ministep->data.size()); return -1; } } @@ -269,7 +277,7 @@ int ecl_sum_tstep_get_ministep(const ecl_sum_tstep_type * ministep) { /*****************************************************************/ -void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vector_type * index_map , fortio_type * fortio) { +void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int * index_map , int index_map_size, fortio_type * fortio) { { ecl_kw_type * ministep_kw = ecl_kw_alloc( MINISTEP_KW , 1 , ECL_INT ); ecl_kw_iset_int( ministep_kw , 0 , ministep->ministep ); @@ -278,16 +286,15 @@ void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vecto } { - int compact_size = int_vector_size( index_map ); + int compact_size = index_map_size; ecl_kw_type * params_kw = ecl_kw_alloc( PARAMS_KW , compact_size , ECL_FLOAT ); - const int * index = int_vector_get_ptr( index_map ); float * data = (float*)ecl_kw_get_ptr( params_kw ); { int i; for (i=0; i < compact_size; i++) - data[i] = ministep->data[ index[i] ]; + data[i] = ministep->data[ index_map[i] ]; } ecl_kw_fwrite( params_kw , fortio ); ecl_kw_free( params_kw ); @@ -298,10 +305,10 @@ void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vecto /*****************************************************************/ void ecl_sum_tstep_iset( ecl_sum_tstep_type * tstep , int index , float value) { - if ((index < tstep->data_size) && (index >= 0)) + if ((index < static_cast(tstep->data.size())) && (index >= 0) ) tstep->data[index] = value; else - util_abort("%s: index:%d invalid. Valid range: [0,%d) \n",__func__ ,index , tstep->data_size); + util_abort("%s: index:%d invalid. Valid range: [0,%d) \n",__func__ ,index , tstep->data.size()); } void ecl_sum_tstep_iscale(ecl_sum_tstep_type * tstep, int index, float scalar) { @@ -312,24 +319,24 @@ void ecl_sum_tstep_ishift(ecl_sum_tstep_type * tstep, int index, float addend) { ecl_sum_tstep_iset(tstep, index, ecl_sum_tstep_iget(tstep, index) + addend); } -void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node , float value) { - int data_index = smspec_node_get_params_index( smspec_node ); +void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const ecl::smspec_node& smspec_node , float value) { + int data_index = smspec_node_get_params_index( &smspec_node ); ecl_sum_tstep_iset( tstep , data_index , value); } -double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node) { - int data_index = smspec_node_get_params_index( smspec_node ); +double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const ecl::smspec_node& smspec_node) { + int data_index = smspec_node_get_params_index( &smspec_node ); return ecl_sum_tstep_iget( tstep , data_index); } void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_key , float value) { - const smspec_node_type * smspec_node = ecl_smspec_get_general_var_node( tstep->smspec , gen_key ); + const ecl::smspec_node& smspec_node = ecl_smspec_get_general_var_node( tstep->smspec , gen_key ); ecl_sum_tstep_set_from_node( tstep , smspec_node , value); } double ecl_sum_tstep_get_from_key(const ecl_sum_tstep_type * tstep , const char * gen_key) { - const smspec_node_type * smspec_node = ecl_smspec_get_general_var_node( tstep->smspec , gen_key ); + const ecl::smspec_node& smspec_node = ecl_smspec_get_general_var_node( tstep->smspec , gen_key ); return ecl_sum_tstep_get_from_node(tstep , smspec_node ); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp index 8bcfebfe4a..ee7d9e1d64 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_sum_vector.c' is part of ERT - Ensemble based Reservoir Tool. @@ -16,6 +16,10 @@ for more details. */ #include + +#include +#include + #include #include #include @@ -23,68 +27,60 @@ #include #include #include -#include -#include #define ECL_SUM_VECTOR_TYPE_ID 8768778 struct ecl_sum_vector_struct { UTIL_TYPE_ID_DECLARATION; - int_vector_type * node_index_list; - bool_vector_type * is_rate_list; - stringlist_type * key_list; + std::vector node_index_list; + std::vector is_rate_list; + std::vector key_list; const ecl_sum_type * ecl_sum; }; void ecl_sum_vector_free( ecl_sum_vector_type * ecl_sum_vector ){ - int_vector_free(ecl_sum_vector->node_index_list); - bool_vector_free(ecl_sum_vector->is_rate_list); - stringlist_free(ecl_sum_vector->key_list); - free(ecl_sum_vector); + delete ecl_sum_vector; } UTIL_IS_INSTANCE_FUNCTION( ecl_sum_vector , ECL_SUM_VECTOR_TYPE_ID ) -static void ecl_sum_vector_add_node(ecl_sum_vector_type * vector, const smspec_node_type * node, const char * key ) { +static void ecl_sum_vector_add_node(ecl_sum_vector_type * vector, const ecl::smspec_node * node, const char * key ) { int params_index = smspec_node_get_params_index( node ); bool is_rate_key = smspec_node_is_rate( node); - int_vector_append(vector->node_index_list, params_index); - bool_vector_append(vector->is_rate_list, is_rate_key); - stringlist_append_copy( vector->key_list, key ); + vector->node_index_list.push_back(params_index); + vector->is_rate_list.push_back(is_rate_key); + vector->key_list.push_back(key); } ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum, bool add_keywords) { - ecl_sum_vector_type * ecl_sum_vector = (ecl_sum_vector_type*)util_malloc( sizeof * ecl_sum_vector ); + ecl_sum_vector_type * ecl_sum_vector = new ecl_sum_vector_type(); UTIL_TYPE_ID_INIT( ecl_sum_vector , ECL_SUM_VECTOR_TYPE_ID); ecl_sum_vector->ecl_sum = ecl_sum; - ecl_sum_vector->node_index_list = int_vector_alloc(0,0); - ecl_sum_vector->is_rate_list = bool_vector_alloc(0,false); - ecl_sum_vector->key_list = stringlist_alloc_new( ); if (add_keywords) { const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum); for (int i=0; i < ecl_smspec_num_nodes(smspec); i++) { - const smspec_node_type * node = ecl_smspec_iget_node( smspec , i ); - const char * key = smspec_node_get_gen_key1(node); + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index( smspec , i ); + const char * key = smspec_node_get_gen_key1(&node); /* The TIME keyword is special case handled to not be included; that is to match the same special casing in the key matching function. */ if (!util_string_equal(key, "TIME")) - ecl_sum_vector_add_node( ecl_sum_vector, node, key); + ecl_sum_vector_add_node( ecl_sum_vector, &node, key); } } return ecl_sum_vector; } static void ecl_sum_vector_add_invalid_key(ecl_sum_vector_type * vector, const char * key) { - int_vector_append(vector->node_index_list, -1); - bool_vector_append(vector->is_rate_list, false); - stringlist_append_copy(vector->key_list, key); + vector->node_index_list.push_back(-1); + vector->is_rate_list.push_back(false); + vector->key_list.push_back(key); } @@ -103,8 +99,8 @@ static void ecl_sum_vector_add_invalid_key(ecl_sum_vector_type * vector, const c ecl_sum_vector_type * ecl_sum_vector_alloc_layout_copy(const ecl_sum_vector_type * src_vector, const ecl_sum_type * ecl_sum) { ecl_sum_vector_type * new_vector = ecl_sum_vector_alloc(ecl_sum, false); - for (int i=0; i < stringlist_get_size(src_vector->key_list); i++) { - const char * key = stringlist_iget(src_vector->key_list, i); + for (size_t i=0; i < src_vector->key_list.size(); i++) { + const char * key = src_vector->key_list[i].c_str(); if (ecl_sum_has_general_var(ecl_sum, key)) ecl_sum_vector_add_key(new_vector, key); else @@ -117,7 +113,7 @@ ecl_sum_vector_type * ecl_sum_vector_alloc_layout_copy(const ecl_sum_vector_type bool ecl_sum_vector_add_key( ecl_sum_vector_type * ecl_sum_vector, const char * key){ if (ecl_sum_has_general_var( ecl_sum_vector->ecl_sum , key)) { - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key ); ecl_sum_vector_add_node(ecl_sum_vector, node, key); return true; } else @@ -131,29 +127,29 @@ void ecl_sum_vector_add_keys( ecl_sum_vector_type * ecl_sum_vector, const char * int i; for(i = 0; i < num_keywords ;i++){ const char * key = stringlist_iget(keylist, i); - const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key ); + const ecl::smspec_node * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key ); ecl_sum_vector_add_node(ecl_sum_vector, node, key); } stringlist_free(keylist); } int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector){ - return int_vector_size(ecl_sum_vector->node_index_list); + return ecl_sum_vector->node_index_list.size(); } bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index){ - return bool_vector_iget(ecl_sum_vector->is_rate_list, index); + return ecl_sum_vector->is_rate_list[index]; } bool ecl_sum_vector_iget_valid(const ecl_sum_vector_type * ecl_sum_vector, int index) { - return (int_vector_iget(ecl_sum_vector->node_index_list, index) >= 0); + return (ecl_sum_vector->node_index_list[index] >= 0); } int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index){ - return int_vector_iget(ecl_sum_vector->node_index_list, index); + return ecl_sum_vector->node_index_list[index]; } const char* ecl_sum_vector_iget_key(const ecl_sum_vector_type * ecl_sum_vector, int index){ - return stringlist_iget( ecl_sum_vector->key_list , index); + return ecl_sum_vector->key_list[index].c_str(); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_type.cpp b/ThirdParty/Ert/lib/ecl/ecl_type.cpp index da180467d9..6e0f6dca7c 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_type.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_type.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_type.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp b/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp index bd9eb1edde..e30b038d89 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp @@ -53,7 +53,7 @@ int unsmry_loader::length() const { std::vector unsmry_loader::get_vector(int pos) const { if (pos >= size) - throw std::invalid_argument("unsmry_loader::get_vector: argument 'pos' mst be less than size of PARAMS."); + throw std::out_of_range("unsmry_loader::get_vector pos: " + std::to_string(pos) + " PARAMS_SIZE: " + std::to_string(size)); std::vector data(this->length()); int_vector_type * index_map = int_vector_alloc( 1 , pos); diff --git a/ThirdParty/Ert/lib/ecl/ecl_util.cpp b/ThirdParty/Ert/lib/ecl/ecl_util.cpp index fd479ca131..f0ddca45dd 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_util.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_util.c' is part of ERT - Ensemble based Reservoir Tool. @@ -1290,6 +1290,8 @@ static int ecl_util_get_num_slave_cpu__(basic_parser_type* parser, FILE* stream, const char * first_item = stringlist_iget(tokens, 0); if (first_item[0] == '/') { + stringlist_free(tokens); + free(buffer); break; } else{ diff --git a/ThirdParty/Ert/lib/ecl/fault_block.cpp b/ThirdParty/Ert/lib/ecl/fault_block.cpp index 8ea051204b..11a3452500 100644 --- a/ThirdParty/Ert/lib/ecl/fault_block.cpp +++ b/ThirdParty/Ert/lib/ecl/fault_block.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'fault_block.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp b/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp index c802705d36..3565a02210 100644 --- a/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp +++ b/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'fault_block_layer.c' is part of ERT - Ensemble based Reservoir Tool. @@ -67,6 +67,8 @@ fault_block_type * fault_block_layer_add_block( fault_block_layer_type * layer , fault_block_type * block = fault_block_alloc( layer , block_id ); int storage_index = vector_get_size( layer->blocks ); + if (block_id >= int_vector_size(layer->block_map)) + int_vector_resize(layer->block_map, block_id+1, -1); int_vector_iset( layer->block_map , block_id , storage_index ); vector_append_owned_ref( layer->blocks , block , fault_block_free__ ); diff --git a/ThirdParty/Ert/lib/ecl/fortio.c b/ThirdParty/Ert/lib/ecl/fortio.c index ec096364d0..e67c4072cc 100644 --- a/ThirdParty/Ert/lib/ecl/fortio.c +++ b/ThirdParty/Ert/lib/ecl/fortio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'fortio.c' is part of ERT - Ensemble based Reservoir Tool. @@ -30,8 +30,6 @@ #define FORTIO_ID 345116 -extern int errno; - /** The fortio struct is implemented to handle fortran io. The problem is that when a Fortran program writes unformatted data to file in a diff --git a/ThirdParty/Ert/lib/ecl/grid_dims.cpp b/ThirdParty/Ert/lib/ecl/grid_dims.cpp index 7a243f2878..ab5d327403 100644 --- a/ThirdParty/Ert/lib/ecl/grid_dims.cpp +++ b/ThirdParty/Ert/lib/ecl/grid_dims.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/layer.cpp b/ThirdParty/Ert/lib/ecl/layer.cpp index 07fe65f50e..3cbcbf5073 100644 --- a/ThirdParty/Ert/lib/ecl/layer.cpp +++ b/ThirdParty/Ert/lib/ecl/layer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'layer.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/nnc_info.cpp b/ThirdParty/Ert/lib/ecl/nnc_info.cpp index d520a985ae..2667303b70 100644 --- a/ThirdParty/Ert/lib/ecl/nnc_info.cpp +++ b/ThirdParty/Ert/lib/ecl/nnc_info.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'nnc_info.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,9 +18,14 @@ #include +#include +#include +#include + #include #include #include +#include #include #include @@ -127,6 +132,8 @@ nnc_vector_type * nnc_info_get_self_vector( const nnc_info_type * nnc_info ) { static void nnc_info_add_vector( nnc_info_type * nnc_info , nnc_vector_type * nnc_vector) { vector_append_owned_ref( nnc_info->lgr_list , nnc_vector , nnc_vector_free__ ); + if (nnc_vector_get_lgr_nr( nnc_vector ) >= int_vector_size( nnc_info->lgr_index_map ) ) + int_vector_resize( nnc_info->lgr_index_map , nnc_vector_get_lgr_nr( nnc_vector)+1, -1); int_vector_iset( nnc_info->lgr_index_map , nnc_vector_get_lgr_nr( nnc_vector ) , vector_get_size( nnc_info->lgr_list ) - 1 ); } @@ -149,27 +156,28 @@ void nnc_info_add_nnc(nnc_info_type * nnc_info, int lgr_nr, int global_cell_numb } } +bool nnc_info_has_grid_index_list( const nnc_info_type * nnc_info, int lgr_nr ) { + return (nnc_info_get_vector( nnc_info , lgr_nr ) != NULL); +} -const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr) { +const std::vector& nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr) { nnc_vector_type * nnc_vector = nnc_info_get_vector( nnc_info , lgr_nr ); - if (nnc_vector) - return nnc_vector_get_grid_index_list( nnc_vector ); - else - return NULL; + if (!nnc_vector) + throw std::invalid_argument(std::string(__func__)); + return nnc_vector_get_grid_index_list( nnc_vector ); } -const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index) { +const std::vector& nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index) { nnc_vector_type * nnc_vector = nnc_info_iget_vector( nnc_info , lgr_index ); - if (nnc_vector) - return nnc_vector_get_grid_index_list( nnc_vector ); - else - return NULL; + if (!nnc_vector) + throw std::invalid_argument(std::string(__func__)); + return nnc_vector_get_grid_index_list( nnc_vector ); } -const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info) { +const std::vector& nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info) { return nnc_info_get_grid_index_list( nnc_info , nnc_info->lgr_nr ); } @@ -205,8 +213,8 @@ void nnc_info_fprintf(const nnc_info_type * nnc_info , FILE * stream) { if (lgr_index >= 0) { printf(" %02d -> %02d => ",lgr_nr , lgr_index); { - const int_vector_type * index_list = nnc_info_iget_grid_index_list( nnc_info , lgr_index ); - int_vector_fprintf( index_list , stream , " " , "%d"); + const std::vector& index_list = nnc_info_iget_grid_index_list( nnc_info , lgr_index ); + vector_util_fprintf( index_list , stream , " " , "%d"); printf("\n"); } } diff --git a/ThirdParty/Ert/lib/ecl/nnc_vector.cpp b/ThirdParty/Ert/lib/ecl/nnc_vector.cpp index b808faa6e4..be24ffba67 100644 --- a/ThirdParty/Ert/lib/ecl/nnc_vector.cpp +++ b/ThirdParty/Ert/lib/ecl/nnc_vector.cpp @@ -1,6 +1,6 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. @@ -19,10 +19,11 @@ #include +#include + #include #include #include -#include #include @@ -33,9 +34,9 @@ struct nnc_vector_struct { UTIL_TYPE_ID_DECLARATION; - int lgr_nr; - int_vector_type * grid_index_list; - int_vector_type * nnc_index_list; + int lgr_nr; + std::vector grid_index_list; + std::vector nnc_index_list; }; @@ -45,21 +46,19 @@ static UTIL_SAFE_CAST_FUNCTION(nnc_vector , NNC_VECTOR_TYPE_ID) nnc_vector_type * nnc_vector_alloc(int lgr_nr) { - nnc_vector_type * nnc_vector = (nnc_vector_type*)util_malloc( sizeof * nnc_vector ); + nnc_vector_type * nnc_vector = new nnc_vector_type(); UTIL_TYPE_ID_INIT(nnc_vector , NNC_VECTOR_TYPE_ID); - nnc_vector->grid_index_list = int_vector_alloc(0,0); - nnc_vector->nnc_index_list = int_vector_alloc(0,0); nnc_vector->lgr_nr = lgr_nr; return nnc_vector; } nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector) { - nnc_vector_type * copy_vector = (nnc_vector_type*)util_malloc( sizeof * src_vector ); + nnc_vector_type * copy_vector = new nnc_vector_type(); UTIL_TYPE_ID_INIT(copy_vector , NNC_VECTOR_TYPE_ID); copy_vector->lgr_nr = src_vector->lgr_nr; - copy_vector->grid_index_list = int_vector_alloc_copy( src_vector->grid_index_list ); - copy_vector->nnc_index_list = int_vector_alloc_copy( src_vector->nnc_index_list ); + copy_vector->grid_index_list = src_vector->grid_index_list; + copy_vector->nnc_index_list = src_vector->nnc_index_list; return copy_vector; } @@ -75,10 +74,10 @@ bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_ty if (nnc_vector1->lgr_nr != nnc_vector2->lgr_nr) return false; - if (!int_vector_equal( nnc_vector1->grid_index_list , nnc_vector2->grid_index_list)) + if (nnc_vector1->grid_index_list != nnc_vector2->grid_index_list) return false; - if (!int_vector_equal( nnc_vector1->nnc_index_list , nnc_vector2->nnc_index_list)) + if (nnc_vector1->nnc_index_list != nnc_vector2->nnc_index_list) return false; return true; @@ -87,9 +86,7 @@ bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_ty void nnc_vector_free( nnc_vector_type * nnc_vector ) { - int_vector_free( nnc_vector->grid_index_list ); - int_vector_free( nnc_vector->nnc_index_list ); - free( nnc_vector ); + delete nnc_vector; } @@ -100,21 +97,21 @@ void nnc_vector_free__(void * arg) { void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number , int nnc_index) { - int_vector_append( nnc_vector->grid_index_list , global_cell_number ); - int_vector_append( nnc_vector->nnc_index_list , nnc_index); + nnc_vector->grid_index_list.push_back( global_cell_number ); + nnc_vector->nnc_index_list.push_back(nnc_index); } -const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector) { +const std::vector& nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector) { return nnc_vector->grid_index_list; } -const int_vector_type * nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector) { +const std::vector& nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector) { return nnc_vector->nnc_index_list; } int nnc_vector_get_size( const nnc_vector_type * nnc_vector ) { - return int_vector_size( nnc_vector->grid_index_list ); + return nnc_vector->grid_index_list.size(); } int nnc_vector_get_lgr_nr( const nnc_vector_type * nnc_vector ) { @@ -122,9 +119,9 @@ int nnc_vector_get_lgr_nr( const nnc_vector_type * nnc_vector ) { } int nnc_vector_iget_nnc_index( const nnc_vector_type * nnc_vector , int index ) { - return int_vector_iget( nnc_vector->nnc_index_list , index ); + return nnc_vector->nnc_index_list[index]; } int nnc_vector_iget_grid_index( const nnc_vector_type * nnc_vector , int index ) { - return int_vector_iget( nnc_vector->grid_index_list , index ); + return nnc_vector->grid_index_list[index]; } diff --git a/ThirdParty/Ert/lib/ecl/smspec_node.cpp b/ThirdParty/Ert/lib/ecl/smspec_node.cpp index 98bf35b597..ba4e9bfdae 100644 --- a/ThirdParty/Ert/lib/ecl/smspec_node.cpp +++ b/ThirdParty/Ert/lib/ecl/smspec_node.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'smspec_node.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,12 +18,14 @@ #include #include +#include #include #include #include #include #include +#include #include #include @@ -41,6 +43,35 @@ #include "detail/util/string_util.hpp" +/** + The special_vars list is used to associate keywords with special + types, when the kewyord name is in conflict with the default vector + naming convention; all the variables mentioned in the list below + are given the type ECL_SMSPEC_MISC_VAR. + + For instance the keyword 'NEWTON' starts with 'N' and is + classified as a NETWORK type variable. However it should rather + be classified as a MISC type variable. (What a fucking mess). + + The special_vars list is used in the functions + ecl_smspec_identify_special_var() and ecl_smspec_identify_var_type(). +*/ + +static const char* special_vars[] = {"NEWTON", + "NAIMFRAC", + "NLINEARS", + "NLINSMIN", + "NLINSMAX", + "ELAPSED", + "MAXDPR", + "MAXDSO", + "MAXDSG", + "MAXDSW", + "STEPTYPE", + "WNEWTON"}; + + +static const int nums_unused = 0; /** This struct contains meta-information about one element in the smspec @@ -50,53 +81,166 @@ probably the most important field. */ -#define SMSPEC_TYPE_ID 61550451 +/** + Goes through the special_vars static table to check if @var is one + the special variables which does not follow normal naming + convention. If the test eavulates to true the function will return + ECL_SMSPEC_MISC_VAR, otherwise the function will return + ECL_SMSPEC_INVALID_VAR and the variable type will be determined + from the var name according to standard naming conventions. + It is important that this function is called before the standard + method. +*/ -struct smspec_node_struct { - UTIL_TYPE_ID_DECLARATION; - std::string wgname; - std::string keyword; /* The value of the KEYWORDS vector for this elements. */ - std::string unit; /* The value of the UNITS vector for this elements. */ - int num; /* The value of the NUMS vector for this elements - NB this will have the value SMSPEC_NUMS_INVALID if the smspec file does not have a NUMS vector. */ - std::string lgr_name; /* The lgr name of the current variable - will be NULL for non-lgr variables. */ - std::array lgr_ijk; +ecl_smspec_var_type ecl::smspec_node::identify_special_var( const char * var ) { + ecl_smspec_var_type var_type = ECL_SMSPEC_INVALID_VAR; - /*------------------------------------------- All members below this line are *derived* quantities. */ + int num_special = sizeof( special_vars ) / sizeof( special_vars[0] ); + int i; + for (i=0; i < num_special; i++) { + if (strcmp( var , special_vars[i]) == 0) { + var_type = ECL_SMSPEC_MISC_VAR; + break; + } + } - std::string gen_key1; /* The main composite key, i.e. WWCT:OP3 for this element. */ - std::string gen_key2; /* Some of the ijk based elements will have both a xxx:i,j,k and a xxx:num key. Some of the region_2_region elements will have both a xxx:num and a xxx:r2-r2 key. Mostly NULL. */ - ecl_smspec_var_type var_type; /* The variable type */ - std::array ijk; /* The ijk coordinates (NB: OFFSET 1) corresponding to the nums value - will be NULL if not relevant. */ - bool rate_variable; /* Is this a rate variable (i.e. WOPR) or a state variable (i.e. BPR). Relevant when doing time interpolation. */ - bool total_variable; /* Is this a total variable like WOPT? */ - bool historical; /* Does the name end with 'H'? */ - int params_index; /* The index of this variable (applies to all the vectors - in particular the PARAMS vectors of the summary files *.Snnnn / *.UNSMRY ). */ - float default_value; /* Default value for this variable. */ -}; - - - -bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2) { - return smspec_node_cmp( node1 , node2 ) == 0; + return var_type; } -static bool smspec_node_need_wgname(ecl_smspec_var_type var_type) { - if (var_type == ECL_SMSPEC_COMPLETION_VAR || - var_type == ECL_SMSPEC_GROUP_VAR || - var_type == ECL_SMSPEC_WELL_VAR || - var_type == ECL_SMSPEC_SEGMENT_VAR) - return true; - else - return false; +/* + See table 3.4 in the ECLIPSE file format reference manual. + + Observe that the combined ecl_sum style keys like e.g. WWCT:OP1 + should be formatted with the keyword first, so that this function + will identify both 'WWCT' and 'WWCT:OP_1' as a ECL_SMSPEC_WELL_VAR + instance. +*/ + +ecl_smspec_var_type ecl::smspec_node::identify_var_type(const char * var) { + ecl_smspec_var_type var_type = ecl::smspec_node::identify_special_var(var); + if (var_type == ECL_SMSPEC_INVALID_VAR) { + switch(var[0]) { + case('A'): + var_type = ECL_SMSPEC_AQUIFER_VAR; + break; + case('B'): + var_type = ECL_SMSPEC_BLOCK_VAR; + break; + case('C'): + var_type = ECL_SMSPEC_COMPLETION_VAR; + break; + case('F'): + var_type = ECL_SMSPEC_FIELD_VAR; + break; + case('G'): + var_type = ECL_SMSPEC_GROUP_VAR; + break; + case('L'): + switch(var[1]) { + case('B'): + var_type = ECL_SMSPEC_LOCAL_BLOCK_VAR; + break; + case('C'): + var_type = ECL_SMSPEC_LOCAL_COMPLETION_VAR; + break; + case('W'): + var_type = ECL_SMSPEC_LOCAL_WELL_VAR; + break; + default: + /* + The documentation explicitly mentions keywords starting with + LB, LC and LW as special types, but keywords starting with + L[^BCW] are also valid. These come in the misceallaneous + category; at least the LLINEAR keyword is an example of such + a keyword. + */ + var_type = ECL_SMSPEC_MISC_VAR; + } + break; + case('N'): + var_type = ECL_SMSPEC_NETWORK_VAR; + break; + case('R'): + { + /* + The distinction between regular region variables and region-to-region + variables is less than clear. The manual prescribes a rule based on + the characters at position 3 and 4 or 4 and 5. + + R*FT* => Region to region + R**FT* => Region to region + R*FR* => Region to region + R**FR* => Region to region + + RORFR => exception - normal region var. + + + In addition older test cases seem to imply the following extra + rules/exceptions: + + RNLF: region to region variable + RxF : region to region variable + + The manual does not seem to offer any backup for these extra rules. + */ + + if (strlen(var) == 3 && var[2] == 'F') { + var_type = ECL_SMSPEC_REGION_2_REGION_VAR; + break; + } + + if (util_string_equal( var , "RNLF")) { + var_type = ECL_SMSPEC_REGION_2_REGION_VAR; + break; + } + + if (util_string_equal(var, "RORFR")) { + var_type = ECL_SMSPEC_REGION_VAR; + break; + } + + if (strlen(var) >= 4) { + if (var[2] == 'F') { + if (var[3] == 'T' || var[3] == 'R') { + var_type = ECL_SMSPEC_REGION_2_REGION_VAR; + break; + } + } + } + + if (strlen(var) >= 5) { + if (var[3] == 'F') { + if (var[4] == 'T' || var[4] == 'R') { + var_type = ECL_SMSPEC_REGION_2_REGION_VAR; + break; + } + } + } + + var_type = ECL_SMSPEC_REGION_VAR; + } + break; + case('S'): + var_type = ECL_SMSPEC_SEGMENT_VAR; + break; + case('W'): + var_type = ECL_SMSPEC_WELL_VAR; + break; + default: + /* + It is unfortunately impossible to recognize an error situation - + the rest just goes in "other" variables. + */ + var_type = ECL_SMSPEC_MISC_VAR; + } + } + + return var_type; } -static bool smspec_node_type_supported(ecl_smspec_var_type var_type) { - if (var_type == ECL_SMSPEC_NETWORK_VAR) - return false; - return true; -} + /*****************************************************************/ @@ -123,9 +267,6 @@ static bool smspec_node_type_supported(ecl_smspec_var_type var_type) { #define ECL_SUM_KEYFMT_SEGMENT "%s%s%s%s%d" #define ECL_SUM_KEYFMT_LOCAL_WELL "%s%s%s%s%s" -UTIL_SAFE_CAST_FUNCTION( smspec_node , SMSPEC_TYPE_ID ) -static UTIL_SAFE_CAST_FUNCTION_CONST( smspec_node , SMSPEC_TYPE_ID ) - std::string smspec_alloc_block_num_key( const char * join_string , const std::string& keyword , int num) { return ecl::util::string_format(ECL_SUM_KEYFMT_BLOCK_NUM, @@ -188,7 +329,7 @@ std::string smspec_alloc_completion_ijk_key( const char * join_string , const st join_string , i , j , k ); else - return std::string(); + return NULL; } @@ -202,7 +343,7 @@ std::string smspec_alloc_completion_num_key( const char * join_string , const st join_string , num ); else - return std::string(); + return NULL; } /* @@ -265,7 +406,7 @@ std::string smspec_alloc_segment_key( const char * join_string , const std::stri join_string , num ); else - return std::string(); + return NULL; } @@ -278,7 +419,7 @@ std::string smspec_alloc_local_well_key( const char * join_string , const std::s join_string , wgname.c_str()); else - return std::string(); + return NULL; } std::string smspec_alloc_local_completion_key( const char * join_string, const std::string& keyword , const std::string& lgr_name , const std::string& wgname , int i , int j , int k) { @@ -292,32 +433,15 @@ std::string smspec_alloc_local_completion_key( const char * join_string, const s join_string , i,j,k); else - return std::string(); + return NULL; } /*****************************************************************/ -static void smspec_node_set_keyword( smspec_node_type * smspec_node , const std::string& keyword ) { - // ECLIPSE Standard: Max eight characters - everything beyond is silently dropped - // This function can __ONLY__ be called on time; run-time chaning of keyword is not - // allowed. - if (smspec_node->keyword.size() == 0) - smspec_node->keyword = keyword; - else - util_abort("%s: fatal error - attempt to change keyword runtime detected - aborting\n",__func__); -} - - -static void smspec_node_set_invalid_flags( smspec_node_type * smspec_node) { - smspec_node->rate_variable = false; - smspec_node->total_variable = false; - smspec_node->historical = false; -} - - bool smspec_node_identify_rate(const char * keyword) { - const char *rate_vars[] = {"OPR" , "GPR" , "WPR" , "LPR", "OIR", "GIR", "WIR", "LIR", "GOR" , "WCT"}; + const char *rate_vars[] = {"OPR" , "GPR" , "WPR" , "LPR", "OIR", "GIR", "WIR", "LIR", "GOR" , "WCT", + "OFR" , "GFR" , "WFR"}; int num_rate_vars = sizeof( rate_vars ) / sizeof( rate_vars[0] ); bool is_rate = false; int ivar; @@ -369,104 +493,76 @@ bool smspec_node_identify_total(const char * keyword, ecl_smspec_var_type var_ty } } } + else if (var_type == ECL_SMSPEC_SEGMENT_VAR) { + const char *total_vars[] = {"OFT", "GFT", "WFT"}; + const char *var_substring = &keyword[1]; + const size_t num_total_vars = sizeof(total_vars) / sizeof(total_vars[0]); + for (size_t ivar = 0; ivar < num_total_vars; ivar++) + if (strncmp(total_vars[ivar], var_substring, strlen(total_vars[ivar])) == 0) { + is_total = true; + break; + } + } return is_total; } -static void smspec_node_set_flags( smspec_node_type * smspec_node) { - /* - Check if this is a rate variabel - that info is used when - interpolating results to true_time between ministeps. - */ - smspec_node->rate_variable = smspec_node_identify_rate(smspec_node->keyword.c_str()); - if (smspec_node->keyword.back() == 'H') - smspec_node->historical = true; - smspec_node->total_variable = smspec_node_identify_total(smspec_node->keyword.c_str(), smspec_node->var_type); +namespace ecl { + + + +float smspec_node::get_default() const { + return this->default_value; } -/** - It is possible to change the default value of an smspec node - runtime, but observe that the new value will only be applied to the - new timesteps you add after the change. Already created timesteps - will not be updated if the default value is changed. + +void smspec_node::set_lgr_ijk( int lgr_i , int lgr_j , int lgr_k) { + lgr_ijk[0] = lgr_i; + lgr_ijk[1] = lgr_j; + lgr_ijk[2] = lgr_k; +} + + +/* + Observe that field vectors like 'FOPT' and 'FOPR' will have the string 'FIELD' + in the 'WGNAME' vector, that is not internalized here. */ -void smspec_node_set_default( smspec_node_type * smspec_node , float default_value) { - smspec_node->default_value = default_value; + +void smspec_node::set_wgname(const char * wgname) { + if (!wgname) + return; + + if (IS_DUMMY_WELL(wgname)) + return; + + if (this->var_type == ECL_SMSPEC_WELL_VAR || + this->var_type == ECL_SMSPEC_GROUP_VAR || + this->var_type == ECL_SMSPEC_COMPLETION_VAR || + this->var_type == ECL_SMSPEC_SEGMENT_VAR || + this->var_type == ECL_SMSPEC_LOCAL_WELL_VAR) + this->wgname = wgname; } - -float smspec_node_get_default( const smspec_node_type * smspec_node ) { - return smspec_node->default_value; -} - - -smspec_node_type * smspec_node_alloc_new(int params_index, float default_value) { - smspec_node_type * node = new smspec_node_type(); - - UTIL_TYPE_ID_INIT( node , SMSPEC_TYPE_ID); - node->params_index = params_index; - smspec_node_set_default( node , default_value ); - - node->var_type = ECL_SMSPEC_INVALID_VAR; - smspec_node_set_invalid_flags( node ); - return node; // This is NOT usable -} - - -static void smspec_node_set_wgname( smspec_node_type * index , const char * wgname ) { - index->wgname = wgname; -} - - - -static void smspec_node_set_lgr_name( smspec_node_type * index , const std::string& lgr_name ) { - index->lgr_name = lgr_name; -} - - -static void smspec_node_set_lgr_ijk( smspec_node_type * index , int lgr_i , int lgr_j , int lgr_k) { - index->lgr_ijk[0] = lgr_i; - index->lgr_ijk[1] = lgr_j; - index->lgr_ijk[2] = lgr_k; -} - - -static void smspec_node_init_num( smspec_node_type * node , ecl_smspec_var_type var_type) { - switch( node->var_type ) { - case(ECL_SMSPEC_WELL_VAR): - node->num = SMSPEC_NUMS_WELL; - break; - case(ECL_SMSPEC_GROUP_VAR): - node->num = SMSPEC_NUMS_GROUP; - break; - case(ECL_SMSPEC_FIELD_VAR): - node->num = SMSPEC_NUMS_FIELD; - break; - default: - node->num = SMSPEC_NUMS_INVALID; - } -} -static void smspec_node_set_num( smspec_node_type * index , const int grid_dims[3] , int num) { - if (num == SMSPEC_NUMS_INVALID) +void smspec_node::set_num( const int * grid_dims , int num_) { + if (num_ == SMSPEC_NUMS_INVALID) util_abort("%s: explicitly trying to set nums == SMSPEC_NUMS_INVALID - seems like a bug?!\n",__func__); + this->num = num_; + if ((var_type == ECL_SMSPEC_COMPLETION_VAR) || (var_type == ECL_SMSPEC_BLOCK_VAR)) { + int global_index = this->num - 1; + this->ijk[2] = global_index / ( grid_dims[0] * grid_dims[1] ); global_index -= this->ijk[2] * (grid_dims[0] * grid_dims[1]); + this->ijk[1] = global_index / grid_dims[0] ; global_index -= this->ijk[1] * grid_dims[0]; + this->ijk[0] = global_index; - index->num = num; - if ((index->var_type == ECL_SMSPEC_COMPLETION_VAR) || (index->var_type == ECL_SMSPEC_BLOCK_VAR)) { - int global_index = num - 1; - index->ijk[2] = global_index / ( grid_dims[0] * grid_dims[1] ); global_index -= index->ijk[2] * (grid_dims[0] * grid_dims[1]); - index->ijk[1] = global_index / grid_dims[0] ; global_index -= index->ijk[1] * grid_dims[0]; - index->ijk[0] = global_index; - - index->ijk[0] += 1; - index->ijk[1] += 1; - index->ijk[2] += 1; + this->ijk[0] += 1; + this->ijk[1] += 1; + this->ijk[2] += 1; } } -static void smspec_node_decode_R1R2( const smspec_node_type * smspec_node , int * r1 , int * r2) { - if (smspec_node->var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { - *r1 = smspec_node->num % 32768; - *r2 = ((smspec_node->num - (*r1)) / 32768)-10; +void smspec_node::decode_R1R2(int * r1 , int * r2) const { + if (var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { + *r1 = this->num % 32768; + *r2 = ((this->num - (*r1)) / 32768)-10; } else { *r1 = -1; *r2 = -1; @@ -485,78 +581,67 @@ static void smspec_node_decode_R1R2( const smspec_node_type * smspec_node , int */ -static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const char * key_join_string) { - switch( smspec_node->var_type) { +void smspec_node::set_gen_keys( const char* key_join_string_) { + switch( var_type) { case(ECL_SMSPEC_COMPLETION_VAR): // KEYWORD:WGNAME:NUM - smspec_node->gen_key1 = smspec_alloc_completion_ijk_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]); - smspec_node->gen_key2 = smspec_alloc_completion_num_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num); + gen_key1 = smspec_alloc_completion_ijk_key( key_join_string_ , keyword , wgname , ijk[0], ijk[1], ijk[2]); + gen_key2 = smspec_alloc_completion_num_key( key_join_string_ , keyword , wgname , num); break; case(ECL_SMSPEC_FIELD_VAR): // KEYWORD - smspec_node->gen_key1 = util_alloc_string_copy( smspec_node->keyword.c_str() ); + gen_key1 = keyword; break; case(ECL_SMSPEC_GROUP_VAR): // KEYWORD:WGNAME - smspec_node->gen_key1 = smspec_alloc_group_key( key_join_string , smspec_node->keyword , smspec_node->wgname); + gen_key1 = smspec_alloc_group_key( key_join_string_ , keyword , wgname); break; case(ECL_SMSPEC_WELL_VAR): // KEYWORD:WGNAME - smspec_node->gen_key1 = smspec_alloc_well_key( key_join_string , smspec_node->keyword , smspec_node->wgname); + gen_key1 = smspec_alloc_well_key( key_join_string_ , keyword , wgname); break; case(ECL_SMSPEC_REGION_VAR): // KEYWORD:NUM - smspec_node->gen_key1 = smspec_alloc_region_key( key_join_string , smspec_node->keyword , smspec_node->num); + gen_key1 = smspec_alloc_region_key( key_join_string_ , keyword , num); break; case (ECL_SMSPEC_SEGMENT_VAR): // KEYWORD:WGNAME:NUM - smspec_node->gen_key1 = smspec_alloc_segment_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num); + gen_key1 = smspec_alloc_segment_key( key_join_string_ , keyword , wgname , num); break; case(ECL_SMSPEC_REGION_2_REGION_VAR): // KEYWORDS:RXF:NUM and RXF:R1-R2 { int r1,r2; - smspec_node_decode_R1R2( smspec_node , &r1 , &r2); - smspec_node->gen_key1 = smspec_alloc_region_2_region_r1r2_key( key_join_string , smspec_node->keyword , r1, r2); + decode_R1R2( &r1 , &r2); + gen_key1 = smspec_alloc_region_2_region_r1r2_key( key_join_string_ , keyword , r1, r2); } - smspec_node->gen_key2 = smspec_alloc_region_2_region_num_key( key_join_string , smspec_node->keyword , smspec_node->num); + gen_key2 = smspec_alloc_region_2_region_num_key( key_join_string_ , keyword , num); break; case(ECL_SMSPEC_MISC_VAR): // KEYWORD /* Misc variable - i.e. date or CPU time ... */ - smspec_node->gen_key1 = smspec_node->keyword; + gen_key1 = keyword; break; case(ECL_SMSPEC_BLOCK_VAR): // KEYWORD:NUM - smspec_node->gen_key1 = smspec_alloc_block_ijk_key( key_join_string , smspec_node->keyword , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]); - smspec_node->gen_key2 = smspec_alloc_block_num_key( key_join_string , smspec_node->keyword , smspec_node->num); + gen_key1 = smspec_alloc_block_ijk_key( key_join_string_ , keyword , ijk[0], ijk[1], ijk[2]); + gen_key2 = smspec_alloc_block_num_key( key_join_string_ , keyword , num); break; case(ECL_SMSPEC_LOCAL_WELL_VAR): /** KEYWORD:LGR:WGNAME */ - smspec_node->gen_key1 = smspec_alloc_local_well_key( key_join_string , smspec_node->keyword , smspec_node->lgr_name , smspec_node->wgname); + gen_key1 = smspec_alloc_local_well_key( key_join_string_ , keyword , lgr_name , wgname); break; case(ECL_SMSPEC_LOCAL_BLOCK_VAR): /* KEYWORD:LGR:i,j,k */ - smspec_node->gen_key1 = smspec_alloc_local_block_key( key_join_string , - smspec_node->keyword , - smspec_node->lgr_name , - smspec_node->lgr_ijk[0] , - smspec_node->lgr_ijk[1] , - smspec_node->lgr_ijk[2] ); + gen_key1 = smspec_alloc_local_block_key( key_join_string_ , keyword , lgr_name , lgr_ijk[0] , lgr_ijk[1] , lgr_ijk[2] ); break; case(ECL_SMSPEC_LOCAL_COMPLETION_VAR): /* KEYWORD:LGR:WELL:i,j,k */ - smspec_node->gen_key1 = smspec_alloc_local_completion_key( key_join_string , - smspec_node->keyword , - smspec_node->lgr_name , - smspec_node->wgname , - smspec_node->lgr_ijk[0], - smspec_node->lgr_ijk[1], - smspec_node->lgr_ijk[2]); + gen_key1 = smspec_alloc_local_completion_key( key_join_string_ , keyword , lgr_name , wgname , lgr_ijk[0], lgr_ijk[1], lgr_ijk[2]); break; case(ECL_SMSPEC_AQUIFER_VAR): - smspec_node->gen_key1 = smspec_alloc_aquifer_key( key_join_string , smspec_node->keyword , smspec_node->num); + gen_key1 = smspec_alloc_aquifer_key( key_join_string_ , keyword , num); break; default: util_abort("%s: internal error - should not be here? \n" , __func__); @@ -564,123 +649,79 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha } +/* + Observe the following: -static void smspec_node_common_init( smspec_node_type * node , ecl_smspec_var_type var_type , const char * keyword , const std::string& unit ) { - if (node->var_type == ECL_SMSPEC_INVALID_VAR) { - smspec_node_set_unit( node , unit.c_str() ); - smspec_node_set_keyword( node , keyword); - node->var_type = var_type; - smspec_node_set_flags( node ); - smspec_node_init_num( node , var_type ); - } else - util_abort("%s: trying to re-init smspec node with keyword:%s - invalid \n",__func__ , keyword ); -} + 1. There are many legitimate value types here which we do not handle, then we + just return false. + 2. Observe that the LGR variables are not thoroughly checked; the only check + is that the well is not the dummy well. Experience has shown that there has + not been problems with SMSPEC files with invalid LGR and LGRIJK values; + that is therefor just assumed to be right. -static bool smspec_node_init__( smspec_node_type * smspec_node, - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num) { +*/ - bool initOK = true; +ecl_smspec_var_type smspec_node::valid_type(const char * keyword, const char * wgname, int num) { + auto var_type = smspec_node::identify_var_type(keyword); - smspec_node_common_init( smspec_node , var_type , keyword , unit ); - switch (var_type) { - case(ECL_SMSPEC_COMPLETION_VAR): - /* Completion variable : WGNAME & NUM */ - smspec_node_set_num( smspec_node , grid_dims , num ); - smspec_node_set_wgname( smspec_node , wgname ); - if (num < 0) - initOK = false; - break; - case(ECL_SMSPEC_GROUP_VAR): - /* Group variable : WGNAME */ - smspec_node_set_wgname( smspec_node , wgname ); - break; - case(ECL_SMSPEC_WELL_VAR): - /* Well variable : WGNAME */ - smspec_node_set_wgname( smspec_node , wgname ); - break; - case(ECL_SMSPEC_SEGMENT_VAR): - smspec_node_set_wgname( smspec_node , wgname ); - smspec_node_set_num( smspec_node , grid_dims , num ); - if (num < 0) - initOK = false; - break; - case(ECL_SMSPEC_FIELD_VAR): - /* Field variable : */ - /* Fully initialized with the smspec_common_init() function */ - break; - case(ECL_SMSPEC_REGION_VAR): - /* Region variable : NUM */ - smspec_node_set_num( smspec_node , grid_dims , num ); - break; - case(ECL_SMSPEC_REGION_2_REGION_VAR): - /* Region 2 region variable : NUM */ - smspec_node_set_num( smspec_node , grid_dims , num ); - break; - case(ECL_SMSPEC_BLOCK_VAR): - /* A block variable : NUM*/ - smspec_node_set_num( smspec_node , grid_dims , num ); - break; - case(ECL_SMSPEC_MISC_VAR): - /* Misc variable : */ + if (var_type == ECL_SMSPEC_MISC_VAR) + return var_type; + + if (var_type == ECL_SMSPEC_FIELD_VAR) + return var_type; + + if (var_type == ECL_SMSPEC_LOCAL_BLOCK_VAR) + return var_type; + + if (var_type == ECL_SMSPEC_WELL_VAR || + var_type == ECL_SMSPEC_GROUP_VAR || + var_type == ECL_SMSPEC_LOCAL_WELL_VAR || + var_type == ECL_SMSPEC_LOCAL_COMPLETION_VAR) { + if (IS_DUMMY_WELL(wgname)) + return ECL_SMSPEC_INVALID_VAR; /* - For some keywords the SMSPEC files generated by Eclipse have a - non zero NUMS value although; it seems that value is required - for the generatd summaryfiles to display nicely in - e.g. S3GRAF. + In most cases the dummy well ':+:+:+:+' is used in situations where a + well/group name does not make sense; however we have also encountered the + blank string as an invalid well name; when this is trimmed we get NULL (C) + or "" (C++). */ - if (util_string_equal( keyword ,SMSPEC_TIME_KEYWORD)) - smspec_node_set_num( smspec_node , grid_dims , SMSPEC_TIME_NUMS_VALUE ); + if (!wgname) + return ECL_SMSPEC_INVALID_VAR; - if (util_string_equal( keyword ,SMSPEC_YEARS_KEYWORD)) - smspec_node_set_num( smspec_node , grid_dims , SMSPEC_YEARS_NUMS_VALUE ); + if (strlen(wgname) == 0) + return ECL_SMSPEC_INVALID_VAR; - break; - case(ECL_SMSPEC_AQUIFER_VAR): - smspec_node_set_num( smspec_node , grid_dims , num ); - break; - default: - /* Lots of legitimate alternatives which are not internalized. */ - initOK = false; - break; + return var_type; } - if (initOK) - smspec_node_set_gen_keys( smspec_node , key_join_string ); + if (var_type == ECL_SMSPEC_COMPLETION_VAR || var_type == ECL_SMSPEC_SEGMENT_VAR) { + if (IS_DUMMY_WELL(wgname)) + return ECL_SMSPEC_INVALID_VAR; - return initOK; + if (num < 0) + return ECL_SMSPEC_INVALID_VAR; + + return var_type; + } + + if (var_type == ECL_SMSPEC_REGION_VAR || + var_type == ECL_SMSPEC_REGION_2_REGION_VAR || + var_type == ECL_SMSPEC_BLOCK_VAR || + var_type == ECL_SMSPEC_AQUIFER_VAR) { + + if (num < 0) + return ECL_SMSPEC_INVALID_VAR; + + return var_type; + } + + return ECL_SMSPEC_INVALID_VAR; } -/* - This function should be removed from the public API. -*/ -void smspec_node_init( smspec_node_type * smspec_node, - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num) { - smspec_node_init__(smspec_node, - var_type, - wgname, - keyword, - unit, - key_join_string, - grid_dims, - num); - -} /** This function will allocate a smspec_node instance, and initialize @@ -696,15 +737,83 @@ void smspec_node_init( smspec_node_type * smspec_node, ecl_smspec_fread_header() functions in addition. UGGGLY */ +smspec_node::smspec_node(int param_index, const char * keyword, int num, const char * unit, const int grid_dims[3], float default_value, const char * key_join_string) + : smspec_node(param_index, + keyword, + nullptr, + num, + unit, + grid_dims, + default_value, + key_join_string) +{ +} + +smspec_node::smspec_node(int param_index, const char * keyword, int num, const char * unit, float default_value, const char * key_join_string) + : smspec_node(param_index, + keyword, + nullptr, + num, + unit, + nullptr, + default_value, + key_join_string) +{ +} -smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num , int param_index, float default_value) { + +smspec_node::smspec_node(int param_index, const char * keyword, const char * wgname, const char * unit, float default_value, const char * key_join_string) + : smspec_node(param_index, + keyword, + wgname, + nums_unused, + unit, + nullptr, + default_value, + key_join_string) +{ +} + +smspec_node::smspec_node(int param_index, const char * keyword, const char * wgname, int num, const char * unit, float default_value, const char * key_join_string) + : smspec_node(param_index, + keyword, + wgname, + num, + unit, + nullptr, + default_value, + key_join_string) +{} + + +smspec_node::smspec_node(int param_index, const char * keyword, const char * unit, float default_value) + : smspec_node(param_index, + keyword, + nullptr, + nums_unused, + unit, + nullptr, + default_value, + nullptr) +{ +} + +//copy constructor with a new id +smspec_node::smspec_node(const smspec_node& node, int param_index) +{ + *this = node; + this->params_index = param_index; +} + +smspec_node::smspec_node(int param_index, + const char * keyword, + const char * wgname , + int num, + const char * unit , + const int grid_dims[3] , + float default_value, + const char * key_join_string) { /* Well and group names in the wgname parameter is quite messy. The situation is as follows: @@ -734,132 +843,129 @@ smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , at all, e.g. like "FOPT" - the wgname input value is ignored completely. */ + this->var_type = this->valid_type(keyword, wgname, num); + if (this->var_type == ECL_SMSPEC_INVALID_VAR) + throw std::invalid_argument("Could not construct smspec_node from this input."); - if (smspec_node_need_wgname(var_type) && IS_DUMMY_WELL(wgname)) - return NULL; + this->params_index = param_index; + this->default_value = default_value; + this->keyword = keyword; + this->num = num; + this->unit = unit; + this->rate_variable = smspec_node_identify_rate(this->keyword.c_str()); + this->total_variable = smspec_node_identify_total(this->keyword.c_str(), this->var_type); + this->historical = (this->keyword.back() == 'H'); + this->set_wgname( wgname ); - if (!smspec_node_type_supported(var_type)) - return NULL; - - /* - TODO: The alloc_new and init functions should be joined in one function. - */ - smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value ); - bool initOK = smspec_node_init__( smspec_node , var_type , wgname , keyword , unit , key_join_string , grid_dims, num); - if (!initOK) { - smspec_node_free(smspec_node); - smspec_node = NULL; - } - - return smspec_node; -} - - - -static void smspec_node_init_lgr( smspec_node_type * smspec_node , - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * lgr , - const char * key_join_string , - int lgr_i, int lgr_j , int lgr_k - ) { - bool initOK = true; - bool wgnameOK = true; - if ((wgname != NULL) && (IS_DUMMY_WELL(wgname))) - wgnameOK = false; - - smspec_node_common_init( smspec_node , var_type , keyword , unit ); - switch (var_type) { - case(ECL_SMSPEC_LOCAL_WELL_VAR): - smspec_node_set_wgname( smspec_node , wgname ); - smspec_node_set_lgr_name( smspec_node , lgr ); - initOK = wgnameOK; + switch (this->var_type) { + case(ECL_SMSPEC_COMPLETION_VAR): + /* Completion variable : WGNAME & NUM */ + set_num( grid_dims , num ); break; - case(ECL_SMSPEC_LOCAL_BLOCK_VAR): - smspec_node_set_lgr_name( smspec_node , lgr ); - smspec_node_set_lgr_ijk( smspec_node , lgr_i, lgr_j , lgr_k ); + case(ECL_SMSPEC_GROUP_VAR): + /* Group variable : WGNAME */ break; - case(ECL_SMSPEC_LOCAL_COMPLETION_VAR): - smspec_node_set_lgr_name( smspec_node , lgr ); - smspec_node_set_wgname( smspec_node , wgname ); - smspec_node_set_lgr_ijk( smspec_node , lgr_i, lgr_j , lgr_k ); - initOK = wgnameOK; + case(ECL_SMSPEC_WELL_VAR): + /* Well variable : WGNAME */ + break; + case(ECL_SMSPEC_SEGMENT_VAR): + set_num( grid_dims , num ); + break; + case(ECL_SMSPEC_FIELD_VAR): + /* Field variable : */ + /* Fully initialized with the smspec_common_init() function */ + break; + case(ECL_SMSPEC_REGION_VAR): + /* Region variable : NUM */ + set_num( grid_dims , num ); + break; + case(ECL_SMSPEC_REGION_2_REGION_VAR): + /* Region 2 region variable : NUM */ + set_num( grid_dims , num ); + break; + case(ECL_SMSPEC_BLOCK_VAR): + /* A block variable : NUM*/ + set_num( grid_dims , num ); + break; + case(ECL_SMSPEC_MISC_VAR): + /* Misc variable : */ + + /* + For some keywords the SMSPEC files generated by Eclipse have a + non zero NUMS value although; it seems that value is required + for the generatd summaryfiles to display nicely in + e.g. S3GRAF. + */ + + if (this->keyword == std::string(SMSPEC_TIME_KEYWORD)) + set_num( grid_dims , SMSPEC_TIME_NUMS_VALUE ); + + if (this->keyword == std::string(SMSPEC_YEARS_KEYWORD)) + set_num( grid_dims , SMSPEC_YEARS_NUMS_VALUE ); + + break; + case(ECL_SMSPEC_AQUIFER_VAR): + set_num( grid_dims , num ); break; default: - util_abort("%s: internal error: in LGR function with non-LGR keyword:%s \n",__func__ , keyword); + throw std::invalid_argument("Should not be here ... "); + break; + } + set_gen_keys( key_join_string ); +} + +smspec_node::smspec_node( int param_index_, + const char * keyword_ , + const char * wgname_ , + const char * unit_ , + const char * lgr_ , + int lgr_i, int lgr_j , int lgr_k, + float default_value_, + const char * key_join_string_) { + + this->var_type = this->valid_type(keyword_, wgname_, -1); + if (this->var_type == ECL_SMSPEC_INVALID_VAR) + throw std::invalid_argument("Could not construct smspec_node from this input."); + + this->params_index = param_index_; + this->default_value = default_value_; + this->keyword = keyword_; + this->wgname = wgname_; + this->unit = unit_; + this->rate_variable = smspec_node_identify_rate(this->keyword.c_str()); + this->total_variable = smspec_node_identify_total(this->keyword.c_str(), this->var_type); + this->historical = (this->keyword.back() == 'H'); + this->lgr_name = lgr_; + this->num = nums_unused; + + switch (this->var_type) { + case(ECL_SMSPEC_LOCAL_WELL_VAR): + break; + case(ECL_SMSPEC_LOCAL_BLOCK_VAR): + set_lgr_ijk( lgr_i, lgr_j , lgr_k ); + break; + case(ECL_SMSPEC_LOCAL_COMPLETION_VAR): + set_lgr_ijk( lgr_i, lgr_j , lgr_k ); + break; + default: + throw std::invalid_argument("Should not be here .... "); } - if (initOK) - smspec_node_set_gen_keys( smspec_node , key_join_string ); + set_gen_keys( key_join_string_ ); } -smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * lgr , - const char * key_join_string , - int lgr_i, int lgr_j , int lgr_k, - int param_index , float default_value) { - - smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value ); - smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , unit , lgr , key_join_string , lgr_i, lgr_j , lgr_k); - return smspec_node; -} - -smspec_node_type* smspec_node_alloc_copy( const smspec_node_type* node ) { - - if( !node ) return NULL; - - { - smspec_node_type * copy = new smspec_node_type(); - UTIL_TYPE_ID_INIT( copy, SMSPEC_TYPE_ID ); - copy->gen_key1 = node->gen_key1; - copy->gen_key2 = node->gen_key2; - copy->var_type = node->var_type; - copy->wgname = node->wgname; - copy->keyword = node->keyword; - copy->unit = node->unit; - copy->num = node->num; - copy->ijk = node->ijk; - copy->lgr_name = node->lgr_name; - copy->lgr_ijk = node->lgr_ijk; - - copy->rate_variable = node->rate_variable; - copy->total_variable = node->total_variable; - copy->historical = node->historical; - copy->params_index = node->params_index; - copy->default_value = node->default_value; - return copy; - } -} - -void smspec_node_free( smspec_node_type * index ) { - delete index; -} - -void smspec_node_free__( void * arg ) { - smspec_node_type * node = smspec_node_safe_cast( arg ); - smspec_node_free( node ); -} - /*****************************************************************/ - - -int smspec_node_get_params_index( const smspec_node_type * smspec_node ) { - return smspec_node->params_index; +int smspec_node::get_params_index() const { + return this->params_index; } - -void smspec_node_set_params_index( smspec_node_type * smspec_node , int params_index) { - smspec_node->params_index = params_index; -} +// void smspec_node::set_params_index( int params_index_) { + // this->params_index = params_index_; +// } namespace { @@ -873,69 +979,60 @@ namespace { } -const char * smspec_node_get_gen_key1( const smspec_node_type * smspec_node) { - return get_cstring( smspec_node->gen_key1 ); + +const char * smspec_node::get_gen_key1() const { + return get_cstring( this->gen_key1 ); } -const char * smspec_node_get_gen_key2( const smspec_node_type * smspec_node) { - return get_cstring( smspec_node->gen_key2 ); +const char * smspec_node::get_gen_key2() const { + return get_cstring( this->gen_key2 ); } - -const char * smspec_node_get_wgname( const smspec_node_type * smspec_node) { - return get_cstring( smspec_node->wgname ); +const char * smspec_node::get_wgname() const { + return get_cstring( this->wgname ); } -const char * smspec_node_get_keyword( const smspec_node_type * smspec_node) { - return get_cstring( smspec_node->keyword ); +const char * smspec_node::get_keyword() const { + return get_cstring( this->keyword ); } - - -ecl_smspec_var_type smspec_node_get_var_type( const smspec_node_type * smspec_node) { - return smspec_node->var_type; +ecl_smspec_var_type smspec_node::get_var_type() const { + return this->var_type; } -int smspec_node_get_num( const smspec_node_type * smspec_node) { - return smspec_node->num; +int smspec_node::get_num() const { + return this->num; } -bool smspec_node_is_rate( const smspec_node_type * smspec_node ) { - return smspec_node->rate_variable; +bool smspec_node::is_rate() const { + return this->rate_variable; } - -bool smspec_node_is_total( const smspec_node_type * smspec_node ){ - return smspec_node->total_variable; +bool smspec_node::is_total() const { + return this->total_variable; } -bool smspec_node_is_historical( const smspec_node_type * smspec_node ){ - return smspec_node->historical; +bool smspec_node::is_historical() const { + return this->historical; } -const char * smspec_node_get_unit( const smspec_node_type * smspec_node) { - return smspec_node->unit.c_str(); -} - -void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit) { - // ECLIPSE Standard: Max eight characters - everything beyond is silently dropped - std::string tmp = unit; - smspec_node->unit = tmp.substr(0,8); +const char * smspec_node::get_unit() const { + return this->unit.c_str(); } // Will be garbage for smspec_nodes which do not have i,j,k -const int* smspec_node_get_ijk( const smspec_node_type * smspec_node ) { - return smspec_node->ijk.data(); +const std::array& smspec_node::get_ijk() const { + return this->ijk; } // Will be NULL for smspec_nodes which are not related to an LGR. -const char* smspec_node_get_lgr_name( const smspec_node_type * smspec_node ) { - return smspec_node->lgr_name.c_str(); +const char * smspec_node::get_lgr_name() const { + return get_cstring(this->lgr_name); } // Will be garbage for smspec_nodes which are not related to an LGR. -const int* smspec_node_get_lgr_ijk( const smspec_node_type * smspec_node ) { - return smspec_node->lgr_ijk.data(); +const std::array& smspec_node::get_lgr_ijk() const { + return this->lgr_ijk; } /* @@ -943,41 +1040,41 @@ const int* smspec_node_get_lgr_ijk( const smspec_node_type * smspec_node ) { of type ECL_SMSPEC_REGION_2_REGION_VAR. */ -int smspec_node_get_R1( const smspec_node_type * smspec_node ) { - if (smspec_node->var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { +int smspec_node::get_R1() const { + if (var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { int r1,r2; - smspec_node_decode_R1R2( smspec_node , &r1 , &r2); + decode_R1R2( &r1 , &r2); return r1; } else return -1; } -int smspec_node_get_R2( const smspec_node_type * smspec_node ) { - if (smspec_node->var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { +int smspec_node::get_R2() const { + if (var_type == ECL_SMSPEC_REGION_2_REGION_VAR) { int r1,r2; - smspec_node_decode_R1R2( smspec_node , &r1 , &r2); + decode_R1R2( &r1 , &r2); return r2; } else return -1; } -bool smspec_node_need_nums( const smspec_node_type * smspec_node ) { +bool smspec_node::need_nums() const { /* Check if this node needs the nums field; if at least one of the nodes need the NUMS field must be stored when writing a SMSPEC file. */ { - if (smspec_node->var_type == ECL_SMSPEC_COMPLETION_VAR || - smspec_node->var_type == ECL_SMSPEC_SEGMENT_VAR || - smspec_node->var_type == ECL_SMSPEC_REGION_VAR || - smspec_node->var_type == ECL_SMSPEC_REGION_2_REGION_VAR || - smspec_node->var_type == ECL_SMSPEC_BLOCK_VAR || - smspec_node->var_type == ECL_SMSPEC_AQUIFER_VAR) + if (this->var_type == ECL_SMSPEC_COMPLETION_VAR || + this->var_type == ECL_SMSPEC_SEGMENT_VAR || + this->var_type == ECL_SMSPEC_REGION_VAR || + this->var_type == ECL_SMSPEC_REGION_2_REGION_VAR || + this->var_type == ECL_SMSPEC_BLOCK_VAR || + this->var_type == ECL_SMSPEC_AQUIFER_VAR) return true; else { - if (smspec_node->num == SMSPEC_NUMS_INVALID) + if (this->num == SMSPEC_NUMS_INVALID) return false; else return true; @@ -986,46 +1083,22 @@ bool smspec_node_need_nums( const smspec_node_type * smspec_node ) { } -void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream) { - fprintf(stream, "KEYWORD: %s \n",smspec_node->keyword.c_str()); - fprintf(stream, "WGNAME : %s \n",smspec_node->wgname.c_str()); - fprintf(stream, "UNIT : %s \n",smspec_node->unit.c_str()); - fprintf(stream, "TYPE : %d \n",smspec_node->var_type); - fprintf(stream, "NUM : %d \n\n",smspec_node->num); -} - - -static bool smspec_node_equal_MISC( const smspec_node_type * node1, const smspec_node_type * node2) { - return node1->keyword == node2->keyword; +void smspec_node::fprintf__( FILE * stream) const { + fprintf(stream, "KEYWORD: %s \n", this->keyword.c_str()); + fprintf(stream, "WGNAME : %s \n", this->wgname.c_str()); + fprintf(stream, "UNIT : %s \n", this->unit.c_str()); + fprintf(stream, "TYPE : %d \n", this->var_type); + fprintf(stream, "NUM : %d \n\n", this->num); } +namespace { /* MISC variables are generally sorted to the end of the list, but some special case variables come at the very beginning. */ -static int smspec_node_cmp_MISC( const smspec_node_type * node1, const smspec_node_type * node2) { - static const std::set early_vars = {"TIME", "DAYS", "DAY", "MONTH", "YEAR", "YEARS"}; - - if (smspec_node_equal_MISC( node1, node2) ) - return 0; - - bool node1_early = !( early_vars.find(node1->keyword) == early_vars.end() ); - bool node2_early = !( early_vars.find(node2->keyword) == early_vars.end() ); - - - if (node1_early && !node2_early) - return -1; - - if (!node1_early && node2_early) - return 1; - - return node1->keyword.compare(node2->keyword); -} - - -static int int_cmp(int v1, int v2) { +int int_cmp(int v1, int v2) { if (v1 < v2) return -1; @@ -1035,174 +1108,354 @@ static int int_cmp(int v1, int v2) { return 0; } -static int smspec_node_cmp_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) { - int i_cmp = int_cmp( node1->lgr_ijk[0] , node2->lgr_ijk[0]); + +int cmp_MISC( const smspec_node& node1, const smspec_node& node2) { + static const std::set early_vars = {"TIME", "DAYS", "DAY", "MONTH", "YEAR", "YEARS"}; + + if (&node1 == &node2) + return 0; + + bool node1_early = !( early_vars.find(node1.get_keyword()) == early_vars.end() ); + bool node2_early = !( early_vars.find(node2.get_keyword()) == early_vars.end() ); + + + if (node1_early && !node2_early) + return -1; + + if (!node1_early && node2_early) + return 1; + + return strcmp(node1.get_keyword(), node2.get_keyword()); +} + + +int cmp_LGRIJK( const smspec_node& node1, const smspec_node& node2) { + const auto& ijk1 = node1.get_lgr_ijk(); + const auto& ijk2 = node2.get_lgr_ijk(); + + int i_cmp = int_cmp( ijk1[0] , ijk2[0]); if (i_cmp != 0) return i_cmp; - int j_cmp = int_cmp( node1->lgr_ijk[1] , node2->lgr_ijk[1]); + int j_cmp = int_cmp(ijk1[1] , ijk2[1]); if (j_cmp != 0) return j_cmp; - return int_cmp( node1->lgr_ijk[2] , node2->lgr_ijk[2]); + return int_cmp( ijk1[2] , ijk2[2]); } - -static int smspec_node_cmp_KEYWORD_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); +int cmp_KEYWORD_LGR_LGRIJK( const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - int lgr_cmp = node1->lgr_name.compare( node2->lgr_name ); + int lgr_cmp = strcmp(node1.get_lgr_name(), node2.get_lgr_name()); if (lgr_cmp != 0) return lgr_cmp; - return smspec_node_cmp_LGRIJK( node1, node2); + return cmp_LGRIJK( node1, node2); } - -static int smspec_node_cmp_KEYWORD_WGNAME_NUM( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); +int cmp_KEYWORD_WGNAME_NUM(const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = node1->wgname.compare(node2->wgname); + int wgname_cmp = strcmp(node1.get_wgname(), node2.get_wgname()); if (wgname_cmp != 0) return wgname_cmp; - return int_cmp( node1->num , node2->num); + return int_cmp( node1.get_num() , node2.get_num()); } -static int smspec_node_cmp_KEYWORD_WGNAME_LGR( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); +int cmp_KEYWORD_WGNAME_LGR( const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = node1->wgname.compare(node2->wgname); + int wgname_cmp = strcmp(node1.get_wgname(), node2.get_wgname()); if (wgname_cmp != 0) return wgname_cmp; - return node1->lgr_name.compare(node2->lgr_name); + return strcmp(node1.get_lgr_name(), node2.get_lgr_name()); } - -static int smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); +int cmp_KEYWORD_WGNAME_LGR_LGRIJK( const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = node1->wgname.compare(node2->wgname); + int wgname_cmp = strcmp(node1.get_wgname(), node2.get_wgname()); if (wgname_cmp != 0) return wgname_cmp; - int lgr_cmp = node1->lgr_name.compare(node2->lgr_name); + int lgr_cmp = strcmp(node1.get_lgr_name(), node2.get_lgr_name()); if (lgr_cmp != 0) return lgr_cmp; - return smspec_node_cmp_LGRIJK( node1, node2); + return cmp_LGRIJK( node1, node2); } - - - -static int smspec_node_cmp_KEYWORD_WGNAME( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); +int cmp_KEYWORD_WGNAME( const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - if (IS_DUMMY_WELL( node1->wgname.c_str() )) { - if (IS_DUMMY_WELL( node2->wgname.c_str() )) + if (IS_DUMMY_WELL( node1.get_wgname() )) { + if (IS_DUMMY_WELL( node2.get_wgname() )) return 0; else return 1; } - if (IS_DUMMY_WELL( node2->wgname.c_str() )) + if (IS_DUMMY_WELL( node2.get_wgname() )) return -1; - return node1->wgname.compare(node2->wgname); + return strcmp(node1.get_wgname(), node2.get_wgname()); +} + +int cmp_KEYWORD( const smspec_node& node1, const smspec_node& node2) { + return strcmp(node1.get_keyword(), node2.get_keyword()); } -static int smspec_node_cmp_KEYWORD_NUM( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = node1->keyword.compare(node2->keyword); + +int cmp_KEYWORD_NUM( const smspec_node& node1, const smspec_node& node2) { + int keyword_cmp = strcmp(node1.get_keyword(), node2.get_keyword()); if (keyword_cmp != 0) return keyword_cmp; - return int_cmp( node1->num , node2->num); + return int_cmp( node1.get_num() , node2.get_num()); } -static int smspec_node_cmp_KEYWORD( const smspec_node_type * node1, const smspec_node_type * node2) { - return node1->keyword.compare(node2->keyword); -} - -static int smspec_node_cmp_key1( const smspec_node_type * node1, const smspec_node_type * node2) { - if (node1->gen_key1.empty()) { - if (node2->gen_key1.empty()) +int cmp_key1( const smspec_node& node1, const smspec_node& node2) { + if (node1.get_gen_key1() == NULL) { + if (node2.get_gen_key1() == NULL) return 0; else return -1; - } else if (node2->gen_key1.empty()) { + } else if (node2.get_gen_key1() == NULL) return 1; - } - return util_strcmp_int( node1->gen_key1.c_str() , node2->gen_key1.c_str() ); + + return util_strcmp_int( node1.get_gen_key1() , node2.get_gen_key1() ); +} } - -int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2) { +int smspec_node::cmp(const smspec_node& node1, const smspec_node& node2) { /* 1: Start with special casing for the MISC variables. */ - if ((node1->var_type == ECL_SMSPEC_MISC_VAR) || (node2->var_type == ECL_SMSPEC_MISC_VAR)) - return smspec_node_cmp_MISC( node1 , node2 ); + if ((node1.var_type == ECL_SMSPEC_MISC_VAR) || (node2.var_type == ECL_SMSPEC_MISC_VAR)) + return cmp_MISC( node1 , node2 ); /* 2: Sort according to variable type */ - if (node1->var_type < node2->var_type) + if (node1.var_type < node2.var_type) return -1; - if (node1->var_type > node2->var_type) + if (node1.var_type > node2.var_type) return 1; /* 3: Internal sort of variables of the same type. */ - switch (node1->var_type) { + switch (node1.var_type) { case( ECL_SMSPEC_FIELD_VAR): - return smspec_node_cmp_KEYWORD( node1, node2); + return cmp_KEYWORD( node1, node2); case( ECL_SMSPEC_WELL_VAR): case( ECL_SMSPEC_GROUP_VAR): - return smspec_node_cmp_KEYWORD_WGNAME( node1, node2); + return cmp_KEYWORD_WGNAME( node1, node2); case( ECL_SMSPEC_BLOCK_VAR): case( ECL_SMSPEC_REGION_VAR): case( ECL_SMSPEC_REGION_2_REGION_VAR): case( ECL_SMSPEC_AQUIFER_VAR): - return smspec_node_cmp_KEYWORD_NUM( node1, node2); + return cmp_KEYWORD_NUM( node1, node2); case( ECL_SMSPEC_COMPLETION_VAR): case( ECL_SMSPEC_SEGMENT_VAR): - return smspec_node_cmp_KEYWORD_WGNAME_NUM( node1, node2); + return cmp_KEYWORD_WGNAME_NUM( node1, node2); case (ECL_SMSPEC_NETWORK_VAR): - return smspec_node_cmp_key1( node1, node2); + return cmp_key1( node1, node2); case( ECL_SMSPEC_LOCAL_BLOCK_VAR): - return smspec_node_cmp_KEYWORD_LGR_LGRIJK( node1, node2); + return cmp_KEYWORD_LGR_LGRIJK( node1, node2); case( ECL_SMSPEC_LOCAL_WELL_VAR): - return smspec_node_cmp_KEYWORD_WGNAME_LGR( node1, node2); + return cmp_KEYWORD_WGNAME_LGR( node1, node2); case( ECL_SMSPEC_LOCAL_COMPLETION_VAR): - return smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( node1, node2); + return cmp_KEYWORD_WGNAME_LGR_LGRIJK( node1, node2); default: /* Should not really end up here. */ - return smspec_node_cmp_key1( node1, node2); + return cmp_key1( node1, node2); } } -int smspec_node_cmp__( const void * node1, const void * node2) { - return smspec_node_cmp( smspec_node_safe_cast_const( node1 ), - smspec_node_safe_cast_const( node2 )); +int smspec_node::cmp(const smspec_node& node2) const { + return smspec_node::cmp(*this, node2); +} + + +} // end namespace ecl + +/************************************** OLD API functions ***********************''''' */ + + +void smspec_node_free( void * index ) { + delete static_cast(index); +} + +void smspec_node_free__( void * arg ) { + smspec_node_free( arg ); +} + +float smspec_node_get_default( const void * smspec_node ) { + return static_cast(smspec_node)->get_default(); +} + +int smspec_node_get_params_index( const void * smspec_node ) { + return static_cast(smspec_node)->get_params_index(); +} + +// void smspec_node_set_params_index( void * smspec_node , int params_index) { + // static_cast(smspec_node)->set_params_index( params_index ); +// } + +const char * smspec_node_get_gen_key1( const void * smspec_node) { + return static_cast(smspec_node)->get_gen_key1(); +} + +const char * smspec_node_get_gen_key2( const void * smspec_node) { + return static_cast(smspec_node)->get_gen_key2(); +} + +const char * smspec_node_get_wgname( const void * smspec_node) { + return static_cast(smspec_node)->get_wgname(); +} + +const char * smspec_node_get_keyword( const void * smspec_node) { + return static_cast(smspec_node)->get_keyword( ); +} + +ecl_smspec_var_type smspec_node_get_var_type( const void * smspec_node) { + return static_cast(smspec_node)->get_var_type(); +} + +int smspec_node_get_num( const void * smspec_node) { + return static_cast(smspec_node)->get_num(); +} + +bool smspec_node_is_rate( const void * smspec_node ) { + return static_cast(smspec_node)->is_rate(); +} + +bool smspec_node_is_total( const void * smspec_node ){ + return static_cast(smspec_node)->is_total(); +} + +bool smspec_node_is_historical( const void * smspec_node ){ + return static_cast(smspec_node)->is_historical(); +} + +const char * smspec_node_get_unit( const void * smspec_node) { + return static_cast(smspec_node)->get_unit(); +} + +// Will be garbage for smspec_nodes which do not have i,j,k +const int* smspec_node_get_ijk( const void * smspec_node ) { + return static_cast(smspec_node)->get_ijk().data(); +} + +// Will be NULL for smspec_nodes which are not related to an LGR. +const char* smspec_node_get_lgr_name( const void * smspec_node ) { + return static_cast(smspec_node)->get_lgr_name(); +} + + +// Will be garbage for smspec_nodes which are not related to an LGR. +const int* smspec_node_get_lgr_ijk( const void * smspec_node ) { + return static_cast(smspec_node)->get_lgr_ijk().data(); +} + +int smspec_node_get_R1( const void * smspec_node ) { + return static_cast(smspec_node)->get_R1(); +} + + +int smspec_node_get_R2( const void * smspec_node ) { + return static_cast(smspec_node)->get_R2(); +} + +bool smspec_node_need_nums( const void * smspec_node ) { + return static_cast(smspec_node)->need_nums(); +} + +void smspec_node_fprintf( const void * smspec_node , FILE * stream) { + static_cast(smspec_node)->fprintf__(stream); +} + +int smspec_node_cmp( const void * node1, const void * node2) { + return ecl::smspec_node::cmp(static_cast(node1), static_cast(node2)); +} + +int smspec_node_cmp__( const void * node1, const void * node2) { + return smspec_node_cmp(node1, node2); +} + + +void * smspec_node_alloc( int param_index, + const char * keyword , + const char * wgname, + int num, + const char * unit , + const int grid_dims[3] , + float default_value, + const char * key_join_string) { + + ecl::smspec_node * node = NULL; + try { + node = new ecl::smspec_node(param_index, + keyword, + wgname, + num, + unit, + grid_dims, + default_value, + key_join_string); + } + catch (const std::invalid_argument& e) { + node = NULL; + } + return node; +} + + +void * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * lgr , + const char * key_join_string , + int lgr_i, int lgr_j , int lgr_k, + int param_index , float default_value) { + + return new ecl::smspec_node( param_index, keyword, wgname, unit, lgr, lgr_i, lgr_j, lgr_k, default_value, key_join_string); +} + + + +bool smspec_node_equal( const void * node1, const void * node2) { + return ecl::smspec_node::cmp( static_cast(node1) , static_cast(node2) ) == 0; +} + + +bool smspec_node_gt( const void * node1, const void * node2) { + return ecl::smspec_node::cmp( static_cast(node1) , static_cast(node2) ) > 0; +} + +bool smspec_node_lt( const void * node1, const void * node2) { + return ecl::smspec_node::cmp( static_cast(node1) , static_cast(node2) ) < 0; } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp index f3c1ac4e44..2a06c3cc88 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_alloc_cpgrid.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp index 9992680f74..7f7ff44104 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2013 Andreas Lauser - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_alloc_grid_dxv_dyv_dzv.c' is part of ERT - Ensemble based Reservoir Tool. @@ -55,6 +55,7 @@ void test_grid() { } } } + ecl_grid_free( ecl_grid ); } int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp index d1882092cd..b2c36fbb22 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_coarse_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp index a26d38b863..35b1860c1e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_dualp.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_equinor.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_equinor.cpp index 73bd471390..a40dbaac1f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_equinor.cpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. - The file 'ecl_fault_block_collection_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_fault_block_collection_equinor.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 diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp index d8de3438af..e1be64668e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_fault_block_layer.c' is part of ERT - Ensemble based Reservoir Tool. @@ -98,6 +98,7 @@ void test_trace_edge( const ecl_grid_type * grid) { test_assert_int_equal( 1 , int_vector_size( cell_list )); test_assert_int_equal( 0 , int_vector_iget( cell_list , 0)); + fault_block_layer_free(layer); int_vector_free( cell_list ); double_vector_free( x_list ); double_vector_free( y_list ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_equinor.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_equinor.cpp index 6e2590397a..a7e0f1e18f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_equinor.cpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. - The file 'ecl_fault_block_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_fault_block_layer_equinor.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 diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp index c680e3d10e..951fe544f6 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp @@ -1,6 +1,6 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -31,7 +31,7 @@ #include void test_writable(size_t data_size) { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_writable"); + ecl::util::TestArea ta("file_writable"); const char * data_file_name = "test_file"; ecl_kw_type * kw = ecl_kw_alloc("TEST_KW", data_size, ECL_INT); @@ -54,11 +54,10 @@ void test_writable(size_t data_size) { } ecl_kw_free(kw); - test_work_area_free( work_area ); } void test_truncated() { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_truncated" ); + ecl::util::TestArea ta("truncate_file"); int num_kw; { ecl_grid_type * grid = ecl_grid_alloc_rectangular(20,20,20,1,1,1,NULL); @@ -69,6 +68,7 @@ void test_truncated() { ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 ); test_assert_true( ecl_file_is_instance( ecl_file ) ); num_kw = ecl_file_get_size( ecl_file ); + test_assert_int_equal( ecl_file_get_num_distinct_kw( ecl_file ), 11); ecl_file_close( ecl_file ); } @@ -83,7 +83,6 @@ void test_truncated() { test_assert_true( ecl_file_get_size( ecl_file) < num_kw ); ecl_file_close( ecl_file ); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_file_equinor.cpp similarity index 90% rename from ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_file_equinor.cpp index 13de6fcf40..3d496444de 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file_equinor.cpp @@ -1,8 +1,8 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. - The file 'ecl_file_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_file_equinor.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 @@ -108,10 +108,10 @@ void test_close_stream1(const char * src_file , const char * target_file ) { void test_writable(const char * src_file ) { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_writable" ); + ecl::util::TestArea ta("file_writable"); char * fname = util_split_alloc_filename( src_file ); - test_work_area_copy_file( work_area , src_file ); + ta.copy_file(src_file); { test_flags( fname ); ecl_file_type * ecl_file = ecl_file_open( fname , ECL_FILE_WRITABLE); @@ -127,7 +127,6 @@ void test_writable(const char * src_file ) { swat = ecl_file_iget_named_kw( ecl_file , "SWAT" , 0 ); test_assert_true( util_double_approx_equal( ecl_kw_iget_float( swat , 0 ) , 1000 )); } - test_work_area_free( work_area ); } @@ -138,16 +137,15 @@ int main( int argc , char ** argv) { const char * target_file = argv[2]; { - test_work_area_type * work_area = test_work_area_alloc("ecl_file"); + ecl::util::TestArea ta("file_equinor"); - test_work_area_copy_file( work_area , src_file ); + ta.copy_file( src_file ); test_loadall(src_file , target_file ); test_close_stream1( src_file , target_file); test_close_stream2( src_file , target_file); test_writable( src_file ); - test_work_area_free( work_area ); } exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp index 9dc7875d7c..7f329c310a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_file_view.c' is part of ERT - Ensemble based Reservoir Tool. @@ -59,7 +59,7 @@ void test_create_file_kw() { test_assert_int_equal( ecl_file_kw_get_size( file_kw0 ) , 1000 ); test_assert_true( ecl_type_is_equal( ecl_file_kw_get_data_type( file_kw0 ) , ECL_FLOAT )); { - test_work_area_type * work_area = test_work_area_alloc("file_kw"); + ecl::util::TestArea ta("file_kw"); { FILE * ostream = util_fopen("file_kw" , "w"); ecl_file_kw_fwrite( file_kw0 , ostream ); @@ -101,7 +101,6 @@ void test_create_file_kw() { test_assert_NULL( ecl_file_kw_fread_alloc_multiple( istream , 10)); fclose( istream ); } - test_work_area_free( work_area ); } ecl_file_kw_free( file_kw0 ); ecl_file_kw_free( file_kw1 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp index 5b04922dce..ea07feae8f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_fmt.c' is part of ERT - Ensemble based Reservoir Tool. @@ -25,14 +25,12 @@ #include -void test_content( test_work_area_type * work_area , const char * src_file , bool fmt_file ) { - test_work_area_install_file( work_area , src_file ); +void test_content( const ecl::util::TestArea& ta , const char * src_file , bool fmt_file ) { + ta.copy_file(src_file); { char * base_name; bool fmt; util_alloc_file_components( src_file , NULL , &base_name , NULL); - util_copy_file( src_file , base_name ); - test_assert_true( ecl_util_fmt_file( base_name , &fmt )); test_assert_bool_equal( fmt , fmt_file ); } @@ -41,6 +39,7 @@ void test_content( test_work_area_type * work_area , const char * src_file , boo + void test_small( ) { bool fmt; @@ -56,7 +55,7 @@ void test_small( ) { int main(int argc , char ** argv) { - test_work_area_type * work_area = test_work_area_alloc( "ecl_fmt"); + ecl::util::TestArea ta("ecl_fmt"); { const char * binary_file = argv[1]; const char * text_file = argv[2]; @@ -78,10 +77,9 @@ int main(int argc , char ** argv) { test_assert_false(ecl_util_fmt_file( "TEST_DOES_NOT_EXIST" , &fmt_file )); - test_content( work_area , binary_file , false ); - test_content( work_area , text_file , true ); + test_content( ta , binary_file , false ); + test_content( ta , text_file , true ); test_small( ); } - test_work_area_free( work_area ); exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp index e18fcd20ae..da7de8e695 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_fortio.c' is part of ERT - Ensemble based Reservoir Tool. @@ -111,7 +111,7 @@ void test_open_close_read( const char * filename ) { void test_fread_truncated_data() { - test_work_area_type * work_area = test_work_area_alloc("fortio_truncated" ); + ecl::util::TestArea work_area("fortio_truncated"); { const size_t buffer_size = 1000; char * buffer = (char *) util_malloc( buffer_size ); @@ -136,11 +136,10 @@ void test_fread_truncated_data() { } free( buffer ); } - test_work_area_free( work_area ); } void test_fread_truncated_head() { - test_work_area_type * work_area = test_work_area_alloc("fortio_truncated" ); + ecl::util::TestArea work_area("fortio_truncated"); { { FILE * stream = util_fopen("PRESSURE" , "w"); @@ -156,12 +155,11 @@ void test_fread_truncated_head() { fortio_fclose( fortio ); } } - test_work_area_free( work_area ); } void test_fread_truncated_tail() { - test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" ); + ecl::util::TestArea work_area("fortio_truncated3"); { const size_t buffer_size = 1000; char * buffer = (char *) util_malloc( buffer_size ); @@ -183,12 +181,11 @@ void test_fread_truncated_tail() { } free( buffer ); } - test_work_area_free( work_area ); } void test_fread_invalid_tail() { - test_work_area_type * work_area = test_work_area_alloc("fortio_invalid" ); + ecl::util::TestArea work_area("fortio_invalid"); int record_size = 10; char * buffer = (char *) util_malloc( record_size ); { @@ -215,13 +212,12 @@ void test_fread_invalid_tail() { } free( buffer ); - test_work_area_free( work_area ); } void test_at_eof() { - test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" ); + ecl::util::TestArea work_area("fortio_truncated3"); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); char * buffer = (char *) util_malloc( 100 ); @@ -242,13 +238,11 @@ void test_at_eof() { fortio_fclose( fortio ); } - - test_work_area_free( work_area ); } void test_fseek() { - test_work_area_type * work_area = test_work_area_alloc("fortio_fseek" ); + ecl::util::TestArea work_area("fortio_fseek"); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); char * buffer = (char *) util_malloc( 100 ); @@ -261,8 +255,6 @@ void test_fseek() { { fortio_type * fortio = fortio_open_reader("PRESSURE" , false , true); - - printf("Starting fssek test \n"); test_assert_true( fortio_fseek( fortio , 0 , SEEK_SET )); test_assert_true( fortio_fseek( fortio , 0 , SEEK_END )); test_assert_false( fortio_fseek( fortio , 100000 , SEEK_END)); @@ -270,14 +262,12 @@ void test_fseek() { fortio_fclose( fortio ); } - - test_work_area_free( work_area ); } void test_write_failure() { - test_work_area_type * work_area = test_work_area_alloc("fortio_fseek" ); + ecl::util::TestArea work_area("fortio_truncated"); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); char * buffer = (char *) util_malloc( 100 ); @@ -292,7 +282,6 @@ void test_write_failure() { test_assert_false( util_file_exists( "PRESSURE")); } - test_work_area_free( work_area ); } @@ -317,10 +306,9 @@ int main( int argc , char ** argv) { test_write( "/tmp/path/does/not/exist" , false ); { - test_work_area_type * work_area = test_work_area_alloc("ecl_fortio.write" ); + ecl::util::TestArea work_area("ecl_fortio_write"); util_make_path("path"); test_write( "path/file.x" , true ); - test_work_area_free( work_area ); } test_write_failure(); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp index 3f715b2cd8..c608634367 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_get_num_cpu_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp index 29b14612cb..056eebb750 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_DEPTHZ.c' is part of ERT - Ensemble based Reservoir Tool. @@ -44,15 +44,15 @@ void test_create() { int ny = 100; int nz = 10; - double * DXV = (double *) util_malloc( nx * sizeof * DXV ); - double * DYV = (double *) util_malloc( ny * sizeof * DYV ); + double * DXV = (double *) util_malloc( (nx + 1) * sizeof * DXV ); + double * DYV = (double *) util_malloc( (ny + 1) * sizeof * DYV ); double * DZV = (double *) util_malloc( nz * sizeof * DZV ); double * DEPTHZ = (double *) util_malloc( (nx + 1) * (ny + 1) * sizeof * DEPTHZ); - for (int i=0; i < nx; i++) + for (int i=0; i <= nx; i++) DXV[i] = 1.0 / nx; - for (int j=0; j < ny; j++) + for (int j=0; j <= ny; j++) DYV[j] = 1.0 / ny; for (int k=0; k < nz; k++) diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp index d7d9221361..144d8dcc1e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_grid_add_nnc.c' is part of ERT - Ensemble based Reservoir Tool. @@ -60,14 +60,13 @@ void simple_test() { verify_simple_nnc( grid0 ); { - test_work_area_type * test_area = test_work_area_alloc("ecl_grid_nnc"); + ecl::util::TestArea ta("simple_nnc"); ecl_grid_type * grid1; ecl_grid_fwrite_EGRID2( grid0 , "TEST.EGRID" , ECL_METRIC_UNITS); grid1 = ecl_grid_alloc( "TEST.EGRID" ); verify_simple_nnc( grid1 ); ecl_grid_free( grid1 ); - test_work_area_free( test_area ); } ecl_grid_free( grid0 ); } @@ -90,14 +89,13 @@ void overwrite_test() { verify_simple_nnc( grid0 ); { - test_work_area_type * test_area = test_work_area_alloc("ecl_grid_nnc"); + ecl::util::TestArea ta("overwrite"); ecl_grid_type * grid1; ecl_grid_fwrite_EGRID2( grid0 , "TEST.EGRID" , ECL_METRIC_UNITS); grid1 = ecl_grid_alloc( "TEST.EGRID" ); verify_simple_nnc( grid1 ); ecl_grid_free( grid1 ); - test_work_area_free( test_area ); } ecl_grid_free( grid0 ); } @@ -118,15 +116,16 @@ void list_test() { verify_simple_nnc( grid0 ); { - test_work_area_type * test_area = test_work_area_alloc("ecl_grid_nnc"); + ecl::util::TestArea ta("list_test"); ecl_grid_type * grid1; ecl_grid_fwrite_EGRID2( grid0 , "TEST.EGRID" , ECL_METRIC_UNITS); grid1 = ecl_grid_alloc( "TEST.EGRID" ); verify_simple_nnc( grid1 ); ecl_grid_free( grid1 ); - test_work_area_free( test_area ); } + int_vector_free(g1); + int_vector_free(g2); ecl_grid_free( grid0 ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp index 6dcb7f05c2..ca2da22e3f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_case.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp index c44ccbfc2f..bab105c304 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_cell_contains.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp index c2eb6d8179..fc11a91c15 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_grid_cell_contains_wellpath.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp index b5e69a4eae..37da21546a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_copy.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_equinor.cpp similarity index 91% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_equinor.cpp index 23182906c3..eafff99257 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_equinor.cpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. - The file 'ecl_grid_copy_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_grid_copy_equinor.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 diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp index 5b3c2fe044..d651d456e2 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_corner.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp index d7d45f32e9..d67b09ebbc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_create.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp index 8658da7089..bff2114681 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp index 542b70b824..35e13dbd8a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp index 913269ae36..80dce52d4c 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_export.c' is part of ERT - Ensemble based Reservoir Tool. @@ -154,7 +154,7 @@ void export_mapaxes( const ecl_grid_type * grid , ecl_file_type * ecl_file ) { int main(int argc , char ** argv) { - test_work_area_type * work_area = test_work_area_alloc("grid_export"); + ecl::util::TestArea ta("grid_export"); { const char * test_grid = "TEST.EGRID"; const char * grid_file; @@ -181,5 +181,4 @@ int main(int argc , char ** argv) { ecl_grid_free( ecl_grid ); } } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp index 75c497189a..3378bda981 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp @@ -12,7 +12,7 @@ void test_1() { - test_work_area_type * work_area = test_work_area_alloc("ext_actnum_main_grid"); + ecl::util::TestArea ta("test1"); { const char * filename = "FILE.EGRID"; @@ -41,21 +41,18 @@ void test_1() { std::vector ext_actnum = {0, 1, 0, 1, 1, 1}; ecl_grid_type * grid = ecl_grid_alloc_ext_actnum(filename1, ext_actnum.data()); - test_assert_int_equal( 2, ecl_grid_get_nactive(grid) ); - test_assert_int_equal( 1, ecl_grid_get_nactive_fracture(grid) ); + test_assert_int_equal( 4, ecl_grid_get_nactive(grid) ); + test_assert_int_equal( 0, ecl_grid_get_nactive_fracture(grid) ); test_assert_true( !ecl_grid_cell_active1(grid, 0) ); test_assert_true( !ecl_grid_cell_active1(grid, 2) ); - test_assert_true( !ecl_grid_cell_active1(grid, 3) ); + test_assert_true( ecl_grid_cell_active1(grid, 3) ); test_assert_true( ecl_grid_cell_active1(grid, 4) ); test_assert_true( ecl_grid_cell_active1(grid, 5) ); ecl_grid_free( grid ); } - test_work_area_free( work_area ); - - } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp index 861edc0c42..d359a41f71 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_kw_fwrite.c' is part of ERT - Ensemble based Reservoir Tool. @@ -37,12 +37,72 @@ void test_fwrite_EGRID(ecl_grid_type * grid ) { test_work_area_free( work_area ); } +namespace { + void test_fwrite_fmt_vs_unfmt( ) { + ecl::util::TestArea ta( "fmt_file" ); + ecl_grid_type * ecl_grid = ecl_grid_alloc_rectangular( 5 , 5 , 5 , 1 , 1 , 1 , nullptr); + + /* .FEGRID -> formatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.FEGRID" , ECL_METRIC_UNITS ); + test_assert_true( util_fmt_bit8( "CASE.FEGRID" ) ); + } + + /* .EGRID -> unformatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.EGRID" , ECL_METRIC_UNITS ); + test_assert_false( util_fmt_bit8( "CASE.EGRID" ) ); + } + + /* Unknown -> unformatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.UNKNOWN" , ECL_METRIC_UNITS ); + test_assert_false( util_fmt_bit8( "CASE.UNKNOWN" ) ); + } + + /* Abuse: .FUNRST -> formatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.FUNRST" , ECL_METRIC_UNITS ); + test_assert_true( util_fmt_bit8( "CASE.FUNRST" ) ); + } + + /* Abuse: .FSMSPEC -> formatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.FSMSPEC" , ECL_METRIC_UNITS ); + test_assert_true( util_fmt_bit8( "CASE.FSMSPEC" ) ); + } + + /* Abuse: .F0001 -> formatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.F0001" , ECL_METRIC_UNITS ); + test_assert_true( util_fmt_bit8( "CASE.F0001" ) ); + } + + /* Abuse: .X1234 -> unformatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.X1234" , ECL_METRIC_UNITS ); + test_assert_false( util_fmt_bit8( "CASE.X1234" ) ); + } + + /* Abuse: .UNSMRY -> unformatted */ + { + ecl_grid_fwrite_EGRID2( ecl_grid , "CASE.UNSMRY" , ECL_METRIC_UNITS ); + test_assert_false( util_fmt_bit8( "CASE.UNSMRY" ) ); + } + + ecl_grid_free( ecl_grid ); + } +} int main( int argc , char **argv) { - const char * src_file = argv[1]; - ecl_grid_type * grid = ecl_grid_alloc( src_file ); + if (argc > 1) { + const char * src_file = argv[1]; + ecl_grid_type * grid = ecl_grid_alloc( src_file ); - test_fwrite_EGRID( grid ); + test_fwrite_EGRID( grid ); - ecl_grid_free( grid ); + ecl_grid_free( grid ); + } + + test_fwrite_fmt_vs_unfmt( ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp index dc480232e0..8d6111f125 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. @@ -31,7 +31,7 @@ void test_write_depth(const ecl_grid_type * grid) { - test_work_area_type * test_area = test_work_area_alloc("write_depth"); + ecl::util::TestArea ta("write_depth"); { fortio_type * init_file = fortio_open_writer( "INIT" , false , ECL_ENDIAN_FLIP ); ecl_grid_fwrite_depth( grid , init_file , ECL_METRIC_UNITS); @@ -47,12 +47,11 @@ void test_write_depth(const ecl_grid_type * grid) { ecl_file_close(init_file); } - test_work_area_free( test_area ); } void test_write_dims(const ecl_grid_type * grid) { - test_work_area_type * test_area = test_work_area_alloc("write_dims"); + ecl::util::TestArea ta("write_dims"); { fortio_type * init_file = fortio_open_writer( "INIT" , false , ECL_ENDIAN_FLIP ); ecl_grid_fwrite_dims( grid , init_file , ECL_METRIC_UNITS ); @@ -74,7 +73,6 @@ void test_write_dims(const ecl_grid_type * grid) { } ecl_file_close(init_file); } - test_work_area_free( test_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp index 6af4f412be..5cb968d336 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_layer_contains' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp index 59d314316f..0055b0a0a3 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. @@ -41,8 +41,6 @@ Name ..................: LG003014 Grid nr ...............: 110 - - Name ..................: /private/joaho/ERT/git/ert/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID */ diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp index c0c39aab37..99d99d26ba 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_grid_reset_actnum.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp index 8d9f9ed5a8..052766aaff 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_simple.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp index 2e75a1c59b..b191503ca9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. The file 'ecl_grid_unit_system.c' is part of ERT - Ensemble based Reservoir Tool. @@ -52,12 +52,10 @@ void test_GRID(const char * filename, ert_ecl_unit_enum unit_system) { int main(int argc, char **argv) { - test_work_area_type * work_area = test_work_area_alloc("grid_export"); + ecl::util::TestArea ta("grid_unit_system"); test_EGRID("METRIC.EGRID", ECL_METRIC_UNITS); test_EGRID("FIELD.EGRID", ECL_FIELD_UNITS); test_GRID("METRIC.GRID", ECL_METRIC_UNITS); test_GRID("FIELD.GRID", ECL_FIELD_UNITS); - - test_work_area_free(work_area); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp index eb6feb62d1..393bc3d14a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_volume.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp index d4dbb4a293..4246bc32eb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_init_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -36,8 +36,8 @@ void test_write_header() { int ny = 10; int nz = 5; + ecl::util::TestArea ta("WRITE_header"); int_vector_type * actnum = int_vector_alloc( nx*ny*nz , 1 ); - test_work_area_type * test_area = test_work_area_alloc( "ecl_init_file" ); time_t start_time = util_make_date_utc(15 , 12 , 2010 ); ecl_grid_type * ecl_grid; @@ -84,7 +84,8 @@ void test_write_header() { ecl_init_file_fwrite_header( f , ecl_grid , NULL , ECL_METRIC_UNITS, 7 , start_time ); fortio_fclose( f ); } - test_work_area_free( test_area ); + ecl_grid_free( ecl_grid ); + int_vector_free( actnum ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp index d7d925bc49..ecc411680e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_kw_cmp_string.c' is part of ERT - Ensemble based Reservoir Tool. @@ -39,6 +39,7 @@ void test_cmp_string() { test_assert_false( ecl_kw_icmp_string( ecl_kw , 0 , "")); test_assert_false( ecl_kw_icmp_string( ecl_kw , 0 , "")); + ecl_kw_free(ecl_kw); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp index 912816025f..231e882468 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_kw_equal.c' is part of ERT - Ensemble based Reservoir Tool. @@ -55,12 +55,13 @@ int main(int argc , char ** argv) { test_assert_true( ecl_kw_content_equal( ecl_kw1 , ecl_ikw )); test_assert_false( ecl_kw_content_equal( ecl_kw1 , ecl_fkw )); + + ecl_kw_free(ecl_ikw); + ecl_kw_free(ecl_fkw); } test_assert_true( ecl_kw_data_equal( ecl_kw1 , data )); data[0] = 99; test_assert_false( ecl_kw_data_equal( ecl_kw1 , data )); - - - + ecl_kw_free(ecl_kw1); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp index 2cf4a24be8..a4badb438b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Statoil ASA, Norway. + Copyright (C) 2015 Equinor ASA, Norway. The file 'ecl_kw_init.c' is part of ERT - Ensemble based Reservoir Tool. @@ -45,7 +45,7 @@ void test_truncated(const char * filename , offset_type truncate_size) { void test_fread_alloc() { - test_work_area_type * work_area = test_work_area_alloc("ecl_kw_fread" ); + ecl::util::TestArea ta("fread_alloc"); { ecl_kw_type * kw1 = ecl_kw_alloc( "INT" , 100 , ECL_INT ); int i; @@ -74,11 +74,10 @@ void test_fread_alloc() { } ecl_kw_free( kw1 ); } - test_work_area_free( work_area ); } void test_kw_io_charlength() { - test_work_area_type * work_area = test_work_area_alloc("ecl_kw_io_charlength"); + ecl::util::TestArea ta("io_charlength"); { const char * KW0 = "QWERTYUI"; const char * KW1 = "ABCDEFGHIJTTTTTTTTTTTTTTTTTTTTTTABCDEFGHIJKLMNOP"; @@ -115,13 +114,13 @@ void test_kw_io_charlength() { test_assert_double_equal(ecl_kw_iget_as_double(ecl_kw_in, 0), 0.0); test_assert_double_equal(ecl_kw_iget_as_double(ecl_kw_in, 4), 6.0); + ecl_kw_free(ecl_kw_in); fclose(file); } ecl_kw_free( ecl_kw_out0 ); ecl_kw_free( ecl_kw_out1 ); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp index a1b49eb55b..97dd9c7947 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool. @@ -32,7 +32,7 @@ int main(int argc , char ** argv) { ecl_kw_iset_int(ecl_kw , i , i ); { - test_work_area_type * work_area = test_work_area_alloc("ecl_kw_grdecl"); + ecl::util::TestArea ta("kw_grdecl"); FILE * stream = util_fopen( "FILE.grdecl" , "w"); ecl_kw_fprintf_grdecl(ecl_kw , stream ); @@ -65,7 +65,6 @@ int main(int argc , char ** argv) { ecl_kw_free( ecl_kw2 ); } fclose( stream ); - test_work_area_free( work_area ); } ecl_kw_free( ecl_kw ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp index 0f4a883526..16b382a188 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_kw_init.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp index ab5d85c6d5..7a0d0ad0d0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_layer.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_layer_equinor.cpp similarity index 96% rename from ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_layer_equinor.cpp index 912248dfd4..a984cb84f8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_layer_equinor.cpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. - The file 'ecl_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_layer_equinor.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 diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp index 6d2048cfdb..0a6163349a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_win64.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp index ca798963d8..f45c5d6aec 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp index a585de4fb2..c0807e951e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_lgr_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_equinor_root.cpp similarity index 97% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_equinor_root.cpp index 784864bf97..f804376366 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_equinor_root.cpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. - The file 'test_ecl_nnc_data_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'test_ecl_nnc_data_equinor.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 diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp index 556e2df7a0..ed97f621f9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool. @@ -74,8 +74,10 @@ int count_kw_data( const ecl_file_type * file , ecl_grid_type * grid , const cha void test_count(const char * name) { char * grid_file_name = ecl_util_alloc_filename(NULL , name , ECL_EGRID_FILE , false , -1); + char * init_file_name = ecl_util_alloc_filename(NULL , name , ECL_INIT_FILE , false , -1); ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * grid_file = ecl_file_open( grid_file_name , 0 ); + ecl_file_type * init_file = ecl_file_open( init_file_name , 0); int num_nnc = 0; @@ -83,7 +85,7 @@ void test_count(const char * name) { num_nnc += count_kw_data( grid_file , grid , "NNCG" , NULL); num_nnc += count_kw_data( grid_file , grid , "NNA1" , NULL); - test_assert_int_equal( num_nnc , ecl_nnc_export_get_size( grid )); + test_assert_int_equal(num_nnc, ecl_nnc_export_get_size(grid, init_file)); free(grid_file_name); ecl_grid_free( grid ); @@ -97,7 +99,7 @@ void test_nnc_export_missing_TRANX(const char * name ) { if (util_entry_exists(init_file_name)) { ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * init_file = ecl_file_open( init_file_name , 0); - ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); + ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc(ecl_nnc_export_get_size(grid, init_file), sizeof *nnc_data1); int count = ecl_nnc_export(grid, init_file, nnc_data1); int i; test_assert_int_equal( count , 0 ); @@ -113,8 +115,8 @@ void test_export(const char * name, bool have_tran_data) { ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * grid_file = ecl_file_open( grid_file_name , 0 ); ecl_file_type * init_file = ecl_file_open( init_file_name , 0); - ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); - ecl_nnc_type * nnc_data2 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data2 ); + ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc(ecl_nnc_export_get_size(grid, init_file), sizeof *nnc_data1); + ecl_nnc_type * nnc_data2 = (ecl_nnc_type *) util_calloc(ecl_nnc_export_get_size(grid, init_file), sizeof *nnc_data2); { @@ -214,23 +216,23 @@ void test_export(const char * name, bool have_tran_data) { } } - test_assert_int_equal( nnc_offset , ecl_nnc_export_get_size( grid )); + test_assert_int_equal(nnc_offset, ecl_nnc_export_get_size(grid, init_file )); ecl_nnc_sort( nnc_data1 , nnc_offset ); } { int export_size = ecl_nnc_export( grid , init_file , nnc_data2 ); - test_assert_int_equal( export_size , ecl_nnc_export_get_size( grid )); + test_assert_int_equal(export_size , ecl_nnc_export_get_size(grid, init_file)); } { int i; - int size = ecl_nnc_export_get_size( grid ); + int size = ecl_nnc_export_get_size(grid, init_file); for (i=0; i < size; i++) test_assert_int_equal( 0 , ecl_nnc_sort_cmp( &nnc_data1[i] , &nnc_data2[i])); } - for (int i =0; i < ecl_nnc_export_get_size( grid ); i++) + for (int i = 0; i < ecl_nnc_export_get_size(grid, init_file); i++) test_assert_true( ecl_nnc_equal( &nnc_data1[i] , &nnc_data2[i] )); { @@ -238,7 +240,7 @@ void test_export(const char * name, bool have_tran_data) { 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(grid, nnc_geo, view_file); - test_assert_int_equal( ecl_nnc_export_get_size( grid ), ecl_nnc_geometry_size( nnc_geo )); + test_assert_int_equal(ecl_nnc_export_get_size(grid, init_file), ecl_nnc_geometry_size(nnc_geo)); for (int i=0; i < ecl_nnc_geometry_size( nnc_geo ); i++) { const ecl_nnc_pair_type *nnc_pair = ecl_nnc_geometry_iget( nnc_geo , i ); ecl_nnc_type * nnc1 = &nnc_data1[i]; diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp index fb40436af0..61addc079a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_intersect.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_intersect.cpp new file mode 100644 index 0000000000..7a8113823d --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_intersect.cpp @@ -0,0 +1,117 @@ +/* + Copyright (C) 2018 Equinor ASA, Norway. + + The file 'ecl_nnc_export_intersect.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 + for more detals. +*/ +// #include +// #include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + + +namespace { + +const auto GRIDX = 10, GRIDY = 10, GRIDZ = 10; +const auto GRID_NNC_NUM = 342; +const auto INIT_NNC_NUM = 298; + + +ERT::ert_unique_ptr +make_intersect_grid() { + auto out = ERT::ert_unique_ptr( + ecl_grid_alloc_rectangular(GRIDX, GRIDY, GRIDZ, 1., 1., 1., nullptr) + ); + for(auto i = 0; i < GRID_NNC_NUM; ++i) + ecl_grid_add_self_nnc(out.get(), 2 * i + 1, 2 * i, i); + return out; +} + + +ERT::ert_unique_ptr +make_intersect_init_file() { + // Create keywords with useless data + auto nnc1_kw = ecl_kw_alloc(NNC1_KW, INIT_NNC_NUM, ECL_INT); + auto nnc2_kw = ecl_kw_alloc(NNC2_KW, INIT_NNC_NUM, ECL_INT); + auto tran_kw = ecl_kw_alloc(TRANNNC_KW, INIT_NNC_NUM, ECL_DOUBLE); + for(auto i = 0; i < INIT_NNC_NUM; ++i) { + ecl_kw_iset_int(nnc1_kw, i, 2 * i); + ecl_kw_iset_int(nnc2_kw, i, 2 * i + 1 ); + ecl_kw_iset_double(tran_kw, i, 2.5 * i); + } + + // write to file directly using fortio + auto init_filename = util_alloc_tmp_file("/tmp", "ecl_nnc_export_intersect_init_file", false); + auto fortio = fortio_open_writer(init_filename, false, ECL_ENDIAN_FLIP); + ecl_kw_fwrite(nnc1_kw, fortio); + ecl_kw_fwrite(nnc2_kw, fortio); + ecl_kw_fwrite(tran_kw, fortio); + fortio_fclose(fortio); + + // reopen the file as an ecl file + auto out = ERT::ert_unique_ptr( + ecl_file_open(init_filename, 0) + ); + + ecl_kw_free(nnc1_kw); + ecl_kw_free(nnc2_kw); + ecl_kw_free(tran_kw); + free(init_filename); + return out; +} +} /* unnamed namespace */ + + + +int main(int argc, char ** argv) { + util_install_signals(); + + const auto grid = make_intersect_grid(); + const auto init_file = make_intersect_init_file(); + + test_assert_true(ecl_nnc_intersect_format(grid.get(), init_file.get())); + test_assert_int_equal(ecl_nnc_export_get_size(grid.get(), init_file.get()), INIT_NNC_NUM); + + auto nnc_data = std::vector( + ecl_nnc_export_get_size(grid.get(), init_file.get()) + ); + auto const total_valid_trans = ecl_nnc_export(grid.get(), init_file.get(), nnc_data.data()); + test_assert_int_equal(total_valid_trans, INIT_NNC_NUM); + test_assert_int_equal(int(nnc_data.size()), INIT_NNC_NUM); + + for(auto i = 0; i < int(nnc_data.size()); ++i) { + auto const& nnc = nnc_data[i]; + test_assert_int_equal(nnc.grid_nr1, 0); + test_assert_int_equal(nnc.grid_nr2, 0); + test_assert_int_equal(nnc.global_index1, 2 * i); // as set in make_intersect_init_file() + test_assert_int_equal(nnc.global_index2, 2 * i + 1); // as set in make_intersect_init_file() + test_assert_double_equal(nnc.trans, 2.5 * i); // as set in make_intersect_init_file() + test_assert_int_equal(nnc.input_index, i); + } + + return 0; +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp index d457ee7b6b..25fb4e6633 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_nnc_geometry.c' is part of ERT - Ensemble based Reservoir Tool. @@ -36,7 +36,7 @@ void test_create_empty() { } void test_create_simple() { - test_work_area_type * work_area = test_work_area_alloc("nnc-INIT"); + ecl::util::TestArea ta("nnc_geometry"); { int nx = 10; int ny = 10; @@ -64,10 +64,10 @@ void test_create_simple() { fortio_fclose( f ); ecl_kw_free( trann_nnc ); } + ecl_nnc_geometry_free(nnc_geo); } ecl_grid_free( grid0 ); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp index dd4f2e616a..c464e6ee07 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_index_list.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp index cfec278eaa..35181b9549 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_index_list_grid.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp index dba5876244..8ddd77ddfd 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_info_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -53,6 +55,8 @@ void test_equal( ) { nnc_info_add_nnc( nnc_info1 , lgr_nr + 2 , 11 , 11 ); nnc_info_add_nnc( nnc_info2 , lgr_nr + 1 , 10 , 10 ); test_assert_true( nnc_info_equal( nnc_info1 , nnc_info2 )); + nnc_info_free( nnc_info1 ); + nnc_info_free( nnc_info2 ); } @@ -91,23 +95,22 @@ void basic_test() { nnc_vector_type * nnc_vector = nnc_info_get_vector( nnc_info , 1); - const int_vector_type * nnc_cells = nnc_info_get_grid_index_list(nnc_info, 1); - test_assert_int_equal(int_vector_size(nnc_cells), 2); - test_assert_ptr_equal( nnc_cells , nnc_vector_get_grid_index_list( nnc_vector )); + const std::vector& nnc_cells = nnc_info_get_grid_index_list(nnc_info, 1); + test_assert_int_equal(nnc_cells.size(), 2); + test_assert_ptr_equal( nnc_cells.data() , nnc_vector_get_grid_index_list( nnc_vector ).data()); nnc_vector_type * nnc_vector_null = nnc_info_get_vector( nnc_info , 2); - const int_vector_type * nnc_cells_null = nnc_info_get_grid_index_list(nnc_info, 2); - test_assert_NULL(nnc_cells_null); + test_assert_true( !nnc_info_has_grid_index_list(nnc_info, 2) ); test_assert_NULL(nnc_vector_null); nnc_vector_type * nnc_vector_self = nnc_info_get_self_vector( nnc_info ); const nnc_vector_type * nnc_vector_77 = nnc_info_get_vector( nnc_info , lgr_nr ); test_assert_ptr_equal( nnc_vector_77 , nnc_vector_self ); - const int_vector_type * nnc_cells_77 = nnc_info_get_grid_index_list(nnc_info, lgr_nr); - const int_vector_type * nnc_cells_self = nnc_info_get_self_grid_index_list(nnc_info); - test_assert_ptr_equal( nnc_cells_77 , nnc_cells_self ); + const std::vector& nnc_cells_77 = nnc_info_get_grid_index_list(nnc_info, lgr_nr); + const std::vector& nnc_cells_self = nnc_info_get_self_grid_index_list(nnc_info); + test_assert_ptr_equal( nnc_cells_77.data() , nnc_cells_self.data() ); test_assert_int_equal( 2 , nnc_info_get_size( nnc_info )); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp index 2827077c4e..4f807b6e50 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_nnc_pair.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp index 5a7d72d958..e84d672cbe 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,9 +18,12 @@ #include #include +#include + #include #include #include +#include #include #include @@ -55,9 +58,9 @@ void test_scan( const char * grid_filename) { if (g2 < ecl_grid_get_global_size( lgr )) { // Skipping matrix <-> fracture link in dual poro. const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( lgr , g1 ); - const int_vector_type * index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr); + const std::vector& index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr); test_assert_not_NULL( nnc_info ); - test_assert_int_not_equal( -1 , int_vector_index( index_list , g2 )); + test_assert_int_not_equal( -1 , vector_util_index( index_list , g2 )); } } } @@ -79,9 +82,9 @@ void test_scan( const char * grid_filename) { const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( ecl_grid , g ); test_assert_not_NULL( nnc_info ); { - const int_vector_type * index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr ); - test_assert_not_NULL( index_list ); - test_assert_int_not_equal( -1 , int_vector_index( index_list , l )); + const std::vector& index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr ); + test_assert_true(nnc_info_has_grid_index_list( nnc_info , lgr_nr ) ); + test_assert_int_not_equal( -1 , vector_util_index( index_list , l )); } } } @@ -102,9 +105,9 @@ void test_scan( const char * grid_filename) { const int g2 = ecl_kw_iget_int( nnc2_kw , i ) - 1; const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( lgr1 , g1 ); - const int_vector_type * index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr2); + const std::vector& index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr2); test_assert_not_NULL( nnc_info ); - test_assert_int_not_equal( -1 , int_vector_index( index_list , g2 )); + test_assert_int_not_equal( -1 , vector_util_index( index_list , g2 )); } } } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp index e568531756..7c12598534 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,6 +18,8 @@ #include #include +#include + #include #include @@ -41,17 +43,17 @@ void test_basic() { test_assert_int_equal( 6 , nnc_vector_get_size( vector )); { - const int_vector_type * grid_index_list = nnc_vector_get_grid_index_list( vector ); - const int_vector_type * nnc_index_list = nnc_vector_get_nnc_index_list( vector ); + const std::vector& grid_index_list = nnc_vector_get_grid_index_list( vector ); + const std::vector& nnc_index_list = nnc_vector_get_nnc_index_list( vector ); - test_assert_int_equal( 6 , int_vector_size( nnc_index_list )); - test_assert_int_equal( 1 , int_vector_iget( nnc_index_list , 0 )); - test_assert_int_equal( 6 , int_vector_iget( nnc_index_list , 5 )); + test_assert_int_equal( 6 , nnc_index_list.size() ); + test_assert_int_equal( 1 , nnc_index_list[0] ); + test_assert_int_equal( 6 , nnc_index_list[5] ); - test_assert_int_equal( 6 , int_vector_size( grid_index_list )); - test_assert_int_equal( 100 , int_vector_iget( grid_index_list , 0 )); - test_assert_int_equal( 200 , int_vector_iget( grid_index_list , 1 )); - test_assert_int_equal( 300 , int_vector_iget( grid_index_list , 2 )); + test_assert_int_equal( 6 , grid_index_list.size() ); + test_assert_int_equal( 100 , grid_index_list[0] ); + test_assert_int_equal( 200 , grid_index_list[1] ); + test_assert_int_equal( 300 , grid_index_list[2] ); } nnc_vector_free( vector ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp index 2ddf344fa3..98d0961b8a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_region.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp index 3402bf92fa..a5dcc685f0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_region2region.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp index f36d0297ea..3fbe747b50 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_restart_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp index fd7c698ae9..f7a9a18811 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_rft.c' is part of ERT - Ensemble based Reservoir Tool. @@ -40,10 +40,9 @@ void test_rft_read_write(const char * rft_file){ ecl_rft_node_type * old_node = ecl_rft_file_iget_node(rft, 0); ecl_rft_node_type * new_node = ecl_rft_node_alloc_new("DUMMY", "R", ecl_rft_node_get_date(old_node), ecl_rft_node_get_days(old_node)); nodes[2]=new_node; - test_work_area_type * work_area = test_work_area_alloc("RFT_RW"); + ecl::util::TestArea ta("rft"); ecl_rft_file_update("eclipse.rft", nodes,3, ECL_METRIC_UNITS); - test_work_area_free(work_area); free(nodes); } @@ -81,8 +80,6 @@ void test_rft( const char * rft_file ) { test_assert_ptr_equal( cell1 , cell2 ); } } - ecl_rft_node_inplace_sort_cells( rft_node ); - ecl_rft_file_free( rft ); } @@ -94,7 +91,6 @@ void test_plt_msw( const char * plt_file ) { test_assert_true( ecl_rft_node_is_PLT( plt_node )); test_assert_true( ecl_rft_node_is_MSW( plt_node )); test_assert_int_equal( 22 , ecl_rft_node_get_size( plt_node )); - ecl_rft_node_inplace_sort_cells( plt_node ); { int i; for (i=1; i < ecl_rft_node_get_size( plt_node ); i++) { @@ -143,7 +139,6 @@ void test_plt( const char * plt_file ) { test_assert_ptr_equal( cell1 , cell2 ); } - ecl_rft_node_inplace_sort_cells( plt_node ); } ecl_rft_file_free( plt ); @@ -159,7 +154,7 @@ void test_simple_load_rft(const char * filename) { int main( int argc , char ** argv) { const char * rft_file = argv[1]; const char * mode_string = argv[2]; - + util_install_signals(); if (strcmp( mode_string , "RFT") == 0) test_rft( rft_file ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp index 03e0be4bcc..cd9e82cbc0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp index 50d1bb6703..b708490790 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_rst_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -65,7 +65,7 @@ void test_file( const char * src_file , const char * target_file , int report_st void test_Xfile() { - test_work_area_type * work_area = test_work_area_alloc("rst-file"); + ecl::util::TestArea ta("xfile"); { fortio_type * f = fortio_open_writer( "TEST.X0010" , false , ECL_ENDIAN_FLIP); @@ -80,13 +80,12 @@ void test_Xfile() { fortio_fclose( f ); } test_file( "TEST.X0010" , "FILE.X0010" , 10 , 0 ); - test_work_area_free( work_area ); } void test_UNRST0() { - test_work_area_type * work_area = test_work_area_alloc("rst-file"); + ecl::util::TestArea ta("rst-file"); offset_type pos10; offset_type pos20; offset_type pos_end; @@ -118,12 +117,11 @@ void test_UNRST0() { test_file( "TEST.UNRST" , "FILE.UNRST" , 15 , pos20 ); test_file( "TEST.UNRST" , "FILE.UNRST" , 20 , pos20 ); test_file( "TEST.UNRST" , "FILE.UNRST" , 25 , pos_end ); - test_work_area_free( work_area ); } void test_UNRST1() { - test_work_area_type * work_area = test_work_area_alloc("rst-file"); + ecl::util::TestArea ta("rst-file"); offset_type pos5; offset_type pos10; offset_type pos20; @@ -158,7 +156,6 @@ void test_UNRST1() { test_file( "TEST.UNRST" , "FILE.UNRST" , 15 , pos20 ); test_file( "TEST.UNRST" , "FILE.UNRST" , 20 , pos20 ); test_file( "TEST.UNRST" , "FILE.UNRST" , 25 , pos_end ); - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp index c690d71535..ab551c685c 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_rst_header.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp index 6ee378897e..963ce03f41 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. @@ -23,28 +23,13 @@ #include #include -void test_sort( ecl_smspec_type * smspec ) -{ - int num_nodes = ecl_smspec_num_nodes( smspec ); - ecl_smspec_sort( smspec ); - test_assert_int_equal( num_nodes, ecl_smspec_num_nodes( smspec )); - - for (int i=1; i < ecl_smspec_num_nodes( smspec ); i++) { - const smspec_node_type * node1 = ecl_smspec_iget_node( smspec, i - 1 ); - const smspec_node_type * node2 = ecl_smspec_iget_node( smspec, i ); - test_assert_true( smspec_node_cmp( node1 , node2 ) <= 0 ); - - test_assert_int_equal( smspec_node_get_params_index( node1 ) , i - 1 ); - } -} - void test_copy(const ecl_smspec_type * smspec1) { ecl_sum_type * ecl_sum2 = ecl_sum_alloc_writer("CASE", false, true, ":", 0, true, 100, 100, 100); const ecl_smspec_type * smspec2 = ecl_sum_get_smspec(ecl_sum2); for (int i=0; i < ecl_smspec_num_nodes(smspec1); i++) { - const smspec_node_type * node = ecl_smspec_iget_node(smspec1, i); - ecl_sum_add_smspec_node(ecl_sum2, node); + const ecl::smspec_node& node = ecl_smspec_iget_node_w_node_index(smspec1, i); + ecl_sum_add_smspec_node(ecl_sum2, &node); } test_assert_true( ecl_smspec_equal(smspec1, smspec2)); ecl_sum_free(ecl_sum2); @@ -63,8 +48,6 @@ int main(int argc, char ** argv) { test_assert_false( ecl_smspec_equal( smspec1 , smspec2 )); test_assert_false( ecl_smspec_equal( smspec2 , smspec1 )); - test_sort( smspec1 ); - test_sort( smspec2 ); ecl_smspec_free( smspec1 ); ecl_smspec_free( smspec2 ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp index 7806fc8dec..bc0efbe740 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. @@ -25,94 +25,158 @@ #include +static void test_identify_rate_variable() { + const char* rate_vars[] = { + "WOPR" , "GGPR" , "FWPR" , "WLPR" , "WOIR" , "FGIR" , "GWIR" , + "WLIR" , "GGOR" , "FWCT" , "SOFR" , "SGFR" , "SWFR" , + }; + + const auto n_var = sizeof(rate_vars) / sizeof(rate_vars[0]); + + for (auto var = rate_vars, end = rate_vars + n_var; var != end; ++var) + test_assert_true(smspec_node_identify_rate(*var)); + + test_assert_false(smspec_node_identify_rate("SPR")); + test_assert_false(smspec_node_identify_rate("SOFT")); + test_assert_false(smspec_node_identify_rate("SGFT")); + test_assert_false(smspec_node_identify_rate("SWFT")); +} + +static void test_identify_total_variable() { + test_assert_true(smspec_node_identify_total("WOPT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GGPT", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FWPT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("RGIT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("CWIT", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WOPTF", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GOPTS", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FOIT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("ROVPT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("COVIT", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WMWT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GWVPT", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FWVIT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("RGMT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("CGPTF", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WSGT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GGST", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FFGT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("RGCT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("CGIMT", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WWGPT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GWGIT", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FEGT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("REXGT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("CGVPT", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WGVIT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GLPT", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FVPT", ECL_SMSPEC_FIELD_VAR)); + test_assert_true(smspec_node_identify_total("RVIT", ECL_SMSPEC_REGION_VAR)); + test_assert_true(smspec_node_identify_total("CNPT", ECL_SMSPEC_COMPLETION_VAR)); + + test_assert_true(smspec_node_identify_total("WNIT", ECL_SMSPEC_WELL_VAR)); + test_assert_true(smspec_node_identify_total("GCPT", ECL_SMSPEC_GROUP_VAR)); + test_assert_true(smspec_node_identify_total("FCIT", ECL_SMSPEC_FIELD_VAR)); + + test_assert_true(smspec_node_identify_total("SOFT", ECL_SMSPEC_SEGMENT_VAR)); + test_assert_true(smspec_node_identify_total("SGFT", ECL_SMSPEC_SEGMENT_VAR)); + test_assert_true(smspec_node_identify_total("SWFT", ECL_SMSPEC_SEGMENT_VAR)); + + test_assert_false(smspec_node_identify_total("SOPT", ECL_SMSPEC_SEGMENT_VAR)); + test_assert_false(smspec_node_identify_total("HEI!", ECL_SMSPEC_SEGMENT_VAR)); + test_assert_false(smspec_node_identify_total("xXx", ECL_SMSPEC_SEGMENT_VAR)); + test_assert_false(smspec_node_identify_total("SPR", ECL_SMSPEC_SEGMENT_VAR)); +} + + +void test_nums_default() { + ecl::smspec_node field_node( 0, "FOPT" , "UNIT" , 0); + ecl::smspec_node group_node( 0, "GOPR" , "G1", "UNIT" , 0, ":"); + ecl::smspec_node well_node( 0, "WOPR" , "W1", "UNIT" , 0, ":"); + + int default_nums = 0; + /* + The integer constant default nums corresponds to the symbol nums_unused + in smspec_node.cpp. It is duplicated here to avoid exporting it - it should + not really be a publically available symbol. + */ + + test_assert_int_equal( field_node.get_num(), default_nums); + test_assert_int_equal( group_node.get_num(), default_nums); + test_assert_int_equal( well_node.get_num(), default_nums); +} + + void test_cmp_types() { const int dims[3] = {10,10,10}; - smspec_node_type * field_node = smspec_node_alloc( ECL_SMSPEC_FIELD_VAR , NULL , "FOPT" , "UNIT" , ":" , dims , 0 , 0 , 0 ); - smspec_node_type * region_node = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * group_node = smspec_node_alloc( ECL_SMSPEC_GROUP_VAR , "G1" , "GOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * well_node = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * block_node = smspec_node_alloc( ECL_SMSPEC_BLOCK_VAR , NULL , "BPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * aquifer_node = smspec_node_alloc( ECL_SMSPEC_AQUIFER_VAR , NULL , "AAQP" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * segment_node = smspec_node_alloc( ECL_SMSPEC_SEGMENT_VAR , "W1" , "SGOR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * misc_node1 = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , NULL , "TIME" , "UNIT" , ":", dims, 10 , 0, 0); - smspec_node_type * misc_node2 = smspec_node_alloc( ECL_SMSPEC_MISC_VAR , NULL , "TCPU" , "UNIT" , ":", dims, 10 , 0, 0); + ecl::smspec_node field_node( 0, "FOPT" , "UNIT" , 0); + ecl::smspec_node region_node( 0, "RPR" , 10, "UNIT" , dims , 0 , ":"); + ecl::smspec_node group_node( 0, "GOPR" , "G1", "UNIT" , 0, ":"); + ecl::smspec_node well_node( 0, "WOPR" , "W1", "UNIT" , 0, ":"); + ecl::smspec_node block_node( 0, "BPR", 10, "UNIT", dims, 0, ":"); + ecl::smspec_node aquifer_node( 0, "AAQP" , 10, "UNIT" , dims, 0 , ":"); + ecl::smspec_node segment_node( 0, "SGOR" , "W1" , 10, "UNIT" , dims , 0 , ":"); + ecl::smspec_node misc_node1( 0, "TIME" , "UNIT", 0 ); + ecl::smspec_node misc_node2( 0, "TCPU", "UNIT", 0); - test_assert_int_equal( smspec_node_cmp( field_node , field_node ), 0); - test_assert_int_equal( smspec_node_cmp( region_node , region_node ), 0); - test_assert_int_equal( smspec_node_cmp( well_node , well_node ), 0); - test_assert_int_equal( smspec_node_cmp( group_node , group_node ), 0); - test_assert_int_equal( smspec_node_cmp( block_node , block_node ), 0); + test_assert_int_equal( field_node.cmp(field_node), 0); + test_assert_int_equal( region_node.cmp(region_node), 0); + test_assert_int_equal( well_node.cmp(well_node), 0); + test_assert_int_equal( group_node.cmp(group_node), 0); + test_assert_int_equal( block_node.cmp(block_node), 0); - test_assert_true( smspec_node_cmp( misc_node1 , field_node ) < 0 ); - test_assert_true( smspec_node_cmp( field_node , region_node ) < 0 ); - test_assert_true( smspec_node_cmp( region_node , group_node ) < 0 ); - test_assert_true( smspec_node_cmp( group_node , well_node ) < 0 ); - test_assert_true( smspec_node_cmp( well_node , segment_node ) < 0 ); - test_assert_true( smspec_node_cmp( segment_node , block_node ) < 0 ); - test_assert_true( smspec_node_cmp( block_node , aquifer_node) < 0 ); - test_assert_true( smspec_node_cmp( aquifer_node , misc_node2 ) < 0 ); + test_assert_true( misc_node1.cmp(field_node) < 0 ); + test_assert_true( field_node.cmp(region_node) < 0 ); + test_assert_true( region_node.cmp(group_node) < 0 ); + test_assert_true( group_node.cmp(well_node) < 0 ); + test_assert_true( well_node.cmp(segment_node) < 0 ); + test_assert_true( segment_node.cmp(block_node) < 0 ); + test_assert_true( block_node.cmp(aquifer_node)< 0 ); + test_assert_true( aquifer_node.cmp(misc_node2) < 0 ); - test_assert_true( smspec_node_cmp( field_node, misc_node1) > 0 ); - test_assert_true( smspec_node_cmp( misc_node2, aquifer_node) > 0 ); - test_assert_true( smspec_node_cmp( misc_node1, misc_node2) < 0 ); - test_assert_true( smspec_node_cmp( misc_node2, misc_node1) > 0 ); - - smspec_node_free( segment_node ); - smspec_node_free( aquifer_node ); - smspec_node_free( block_node ); - smspec_node_free( group_node ); - smspec_node_free( well_node ); - smspec_node_free( region_node ); - smspec_node_free( field_node ); - smspec_node_free( misc_node1 ); - smspec_node_free( misc_node2 ); + test_assert_true( field_node.cmp(misc_node1) > 0 ); + test_assert_true( misc_node2.cmp(aquifer_node) > 0 ); + test_assert_true( misc_node1.cmp(misc_node2) < 0 ); + test_assert_true( misc_node2.cmp(misc_node1) > 0 ); } void test_cmp_well() { - const int dims[3] = {10,10,10}; - smspec_node_type * well_node1_1 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * well_node1_2 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W2" , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * well_node2_1 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W1" , "WWCT" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * well_node2_2 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W2" , "WWWT" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * well_node_dummy = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , DUMMY_WELL , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); + ecl::smspec_node well_node1_1( 0 , "WOPR" ,"W1" , "UNIT" , 10 ,":"); + ecl::smspec_node well_node1_2( 0 , "WOPR" ,"W2" , "UNIT" , 10 ,":"); + ecl::smspec_node well_node2_1( 0 , "WWCT" ,"W1" , "UNIT" , 10 ,":"); + ecl::smspec_node well_node2_2( 0 , "WWWT" ,"W2" , "UNIT" , 10 ,":"); - test_assert_NULL( well_node_dummy); - test_assert_int_equal( smspec_node_cmp( well_node1_1 , well_node1_1 ), 0); - test_assert_int_equal( smspec_node_cmp( well_node2_2 , well_node2_2 ), 0); + test_assert_int_equal( well_node1_1.cmp(well_node1_1), 0); + test_assert_int_equal( well_node2_2.cmp(well_node2_2), 0); - test_assert_true( smspec_node_cmp( well_node1_1, well_node1_2) < 0 ); - test_assert_true( smspec_node_cmp( well_node1_1, well_node2_1) < 0 ); - test_assert_true( smspec_node_cmp( well_node1_1, well_node2_2) < 0 ); + test_assert_true( well_node1_1.cmp(well_node1_2)< 0 ); + test_assert_true( well_node1_1.cmp(well_node2_1)< 0 ); + test_assert_true( well_node1_1.cmp(well_node2_2)< 0 ); - test_assert_true( smspec_node_cmp( well_node1_2, well_node1_1) > 0 ); - test_assert_true( smspec_node_cmp( well_node1_2, well_node2_1) < 0 ); - - smspec_node_free( well_node1_1 ); - smspec_node_free( well_node2_1 ); - smspec_node_free( well_node1_2 ); - smspec_node_free( well_node2_2 ); + test_assert_true( well_node1_2.cmp(well_node1_1)> 0 ); + test_assert_true( well_node1_2.cmp(well_node2_1)< 0 ); } void test_cmp_region() { const int dims[3] = {10,10,10}; - smspec_node_type * region_node1_1 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "ROIP" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * region_node1_2 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "ROIP" , "UNIT" , ":" , dims , 11 , 0 , 0 ); - smspec_node_type * region_node2_1 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); - smspec_node_type * region_node2_2 = smspec_node_alloc( ECL_SMSPEC_REGION_VAR , NULL , "RPR" , "UNIT" , ":" , dims , 12 , 0 , 0 ); + ecl::smspec_node region_node1_1( 0, "ROIP" , 10 ,"UNIT" , dims , 0 , ":" ); + ecl::smspec_node region_node1_2( 0, "ROIP" , 11 ,"UNIT" , dims , 0 , ":" ); + ecl::smspec_node region_node2_1( 0, "RPR" , 10 ,"UNIT" , dims , 0 , ":" ); + ecl::smspec_node region_node2_2( 0, "RPR" , 12 ,"UNIT" , dims , 0 , ":" ); - test_assert_true( smspec_node_cmp( region_node1_1, region_node1_2) < 0 ); - test_assert_true( smspec_node_cmp( region_node1_1, region_node2_1) < 0 ); - test_assert_true( smspec_node_cmp( region_node1_1, region_node2_2) < 0 ); + test_assert_true( region_node1_1.cmp(region_node1_2)< 0 ); + test_assert_true( region_node1_1.cmp(region_node2_1)< 0 ); + test_assert_true( region_node1_1.cmp(region_node2_2)< 0 ); - test_assert_true( smspec_node_cmp( region_node1_2, region_node1_1) > 0 ); - test_assert_true( smspec_node_cmp( region_node1_2, region_node2_1) < 0 ); - - smspec_node_free( region_node1_1 ); - smspec_node_free( region_node2_1 ); - smspec_node_free( region_node1_2 ); - smspec_node_free( region_node2_2 ); + test_assert_true( region_node1_2.cmp(region_node1_1)> 0 ); + test_assert_true( region_node1_2.cmp(region_node2_1)< 0 ); } @@ -121,4 +185,7 @@ int main(int argc, char ** argv) { test_cmp_types(); test_cmp_well(); test_cmp_region( ); + test_identify_rate_variable(); + test_identify_total_variable(); + test_nums_default(); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index 3eb32c2f5a..ae98f6acb4 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -3,6 +3,7 @@ #include #include +#include ecl_sum_type * test_alloc_ecl_sum() { time_t start_time = util_make_date_utc( 1,1,2010 ); @@ -12,16 +13,16 @@ ecl_sum_type * test_alloc_ecl_sum() { int num_dates = 4; double ministep_length = 86400; // seconds in a day - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); for (int report_step = 0; report_step < num_dates; report_step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , report_step*2.0 ); - ecl_sum_tstep_set_from_node( tstep , node2 , report_step*4.0 + 2.0 ); - ecl_sum_tstep_set_from_node( tstep , node3 , report_step*6.0 + 4.0 ); + ecl_sum_tstep_set_from_node( tstep , *node1 , report_step*2.0 ); + ecl_sum_tstep_set_from_node( tstep , *node2 , report_step*4.0 + 2.0 ); + ecl_sum_tstep_set_from_node( tstep , *node3 , report_step*6.0 + 4.0 ); } sim_seconds += ministep_length * 3; @@ -37,19 +38,19 @@ void test_correct_time_vector() { time_t_vector_append(t, util_make_date_utc( 4,1,2010 )); time_t_vector_append(t, util_make_date_utc( 6,1,2010 )); time_t_vector_append(t, util_make_date_utc( 8,1,2010 )); - ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t); + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t, false, false); test_assert_int_equal( ecl_sum_get_report_time(ecl_sum_resampled, 2) , util_make_date_utc( 6,1,2010 )); const ecl_smspec_type * smspec_resampled = ecl_sum_get_smspec(ecl_sum_resampled); - const smspec_node_type * node1 = ecl_smspec_iget_node(smspec_resampled, 1); - const smspec_node_type * node2 = ecl_smspec_iget_node(smspec_resampled, 2); - const smspec_node_type * node3 = ecl_smspec_iget_node(smspec_resampled, 3); - test_assert_string_equal( "BPR" , smspec_node_get_keyword(node2) ); - test_assert_string_equal( "BARS" , smspec_node_get_unit(node2) ); + const ecl::smspec_node& node1 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 1); + const ecl::smspec_node& node2 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 2); + const ecl::smspec_node& node3 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 3); + test_assert_string_equal( "BPR" , smspec_node_get_keyword(&node2) ); + test_assert_string_equal( "BARS" , smspec_node_get_unit(&node2) ); - test_assert_double_equal(3.33333, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 6,1,2010 ), node1) ); - test_assert_double_equal(3.33333, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 2,1,2010 ), node2) ); - test_assert_double_equal(10.0000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4,1,2010 ), node3) ); + test_assert_double_equal(3.33333, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 6,1,2010 ), &node1) ); + test_assert_double_equal(3.33333, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 2,1,2010 ), &node2) ); + test_assert_double_equal(10.0000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4,1,2010 ), &node3) ); ecl_sum_free(ecl_sum_resampled); @@ -57,23 +58,38 @@ void test_correct_time_vector() { ecl_sum_free(ecl_sum); } -void test_time_before() { - ecl_sum_type * ecl_sum = test_alloc_ecl_sum(); - time_t_vector_type * t = time_t_vector_alloc( 0 , 0 ); - time_t_vector_append(t, util_make_date_utc( 1,1,2009 )); - test_assert_NULL( ecl_sum_alloc_resample(ecl_sum, "kk", t) ); - time_t_vector_free(t); - ecl_sum_free(ecl_sum); -} -void test_time_after() { - ecl_sum_type * ecl_sum = test_alloc_ecl_sum(); - time_t_vector_type * t = time_t_vector_alloc( 0 , 0 ); - time_t_vector_append(t, util_make_date_utc( 1,1,2010 )); - time_t_vector_append(t, util_make_date_utc( 11,1,2010 )); - test_assert_NULL( ecl_sum_alloc_resample(ecl_sum, "kk", t) ); - time_t_vector_free(t); - ecl_sum_free(ecl_sum); +void test_resample_extrapolate_rate() { + + ecl_sum_type * ecl_sum = test_alloc_ecl_sum(); + + time_t_vector_type * t = time_t_vector_alloc( 0 , 0 ); + time_t_vector_append(t, util_make_date_utc( 1,1,2009 )); + time_t_vector_append(t, util_make_date_utc( 4,1,2010 )); + time_t_vector_append(t, util_make_date_utc( 12,1,2010 )); + + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t, true, true); + + + const ecl_smspec_type * smspec_resampled = ecl_sum_get_smspec(ecl_sum_resampled); + const ecl::smspec_node& node1 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 1); + const ecl::smspec_node& node3 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 3); + + + //testing extrapolation for rate wrt. 3 dates: lower, inside and upper + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 1, 1, 2009), &node3)); + test_assert_double_equal(10.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4, 1, 2010), &node3)); + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1, 2010), &node3)); + + //testing extrapolation for variable wrt. 3 dates: lower, inside and upper + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 1, 1, 2009 ), &node1) ); + test_assert_double_equal(2.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4, 1,2010 ), &node1) ); + test_assert_double_equal(6.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1,2010 ), &node1) ); + + + ecl_sum_free(ecl_sum_resampled); + time_t_vector_free(t); + ecl_sum_free(ecl_sum); } void test_not_sorted() { @@ -82,7 +98,7 @@ void test_not_sorted() { time_t_vector_append(t, util_make_date_utc( 1,1,2010 )); time_t_vector_append(t, util_make_date_utc( 3,1,2010 )); time_t_vector_append(t, util_make_date_utc( 2,1,2010 )); - test_assert_NULL( ecl_sum_alloc_resample( ecl_sum, "kk", t) ); + test_assert_NULL( ecl_sum_alloc_resample( ecl_sum, "kk", t, false, false) ); time_t_vector_free(t); ecl_sum_free(ecl_sum); } @@ -90,8 +106,7 @@ void test_not_sorted() { int main() { test_correct_time_vector(); - test_time_before(); - test_time_after(); + test_resample_extrapolate_rate(); test_not_sorted(); return 0; } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp index ed43da456d..a9f852388d 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_sum_case_exists.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp index 9a4e569894..3de2dd13a7 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp @@ -5,16 +5,21 @@ #include #include +#include +#include +#include +#include #include +#include /* CASE1 --------- -1 : BPR:1 100 200 300 400 -2 : BPR:2 110 210 310 410 -3 : BRP:3 120 220 320 430 +1 : BPR:1 100 200 300 400 500 600 700 800 900 .... +2 : BPR:2 110 210 310 410 510 610 710 810 910 .... +3 : BRP:3 120 220 320 420 520 620 720 820 920 .... @@ -51,13 +56,14 @@ Total CASE3: #define ieq(d,i,v) test_assert_double_equal(double_vector_iget(d,(i)), v) -void verify_CASE1() { +void verify_CASE1(int length) { ecl_sum_type * sum = ecl_sum_fread_alloc_case("CASE1", ":"); + int params_size = 4; // TIME, BPR:1, BPR:2, BPR:3 - for (int i=1; i < 4; i++) { + for (int i=1; i < params_size; i++) { double_vector_type * d = ecl_sum_alloc_data_vector(sum, i, false); - //test_assert_int_equal(4, double_vector_size(d)); - for (int j=0; j < 4; j++) { + test_assert_int_equal(length, double_vector_size(d)); + for (int j=0; j < length; j++) { test_assert_double_equal( double_vector_iget(d, j), (i - 1)*10 + (j + 1)*100); } double_vector_free(d); @@ -72,37 +78,38 @@ void write_CASE1(bool unified) { ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( "CASE1" , false , unified, ":" , start_time , true , 10 , 10 , 10 ); double sim_seconds = 0; - int num_dates = 4; + int num_dates = 100; double ministep_length = 86400; // seconds in a day - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); for (int report_step = 0; report_step < num_dates; report_step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , (1 + report_step) * 100 ); - ecl_sum_tstep_set_from_node( tstep , node2 , (1 + report_step) * 100 + 10.0 ); - ecl_sum_tstep_set_from_node( tstep , node3 , (1 + report_step) * 100 + 20.0 ); + ecl_sum_tstep_set_from_node( tstep , *node1 , (1 + report_step) * 100 ); + ecl_sum_tstep_set_from_node( tstep , *node2 , (1 + report_step) * 100 + 10.0 ); + ecl_sum_tstep_set_from_node( tstep , *node3 , (1 + report_step) * 100 + 20.0 ); } sim_seconds += ministep_length * 3; } ecl_sum_fwrite( ecl_sum ); ecl_sum_free(ecl_sum); - verify_CASE1(); + verify_CASE1(num_dates); } -void verify_CASE2() { +void verify_CASE2(int length) { ecl_sum_type * sum = ecl_sum_fread_alloc_case2__("CASE2", ":", false, true, 0); + const int params_size = 2; // TIME, BPR:2, BPR:1 - for (int i=0; i < 2; i++) { + for (int i=0; i < params_size; i++) { double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); - //test_assert_int_equal(4, double_vector_size(d)); - for (int j=1; j < 4; j++) + test_assert_int_equal(length, double_vector_size(d)); + for (int j=1; j < length; j++) test_assert_double_equal( double_vector_iget(d, j-1), (1 - i)*100 + j*1000); double_vector_free(d); } @@ -111,9 +118,9 @@ void verify_CASE2() { sum = ecl_sum_fread_alloc_case("CASE2", ":"); - for (int i=0; i < 2; i++) { + for (int i=0; i < params_size; i++) { double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); - //test_assert_int_equal(double_vector_size(d), 7); + test_assert_int_equal(double_vector_size(d), 7); ieq(d,0,(1 - i)*10 + 100); ieq(d,1,(1 - i)*10 + 200); ieq(d,2,(1 - i)*10 + 300); @@ -137,30 +144,31 @@ void write_CASE2(bool unified) { double sim_seconds = ministep_length * 2.5 * 3; ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( "CASE2" , "CASE1", false , true , ":" , start_time , true , 10 , 10 , 10 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); for (int report_step = 1; report_step <= num_dates; report_step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 3 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , report_step*1000); - ecl_sum_tstep_set_from_node( tstep , node2 , report_step*1000 + 100); + ecl_sum_tstep_set_from_node( tstep , *node1 , report_step*1000); + ecl_sum_tstep_set_from_node( tstep , *node2 , report_step*1000 + 100); } sim_seconds += ministep_length * 3; } ecl_sum_fwrite( ecl_sum ); ecl_sum_free(ecl_sum); - verify_CASE2(); + verify_CASE2(num_dates); } } -void verify_CASE3() { +void verify_CASE3(int length) { + const int params_size = 3; ecl_sum_type * sum = ecl_sum_fread_alloc_case2__("CASE3", ":", false, true, 0); - for (int i=0; i < 3; i++) { + for (int i=0; i < params_size; i++) { double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); - //test_assert_int_equal(4, double_vector_size(d)); - for (int j=0; j < 4; j++) { + test_assert_int_equal(length, double_vector_size(d)); + for (int j=0; j < length; j++) { test_assert_double_equal( double_vector_iget(d, j), (2 - i)*1000 + (j + 1)*10000); } double_vector_free(d); @@ -168,15 +176,15 @@ void verify_CASE3() { ecl_sum_free(sum); sum = ecl_sum_fread_alloc_case("CASE3", ":"); - for (int i=0; i < 3; i++) { + for (int i=0; i < params_size; i++) { double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); ieq(d,0,(2 - i)*10 + 100); ieq(d,1,(2 - i)*10 + 200); ieq(d,2,(2 - i)*10 + 300); if (i == 0) { - const smspec_node_type * node = ecl_smspec_iget_node(ecl_sum_get_smspec(sum), i); - double default_value = smspec_node_get_default(node); + const ecl::smspec_node& node = ecl_smspec_iget_node_w_params_index(ecl_sum_get_smspec(sum), i); + double default_value = node.get_default(); ieq(d,3,default_value); ieq(d,4,default_value); } else { @@ -190,12 +198,16 @@ void verify_CASE3() { double_vector_free(d); } + ecl_sum_vector_type * vector = ecl_sum_vector_alloc(sum, true); + double frame[27]; //3 vectors X 9 data points pr. vector + ecl_sum_init_double_frame(sum, vector, frame); + ecl_sum_vector_free(vector); + ecl_sum_free(sum); } void write_CASE3(bool unified) { - test_work_area_type * work_area = test_work_area_alloc("SMSPEC"); write_CASE2(unified); { time_t start_time = util_make_date_utc( 1,1,2010 ); @@ -204,29 +216,103 @@ void write_CASE3(bool unified) { double sim_seconds = ministep_length * 4.0 * 3; ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( "CASE3" , "CASE2", false , true , ":" , start_time , true , 10 , 10 , 10 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); for (int report_step = 1; report_step <= num_dates; report_step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 5 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , report_step*10000); - ecl_sum_tstep_set_from_node( tstep , node2 , report_step*10000 + 1000); - ecl_sum_tstep_set_from_node( tstep , node3 , report_step*10000 + 2000); + ecl_sum_tstep_set_from_node( tstep , *node1 , report_step*10000); + ecl_sum_tstep_set_from_node( tstep , *node2 , report_step*10000 + 1000); + ecl_sum_tstep_set_from_node( tstep , *node3 , report_step*10000 + 2000); } sim_seconds += ministep_length * 3; } ecl_sum_fwrite( ecl_sum ); ecl_sum_free(ecl_sum); - verify_CASE3(); + verify_CASE3(num_dates); } - test_work_area_free(work_area); } +void verify_CASE4() { + ecl_sum_type * sum = ecl_sum_fread_alloc_case("CASE4", ":"); + + double_vector_type * d; + d = ecl_sum_alloc_data_vector(sum, 0, false); double_vector_free(d); + d = ecl_sum_alloc_data_vector(sum, 1, false); double_vector_free(d); + d = ecl_sum_alloc_data_vector(sum, 2, false); double_vector_free(d); + d = ecl_sum_alloc_data_vector(sum, 4, false); + ieq(d, 0, -99); + ieq(d, 4, -99); + ieq(d, 5, 10000); + ieq(d, 8, 40000); + double_vector_free(d); + + ecl_sum_vector_type * vector = ecl_sum_vector_alloc(sum, true); + double frame[27]; //3 vectors X 9 data points pr. vector + ecl_sum_init_double_frame(sum, vector, frame); + test_assert_double_equal(frame[26], 40000); + ecl_sum_vector_free(vector); + + ecl_sum_free(sum); +} + + +void write_CASE4(bool unified) { + ecl::util::TestArea ta("case4"); + write_CASE3(unified); + { + ecl_file_type * sum_file = ecl_file_open("CASE3.UNSMRY", 0); + ecl_file_type * smspec_file = ecl_file_open("CASE3.SMSPEC", 0); + + ecl_kw_type * keywords = ecl_file_iget_named_kw(smspec_file, "KEYWORDS", 0); + ecl_kw_resize(keywords, 5); + ecl_kw_iset_char_ptr(keywords, 3, "WTPRWI1"); + ecl_kw_iset_char_ptr(keywords, 4, "BPR"); + + ecl_kw_type * nums = ecl_file_iget_named_kw(smspec_file, "NUMS", 0); + ecl_kw_resize(nums, 5); + unsigned int * nums_ptr = (unsigned int *)ecl_kw_get_int_ptr(nums); + nums_ptr[3] = 5; + nums_ptr[4] = 8; //a different + + ecl_kw_type * wgnames = ecl_file_iget_named_kw(smspec_file, "WGNAMES", 0); + ecl_kw_resize(wgnames, 5); + ecl_kw_iset_char_ptr(wgnames, 4, ":+:+:+:+"); + + ecl_kw_type * units = ecl_file_iget_named_kw(smspec_file, "UNITS", 0); + ecl_kw_resize(units, 5); + ecl_kw_iset_char_ptr(units, 4, "BARS"); + + int num_params = ecl_file_get_num_named_kw(sum_file, "PARAMS"); + for (int i = 0; i < num_params; i++) { + ecl_kw_type * params_kw = ecl_file_iget_named_kw(sum_file, "PARAMS", i); + ecl_kw_resize(params_kw, 5); + float * ptr = (float*)ecl_kw_get_void_ptr(params_kw); + ptr[4] = ptr[3]; + ptr[3] = -1; + } + + fortio_type * f; + const char * filename_sum = "CASE4.UNSMRY"; + f = fortio_open_writer( filename_sum, false, ECL_ENDIAN_FLIP ); + ecl_file_fwrite_fortio(sum_file, f, 0); + fortio_fclose( f ); + + const char * filename_smspec = "CASE4.SMSPEC"; + f = fortio_open_writer( filename_smspec, false, ECL_ENDIAN_FLIP ); + ecl_file_fwrite_fortio(smspec_file, f, 0); + fortio_fclose( f ); + + ecl_file_close(smspec_file); + ecl_file_close(sum_file); + verify_CASE4(); + } +} int main() { - write_CASE3(true); - write_CASE3(false); + write_CASE4(true); + write_CASE4(false); return 0; } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp index 4cd4b1ece4..673755d55b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp index d9b30efa0e..93f8b3f572 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_restart.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_restart.cpp new file mode 100644 index 0000000000..aa247fcd29 --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_restart.cpp @@ -0,0 +1,167 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +/* + +CASE1 +--------- +1 : BPR:1 100 200 300 400 500 600 700 800 900 .... +2 : BPR:2 110 210 310 410 510 610 710 810 910 .... +3 : BRP:3 120 220 320 420 520 620 720 820 920 .... + + + +CASE2 +--------- +1 : BRP:2 1100 2100 3100 4100 +2 : BPR:1 1000 2000 3000 4000 + + + +Total CASE2: +------------ +1 : BPR:2 110 210 310 1100 2100 3100 4100 +2 : BRP:1 100 200 300 1000 2000 3000 4000 + + + +CASE3 +----- +1 : BPR:3 12000 22000 32000 42000 +2 : BRP:2 11000 21000 31000 41000 +3 : BPR:1 10000 20000 30000 40000 + + +Total CASE3: +------------ +1 : BPR:3 120 220 320 0 0 12000 22000 32000 42000 +2 : BPR:2 110 210 310 1100 2100 11000 21000 31000 41000 +3 : BPR:1 100 200 300 1000 2000 10000 20000 30000 40000 + +*/ + + +#define ieq(d,i,v) test_assert_double_equal(double_vector_iget(d,(i)), v) + + +void verify_CASE1(int length) { + ecl_sum_type * sum = ecl_sum_fread_alloc_case("CASE1", ":"); + int params_size = 4; // TIME, BPR:1, BPR:2, BPR:3 + + for (int i=1; i < params_size; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i, false); + test_assert_int_equal(length, double_vector_size(d)); + for (int j=0; j < length; j++) { + test_assert_double_equal( double_vector_iget(d, j), (i - 1)*10 + (j + 1)*100); + } + double_vector_free(d); + } + ecl_sum_free(sum); +} + + +void verify_CASE2(int length) { + ecl_sum_type * sum = ecl_sum_fread_alloc_case2__("CASE2", ":", false, true, 0); + const int params_size = 2; // TIME, BPR:2, BPR:1 + + for (int i=0; i < params_size; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + test_assert_int_equal(length, double_vector_size(d)); + for (int j=1; j < length; j++) + test_assert_double_equal( double_vector_iget(d, j-1), (1 - i)*100 + j*1000); + double_vector_free(d); + } + + ecl_sum_free(sum); + + sum = ecl_sum_fread_alloc_case("CASE2", ":"); + for (int i=0; i < params_size; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + test_assert_int_equal(double_vector_size(d), 4); + ieq(d,0,(1 - i)*100 + 1000); + ieq(d,1,(1 - i)*100 + 2000); + ieq(d,2,(1 - i)*100 + 3000); + ieq(d,3,(1 - i)*100 + 4000); + double_vector_free(d); + } + + ecl_sum_free(sum); +} + + +void write_CASE1(bool unified) { + time_t start_time = util_make_date_utc( 1,1,2010 ); + ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( "CASE1" , false , unified, ":" , start_time , true , 10 , 10 , 10 ); + double sim_seconds = 0; + + int num_dates = 100; + double ministep_length = 86400; // seconds in a day + + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); + + for (int report_step = 0; report_step < num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node1 , (1 + report_step) * 100 ); + ecl_sum_tstep_set_from_node( tstep , *node2 , (1 + report_step) * 100 + 10.0 ); + ecl_sum_tstep_set_from_node( tstep , *node3 , (1 + report_step) * 100 + 20.0 ); + } + sim_seconds += ministep_length * 3; + } + ecl_sum_fwrite( ecl_sum ); + ecl_sum_free(ecl_sum); + + verify_CASE1(num_dates); +} + + + + +void write_CASE2() { + bool unified = false; + write_CASE1(unified); + { + time_t start_time = util_make_date_utc( 1,1,2010 ); + int num_dates = 4; + double ministep_length = 86400; // seconds in a day + double sim_seconds = ministep_length * 2.5 * 3; + ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( "CASE2" , "CASE1", false , true , ":" , start_time , true , 10 , 10 , 10 ); + + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + + for (int report_step = 1; report_step <= num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 3 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node1 , report_step*1000); + ecl_sum_tstep_set_from_node( tstep , *node2 , report_step*1000 + 100); + } + sim_seconds += ministep_length * 3; + } + ecl_sum_fwrite( ecl_sum ); + ecl_sum_free(ecl_sum); + + util_unlink("CASE1.SMSPEC"); + + verify_CASE2(num_dates); + } +} + +int main() { + write_CASE2(); + return 0; +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp index 9b049bdb79..58d6f693be 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp index 2fb3abb4c9..9db9f9f4d6 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_sum_writer.c' is part of ERT - Ensemble based Reservoir Tool. @@ -32,10 +32,13 @@ double write_summary( const char * name , time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) { ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( name , false , true , ":" , start_time , true , nx , ny , nz ); double sim_seconds = 0; + ecl_smspec_type * smspec = ecl_sum_get_smspec( ecl_sum ); - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); + test_assert_int_equal( ecl_smspec_get_params_size( smspec ), 1); + const ecl::smspec_node * node1 = ecl_smspec_add_node( smspec , "FOPT" , "Barrels", 99.0); + const ecl::smspec_node * node2 = ecl_smspec_add_node( smspec , "BPR" , 567 , "BARS", 0.0 ); + const ecl::smspec_node * node3 = ecl_smspec_add_node( smspec , "WWCT" , "OP-1" , "(1)" , 0.0 ); + test_assert_int_equal( ecl_smspec_get_params_size( smspec ), 4); for (int report_step = 0; report_step < num_dates; report_step++) { for (int step = 0; step < num_ministep; step++) { @@ -43,13 +46,13 @@ double write_summary( const char * name , time_t start_time , int nx , int ny , { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node2 , 10*sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node3 , 100*sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node1 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node2 , 10*sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node3 , 100*sim_seconds ); - test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , node1 ), sim_seconds ); - test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , node2 ), sim_seconds*10 ); - test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , node3 ), sim_seconds*100 ); + test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , *node1 ), sim_seconds ); + test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , *node2 ), sim_seconds*10 ); + test_assert_double_equal( ecl_sum_tstep_get_from_node( tstep , *node3 ), sim_seconds*100 ); } sim_seconds += ministep_length; } @@ -61,20 +64,20 @@ double write_summary( const char * name , time_t start_time , int nx , int ny , int write_restart_summary(const char * name, const char * restart_name , int start_report_step, double sim_seconds, time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) { ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( name , restart_name, false , true , ":" , start_time , true , nx , ny , nz ); + ecl_smspec_type * smspec = ecl_sum_get_smspec( ecl_sum ); - - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); + const ecl::smspec_node * node1 = ecl_smspec_add_node( smspec , "FOPT", "Barrels" , 99.0 ); + const ecl::smspec_node * node2 = ecl_smspec_add_node( smspec , "BPR" , 567 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_smspec_add_node( smspec , "WWCT" , "OP-1" , "(1)", 0.0 ); int num_report_steps = start_report_step + num_dates; for (int report_step = start_report_step; report_step < num_report_steps; report_step++) { for (int step = 0; step < num_ministep; step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , sim_seconds); - ecl_sum_tstep_set_from_node( tstep , node2 , 10*sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node3 , 100*sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node1 , sim_seconds); + ecl_sum_tstep_set_from_node( tstep , *node2 , 10*sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , *node3 , 100*sim_seconds ); } sim_seconds += ministep_length; @@ -97,17 +100,24 @@ void test_write_read( ) { int num_ministep = 10; double ministep_length = 86400; // Seconds - numerical value chosen to avoid rounding problems when converting between seconds and days. { - test_work_area_type * work_area = test_work_area_alloc("sum/write"); ecl_sum_type * ecl_sum; - write_summary( name , start_time , nx , ny , nz , num_dates , num_ministep , ministep_length); + auto seconds = write_summary( name , start_time , nx , ny , nz , num_dates , num_ministep , ministep_length); ecl_sum = ecl_sum_fread_alloc_case( name , ":" ); test_assert_true( ecl_sum_is_instance( ecl_sum )); + printf("days: %g \n", seconds / 86400.0 ); + /* Time direction */ test_assert_time_t_equal( start_time , ecl_sum_get_start_time(ecl_sum)); test_assert_time_t_equal( start_time , ecl_sum_get_data_start(ecl_sum)); util_inplace_forward_seconds_utc(&end_time, (num_dates * num_ministep - 1) * ministep_length ); + { + time_t et = ecl_sum_get_end_time(ecl_sum); + printf("days: %g \n", 1.0 * (et - start_time) / 86400); + printf("days: %g \n", 1.0 * (end_time - start_time) / 86400); + printf("%ld %ld diff:%ld fraction:%g \n", end_time, et, end_time - et , 1.0 * et / end_time); + } test_assert_time_t_equal( end_time , ecl_sum_get_end_time(ecl_sum)); /* Keys */ @@ -126,14 +136,13 @@ void test_write_read( ) { } ecl_sum_free( ecl_sum ); - test_work_area_free( work_area ); + //test_work_area_free( work_area ); } } void test_ecl_sum_alloc_restart_writer() { - - test_work_area_type * work_area = test_work_area_alloc("sum_write_restart"); + ecl::util::TestArea ta("sum_write_restart"); { const char * name1 = "CASE1"; const char * name2 = "CASE2"; @@ -170,7 +179,6 @@ void test_ecl_sum_alloc_restart_writer() { ecl_file_close(restart_file); } - test_work_area_free( work_area ); } @@ -182,7 +190,7 @@ void test_long_restart_names() { strcat(restart_case, s); } const char * name = "THE_CASE"; - test_work_area_type * work_area = test_work_area_alloc("sum_write_restart_long_name"); + ecl::util::TestArea ta("suM_write_restart_long_name"); { int restart_step = 77; time_t start_time = util_make_date_utc( 1,1,2010 ); @@ -210,12 +218,10 @@ void test_long_restart_names() { ecl_smspec_free( smspec); } } - - test_work_area_free( work_area ); - } int main( int argc , char ** argv) { + util_install_signals(); test_write_read(); test_ecl_sum_alloc_restart_writer(); test_long_restart_names(); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp index 55606a6ffa..e142b78cab 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp @@ -17,16 +17,16 @@ ecl_sum_type * write_ecl_sum() { int num_dates = 4; double ministep_length = 86400; // seconds in a day - smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); - smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); - smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); + const ecl::smspec_node * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); + const ecl::smspec_node * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); + const ecl::smspec_node * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); for (int report_step = 0; report_step < num_dates; report_step++) { { ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); - ecl_sum_tstep_set_from_node( tstep , node1 , report_step*2.0 ); - ecl_sum_tstep_set_from_node( tstep , node2 , report_step*4.0 + 2.0 ); - ecl_sum_tstep_set_from_node( tstep , node3 , report_step*6.0 + 4.0 ); + ecl_sum_tstep_set_from_node( tstep , *node1 , report_step*2.0 ); + ecl_sum_tstep_set_from_node( tstep , *node2 , report_step*4.0 + 2.0 ); + ecl_sum_tstep_set_from_node( tstep , *node3 , report_step*6.0 + 4.0 ); } sim_seconds += ministep_length * 3; @@ -36,7 +36,7 @@ ecl_sum_type * write_ecl_sum() { } void test_load() { - test_work_area_type * work_area = test_work_area_alloc("unsmry_loader"); + ecl::util::TestArea ta("ecl_sum_loader"); ecl_sum_type * ecl_sum = write_ecl_sum(); test_assert_true( util_file_exists("CASE.SMSPEC") ); test_assert_true( util_file_exists("CASE.UNSMRY") ); @@ -52,7 +52,6 @@ void test_load() { delete loader; ecl_sum_free(ecl_sum); - test_work_area_free(work_area); } int main() { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp index 65bc7d58fd..afc25cb970 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. The file 'ecl_util_filenames.c' is part of ERT - Ensemble based Reservoir Tool. @@ -33,14 +33,21 @@ void test_filename_report_nr() { } void test_filename_case() { - test_assert_NULL( ecl_util_alloc_filename(NULL, "mixedBase", ECL_EGRID_FILE, false, -1)); - test_assert_string_equal( ecl_util_alloc_filename(NULL, "UPPER", ECL_EGRID_FILE, false, -1), "UPPER.EGRID"); - test_assert_string_equal( ecl_util_alloc_filename(NULL , "lower", ECL_EGRID_FILE, false, -1), "lower.egrid"); + char * f1 = ecl_util_alloc_filename(NULL, "mixedBase", ECL_EGRID_FILE, false, -1); + char * f2 = ecl_util_alloc_filename(NULL, "UPPER", ECL_EGRID_FILE, false, -1); + char * f3 = ecl_util_alloc_filename(NULL , "lower", ECL_EGRID_FILE, false, -1); + + test_assert_NULL( f1 ); + test_assert_string_equal( f2 , "UPPER.EGRID"); + test_assert_string_equal( f3 , "lower.egrid"); + + free(f2); + free(f3); } void test_file_list() { - test_work_area_type * work_area = test_work_area_alloc("RESTART_FILES"); + ecl::util::TestArea ta("file_list"); stringlist_type * s = stringlist_alloc_new(); for (int i = 0; i < 10; i += 2) { @@ -109,7 +116,6 @@ void test_file_list() { test_assert_int_equal(stringlist_get_size(s), 10); stringlist_free(s); - test_work_area_free(work_area); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp index b4d6cc1eaa..6af65736e0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_util_make_date_no_shift.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp index 73fa007994..159a874b0f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp @@ -1,4 +1,4 @@ - /* Copyright (C) 2013 Statoil ASA, Norway. + /* Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_util_make_date_shift.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp index afd3d7af11..f708805d15 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_util_month_range.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp index 470acebe53..f1821756cb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. The file 'ecl_util_path_access.c' is part of ERT - Ensemble based Reservoir Tool. @@ -27,7 +27,7 @@ void test_relative_access() { - test_work_area_type * work_area = test_work_area_alloc("access"); + ecl::util::TestArea ta("ecl_access"); test_assert_false( ecl_util_path_access("No/directory/does/not/exist")); util_make_path("path"); @@ -44,7 +44,6 @@ void test_relative_access() { test_assert_false( ecl_util_path_access("path/file")); test_assert_true( ecl_util_path_access("ECLIPSE_CASE")); - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp index b275c4300f..f69e5d47d7 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp @@ -5,7 +5,7 @@ * Author: joaho */ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_lgr_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp index 1dd75bd20e..cb9b2e05c8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp index bbfab425cb..238572e725 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp @@ -1,5 +1,5 @@ /* - Copyright 2015 Statoil ASA. + Copyright 2015 Equinor ASA. This file is part of the Open Porous Media project (OPM). @@ -28,7 +28,7 @@ void test_open() { - test_work_area_type * work_area = test_work_area_alloc("FORTIO"); + ecl::util::TestArea ta("fortioxx"); ERT::FortIO fortio; fortio.open( "new_file" , std::fstream::out ); @@ -67,12 +67,11 @@ void test_open() { } test_assert_false( fortio.ftruncate( 0 )); fortio.close(); - test_work_area_free(work_area); } void test_fortio() { - test_work_area_type * work_area = test_work_area_alloc("FORTIO"); + ecl::util::TestArea ta("FORTIO"); ERT::FortIO fortio("new_file" , std::fstream::out ); { std::vector data; @@ -97,12 +96,11 @@ void test_fortio() { fortio.close(); test_assert_throw( ERT::FortIO fortio("file/does/not/exists" , std::fstream::in) , std::invalid_argument ); - test_work_area_free(work_area); } void test_fortio_kw() { - test_work_area_type * work_area = test_work_area_alloc("FORTIO"); + ecl::util::TestArea ta("fortio_kw"); std::vector< int > vec( 1000 ); for (size_t i =0 ; i < vec.size(); i++) @@ -123,12 +121,7 @@ void test_fortio_kw() { for (size_t i =0 ; i < kw.size(); i++) test_assert_int_equal( kw.at( i ), kw2.at( i ) ); - - fortio = ERT::FortIO("new_file" , std::fstream::in ); - test_assert_throw( ERT::EclKW::load(fortio) , std::invalid_argument ); - fortio.close(); } - test_work_area_free(work_area); } diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp index f348304c33..a3c561681c 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp @@ -1,5 +1,5 @@ /* - Copyright 2015 Statoil ASA. + Copyright 2015 Equinor ASA. This file is part of the Open Porous Media project (OPM). @@ -170,7 +170,7 @@ void test_read_write() { std::vector s_data = {"S1", "S2", "S3"}; { - test_work_area_type * work_area = test_work_area_alloc("READ_WRITE"); + ecl::util::TestArea ta("kw-read-write"); { ERT::FortIO f("test_file", std::ios_base::out); ERT::write_kw(f, "DOUBLE", d_data); @@ -208,7 +208,6 @@ void test_read_write() { } ecl_file_close(f); - test_work_area_free(work_area); } } } diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp deleted file mode 100644 index ca134cf6f9..0000000000 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright 2015 Statoil ASA. - - This file is part of the Open Porous Media project (OPM). - - OPM is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OPM is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OPM. If not, see . -*/ - -#include -#include - -#include - -void test_smspec_copy() { - std::string kw( "FOPT" ); - ERT::smspec_node field( kw ); - - ERT::smspec_node copy( field ); -} - -void test_smspec_get() { - std::string kw( "FOPT" ); - ERT::smspec_node field( kw ); - - test_assert_true( field.get() != nullptr ); -} - -void test_smspec_move() { - std::string kw( "FOPT" ); - ERT::smspec_node field( kw ); - ERT::smspec_node move_ctor( std::move( field ) ); - auto move_assignment = std::move( move_ctor ); -} - -void test_smspec_wg() { - std::string wkw( "WWCT" ); - std::string gkw( "GWCT" ); - std::string wg( "OP1" ); - std::string gr( "WG1" ); - - ERT::smspec_node well( ECL_SMSPEC_WELL_VAR, wg, wkw ); - ERT::smspec_node group( ECL_SMSPEC_GROUP_VAR, gr, gkw ); - - test_assert_string_equal(well.key1() , "WWCT:OP1"); - test_assert_string_equal(well.keyword() , "WWCT"); - test_assert_true(well.wgname() == wg); - test_assert_true(well.type() == ECL_SMSPEC_WELL_VAR ); - - test_assert_string_equal(group.key1(), "GWCT:WG1"); - test_assert_string_equal(group.keyword() , "GWCT"); - test_assert_true(group.wgname() == gr); - test_assert_true(group.type() == ECL_SMSPEC_GROUP_VAR ); -} - -void test_smspec_field() { - std::string kw( "FOPT" ); - ERT::smspec_node field( kw ); - - test_assert_string_equal( field.key1() , "FOPT" ); - test_assert_true( field.keyword() == kw ); - test_assert_true( field.type() == ECL_SMSPEC_FIELD_VAR ); -} - -void test_smspec_block() { - std::string kw( "BPR" ); - int dims[ 3 ] = { 10, 10, 10 }; - int ijk[ 3 ] = { 5, 5, 5 }; - - ERT::smspec_node block( kw, dims, ijk ); - - // Observe that ERT::smspec_node( ) constructor is considered part - // of the developer API, with offset zero indices, whereas the - // key1() string is meant for user consumption and has offset 1 - - // what a mess! - test_assert_string_equal( block.key1(), "BPR:6,6,6" ); - test_assert_true( block.keyword() == kw ); - test_assert_true( block.type() == ECL_SMSPEC_BLOCK_VAR ); - test_assert_true( block.num() == 556 ); -} - -void test_smspec_misc() { - ERT::smspec_node tcpu( "TCPU" ); - test_assert_true( tcpu.type() == ECL_SMSPEC_MISC_VAR ); -} - - -void test_smspec_region() { - std::string kw( "ROIP" ); - int dims[ 3 ] = { 10, 10, 10 }; - ERT::smspec_node region( kw, dims, 0 ); - - test_assert_true( region.keyword() == kw ); - test_assert_true( region.type() == ECL_SMSPEC_REGION_VAR ); - test_assert_true( region.num() == 0 ); -} - -void test_smspec_completion() { - std::string kw( "CWIT" ); - std::string wg( "WELL1" ); - int dims[ 3 ] = { 10, 10, 10 }; - int ijk[ 3 ] = { 1, 1, 1 }; - ERT::smspec_node completion( kw, wg, dims, ijk ); - - test_assert_true( completion.keyword() == kw ); - test_assert_true( completion.type() == ECL_SMSPEC_COMPLETION_VAR ); - test_assert_true( completion.num() == 112 ); -} - -int main (int argc, char **argv) { - test_smspec_copy(); - test_smspec_move(); - test_smspec_get(); - test_smspec_wg(); - test_smspec_field(); - test_smspec_block(); - test_smspec_region(); - test_smspec_completion(); - test_smspec_misc(); -} diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp index 7b04d9414d..c1098b2e0e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp b/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp index 4bd4b85f5f..fae3c59b93 100644 --- a/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'rft_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp b/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp index 59f59bb79e..5a4fc201ea 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'test_ecl_file_index.c' is part of ERT - Ensemble based Reservoir Tool. @@ -34,7 +34,7 @@ void test_load_nonexisting_file() { void test_create_and_load_index_file() { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_index_testing"); + ecl::util::TestArea ta("Load_index"); { const char * file_name = "initial_data_file"; const char * index_file_name = "index_file"; @@ -98,7 +98,6 @@ void test_create_and_load_index_file() { ecl_kw_free(kw2); ecl_file_close( ecl_file_index ); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp b/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp index a68185e61f..cc5f3cf460 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'test_ecl_nnc_data.c' is part of ERT - Ensemble based Reservoir Tool. @@ -34,7 +34,7 @@ void test_alloc_global_only(bool data_in_file) { - test_work_area_type * work_area = test_work_area_alloc("nnc-INIT"); + ecl::util::TestArea ta("nnc-INIT"); { int nx = 10; int ny = 10; @@ -90,7 +90,6 @@ void test_alloc_global_only(bool data_in_file) { } ecl_grid_free( grid0 ); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp b/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp index 1d6f9933ad..057f3f4fbc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp @@ -1,6 +1,6 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'test_transactions.c' is part of ERT - Ensemble based Reservoir Tool. @@ -38,7 +38,7 @@ void test_transaction() { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_index_testing"); + ecl::util::TestArea ta("index_testing"); { const char * file_name = "data_file"; fortio_type * fortio = fortio_open_writer(file_name, false, ECL_ENDIAN_FLIP); @@ -99,9 +99,10 @@ void test_transaction() { test_assert_false( ecl_file_kw_get_kw_ptr(file_kw2) ); ecl_file_close(file); - + ecl_kw_free(kw1); + ecl_kw_free(kw2); + ecl_kw_free(kw3); } - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp b/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp index df88ed73af..55cd4c8563 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp b/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp index c81907c0bc..95ed85fdcd 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp b/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp index 27de6631d5..dc89d6a935 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp b/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp index d988c1b1e6..b843a6cb3b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp index 02fd157415..197d11f37d 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp b/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp index 30315df48e..abcc652a50 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_dualp.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_info.cpp b/ThirdParty/Ert/lib/ecl/tests/well_info.cpp index 2daf549175..e2f4fe3df0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_info.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_info.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. @@ -30,6 +30,7 @@ int main(int argc , char ** argv) { + util_install_signals(); const char * grid_file = argv[1]; ecl_grid_type * grid = ecl_grid_alloc( grid_file ); @@ -37,6 +38,9 @@ int main(int argc , char ** argv) { { well_info_type * well_info = well_info_alloc( grid ); test_assert_not_NULL( well_info ); + if (argc >= 3) + well_info_load_rstfile(well_info, argv[2], true); + well_info_free( well_info ); } ecl_grid_free( grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp index 4e060c1772..86bfd96336 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_lgr_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp index fd3062716a..512bf4be10 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp index 55761b2448..68b399ab4b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp index 8c28653adc..aafcded940 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp index 9b53f16eaa..bd4d31b915 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_conn.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp index 92b213fbfd..9de125c64c 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp index 6ca651d811..dc59ea1d4f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state.cpp b/ThirdParty/Ert/lib/ecl/tests/well_state.cpp index 436aad1cd0..7c12b932dc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_state.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_state.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp b/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp index e78acdfcd5..52bbf88a46 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_state_load.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp b/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp index d20955352b..a80f7aeda7 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_state_load_missing_RSEG.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp b/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp index 7a4dba9dc9..9fe458d8cb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_ts.c' is part of ERT - Ensemble based Reservoir Tool. @@ -70,7 +70,8 @@ int main(int argc , char ** argv) { well_info_load_rstfile( well_info , stringlist_iget(file_list , i), true); well_info_free( well_info ); } - + ecl_grid_free( grid ); + free( grid_file ); exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp b/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp index 005419decf..46f5ef3e25 100644 --- a/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,10 +18,10 @@ #include +#include + #include #include -#include -#include #include #include @@ -33,8 +33,8 @@ struct well_branch_collection_struct { UTIL_TYPE_ID_DECLARATION; - vector_type * __start_segments; - int_vector_type * index_map; + std::vector __start_segments; + std::vector index_map; }; @@ -43,19 +43,24 @@ static UTIL_SAFE_CAST_FUNCTION( well_branch_collection , WELL_BRANCH_COLLECTION_ well_branch_collection_type * well_branch_collection_alloc() { - well_branch_collection_type * branch_collection = (well_branch_collection_type*)util_malloc( sizeof * branch_collection ); + well_branch_collection_type * branch_collection = new well_branch_collection_type(); UTIL_TYPE_ID_INIT( branch_collection , WELL_BRANCH_COLLECTION_TYPE_ID ); - branch_collection->__start_segments = vector_alloc_new(); - branch_collection->index_map = int_vector_alloc(0 , -1 ); return branch_collection; } +namespace { +int well_branch_collection_safe_iget_index( const well_branch_collection_type * branches, int index ) { + if (index >= (int)branches->index_map.size()) + return -1; + else + return branches->index_map[index]; +} + +} void well_branch_collection_free( well_branch_collection_type * branches ) { - vector_free( branches->__start_segments ); - int_vector_free( branches->index_map ); - free( branches ); + delete branches; } @@ -67,12 +72,12 @@ void well_branch_collection_free__( void * arg ) { int well_branch_collection_get_size( const well_branch_collection_type * branches ) { - return vector_get_size( branches->__start_segments ); + return branches->__start_segments.size(); } bool well_branch_collection_has_branch( const well_branch_collection_type * branches , int branch_id) { - if (int_vector_safe_iget( branches->index_map , branch_id) >= 0) + if (well_branch_collection_safe_iget_index( branches , branch_id) >= 0) return true; else return false; @@ -81,8 +86,8 @@ bool well_branch_collection_has_branch( const well_branch_collection_type * bran const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index ) { - if (index < vector_get_size( branches->__start_segments)) - return (const well_segment_type*)vector_iget_const( branches->__start_segments , index); + if (index < static_cast(branches->__start_segments.size())) + return branches->__start_segments[index]; else return NULL; } @@ -90,7 +95,7 @@ const well_segment_type * well_branch_collection_iget_start_segment( const well_ const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id) { - int internal_index = int_vector_safe_iget( branches->index_map , branch_id); + int internal_index = well_branch_collection_safe_iget_index( branches , branch_id); if (internal_index >= 0) return well_branch_collection_iget_start_segment( branches , internal_index ); else @@ -98,16 +103,18 @@ const well_segment_type * well_branch_collection_get_start_segment( const well_b } -bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment) { +bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , well_segment_type * start_segment) { if ((well_segment_get_link_count( start_segment ) == 0) && (well_segment_get_outlet(start_segment))) { int branch_id = well_segment_get_branch_id( start_segment ); - int current_index = int_vector_safe_iget( branches->index_map , branch_id); + int current_index = well_branch_collection_safe_iget_index( branches , branch_id); if (current_index >= 0) - vector_iset_ref( branches->__start_segments , current_index , start_segment); + branches->__start_segments[current_index] = start_segment; else { - int new_index = vector_get_size( branches->__start_segments ); - vector_append_ref( branches->__start_segments , start_segment); - int_vector_iset( branches->index_map , branch_id , new_index); + int new_index = branches->__start_segments.size(); + branches->__start_segments.push_back(start_segment); + if (branch_id >= (int)branches->index_map.size()) + branches->index_map.resize(branch_id+1, -1); + branches->index_map[branch_id] = new_index; } return true; diff --git a/ThirdParty/Ert/lib/ecl/well_conn.cpp b/ThirdParty/Ert/lib/ecl/well_conn.cpp index eaa8a90ac4..e3f2f2a890 100644 --- a/ThirdParty/Ert/lib/ecl/well_conn.cpp +++ b/ThirdParty/Ert/lib/ecl/well_conn.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. @@ -92,7 +92,7 @@ UTIL_SAFE_CAST_FUNCTION( well_conn , WELL_CONN_TYPE_ID) static well_conn_type * well_conn_alloc__( int i , int j , int k , double connection_factor , well_conn_dir_enum dir , bool open, int segment_id, bool matrix_connection) { if (well_conn_assert_direction( dir , matrix_connection)) { - well_conn_type * conn = (well_conn_type*)util_malloc( sizeof * conn ); + well_conn_type * conn = new well_conn_type(); UTIL_TYPE_ID_INIT( conn , WELL_CONN_TYPE_ID ); conn->i = i; conn->j = j; @@ -245,7 +245,7 @@ well_conn_type * well_conn_alloc_from_kw( const ecl_kw_type * icon_kw , void well_conn_free( well_conn_type * conn) { - free( conn ); + delete conn; } diff --git a/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp b/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp index 788d25440a..1616e796dc 100644 --- a/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,9 +18,10 @@ #include +#include + #include #include -#include #include #include @@ -34,7 +35,8 @@ struct well_conn_collection_struct { UTIL_TYPE_ID_DECLARATION; - vector_type * connection_list; + std::vector connection_list; + std::vector connection_list_owned; }; @@ -43,9 +45,8 @@ static UTIL_SAFE_CAST_FUNCTION( well_conn_collection , WELL_CONN_COLLECTION_TYPE well_conn_collection_type * well_conn_collection_alloc() { - well_conn_collection_type * wellcc = (well_conn_collection_type*)util_malloc( sizeof * wellcc ); + well_conn_collection_type * wellcc = new well_conn_collection_type(); UTIL_TYPE_ID_INIT( wellcc , WELL_CONN_COLLECTION_TYPE_ID ); - wellcc->connection_list = vector_alloc_new(); return wellcc; } @@ -55,7 +56,8 @@ well_conn_collection_type * well_conn_collection_alloc() { */ void well_conn_collection_add( well_conn_collection_type * wellcc , well_conn_type * conn) { - vector_append_owned_ref( wellcc->connection_list , conn , well_conn_free__); + wellcc->connection_list.push_back(conn); + wellcc->connection_list_owned.push_back(true); } /* @@ -63,13 +65,16 @@ void well_conn_collection_add( well_conn_collection_type * wellcc , well_conn_ty */ void well_conn_collection_add_ref( well_conn_collection_type * wellcc , well_conn_type * conn) { - vector_append_ref( wellcc->connection_list , conn ); + wellcc->connection_list.push_back(conn); + wellcc->connection_list_owned.push_back(false); } void well_conn_collection_free( well_conn_collection_type * wellcc ) { - vector_free( wellcc->connection_list ); - free( wellcc ); + for (size_t i = 0; i < wellcc->connection_list.size(); i++) + if (wellcc->connection_list_owned[i]) + well_conn_free(wellcc->connection_list[i]); + delete wellcc; } void well_conn_collection_free__( void * arg ) { @@ -79,14 +84,14 @@ void well_conn_collection_free__( void * arg ) { int well_conn_collection_get_size( const well_conn_collection_type * wellcc ) { - return vector_get_size( wellcc->connection_list ); + return wellcc->connection_list.size(); } const well_conn_type * well_conn_collection_iget_const(const well_conn_collection_type * wellcc , int index) { int size = well_conn_collection_get_size( wellcc ); if (index < size) - return (const well_conn_type*)vector_iget_const( wellcc->connection_list , index ); + return wellcc->connection_list[index]; else return NULL; } @@ -95,7 +100,7 @@ const well_conn_type * well_conn_collection_iget_const(const well_conn_collectio well_conn_type * well_conn_collection_iget(const well_conn_collection_type * wellcc , int index) { int size = well_conn_collection_get_size( wellcc ); if (index < size) - return (well_conn_type*)vector_iget( wellcc->connection_list , index ); + return wellcc->connection_list[index]; else return NULL; } diff --git a/ThirdParty/Ert/lib/ecl/well_info.cpp b/ThirdParty/Ert/lib/ecl/well_info.cpp index b838955ff9..94f6692dd7 100644 --- a/ThirdParty/Ert/lib/ecl/well_info.cpp +++ b/ThirdParty/Ert/lib/ecl/well_info.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. @@ -21,10 +21,10 @@ #include #include +#include +#include #include -#include -#include #include #include @@ -182,7 +182,7 @@ struct well_info_struct { - hash_type * wells; /* Hash table of well_ts_type instances; indexed by well name. */ + std::map wells; /* std::map of well_ts_type instances; indexed by well name. */ std::vector well_names; /* A list of all the well names. */ const ecl_grid_type * grid; }; @@ -195,23 +195,25 @@ struct well_info_struct { well_info_type * well_info_alloc( const ecl_grid_type * grid) { well_info_type * well_info = new well_info_type(); - well_info->wells = hash_alloc(); well_info->grid = grid; return well_info; } bool well_info_has_well( well_info_type * well_info , const char * well_name ) { - return hash_has_key( well_info->wells , well_name ); + const auto it = well_info->wells.find(well_name); + if (it == well_info->wells.end()) + return false; + return true; } well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name) { - return (well_ts_type*)hash_get( well_info->wells , well_name ); + return well_info->wells.at( well_name ); } static void well_info_add_new_ts( well_info_type * well_info , const char * well_name) { well_ts_type * well_ts = well_ts_alloc( well_name ) ; - hash_insert_hash_owned_ref( well_info->wells , well_name , well_ts , well_ts_free__); + well_info->wells[well_name] = well_ts; well_info->well_names.push_back( well_name ); } @@ -353,7 +355,9 @@ void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * ec } void well_info_free( well_info_type * well_info ) { - hash_free( well_info->wells ); + for (const auto& pair : well_info->wells) + well_ts_free(pair.second); + delete well_info; } diff --git a/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp b/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp index c0bc317cc2..43c757ec2d 100644 --- a/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp +++ b/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. @@ -79,6 +79,7 @@ double * well_rseg_loader_load_values(const well_rseg_loader_type * loader, int int_vector_type * index_map = loader->absolute_index_map; int index = 0; + int_vector_resize( index_map, int_vector_size(loader->relative_index_map), 0 ); for(index = 0; index < int_vector_size(loader->relative_index_map); index++) { int relative_index = int_vector_iget(loader->relative_index_map, index); int_vector_iset(index_map, index, relative_index + rseg_offset); diff --git a/ThirdParty/Ert/lib/ecl/well_segment.cpp b/ThirdParty/Ert/lib/ecl/well_segment.cpp index 8d3717847e..cfb041c7e8 100644 --- a/ThirdParty/Ert/lib/ecl/well_segment.cpp +++ b/ThirdParty/Ert/lib/ecl/well_segment.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,8 +18,10 @@ #include +#include +#include + #include -#include #include #include @@ -39,7 +41,8 @@ struct well_segment_struct { int branch_id; int outlet_segment_id; // This is in the global index space given by the ISEG keyword. well_segment_type * outlet_segment; - hash_type * connections; // hash_type; + std::map connections; // hash_type; double depth; // The depth of the segment node; furthest away from the wellhead. double length; @@ -53,7 +56,7 @@ static UTIL_SAFE_CAST_FUNCTION( well_segment , WELL_SEGMENT_TYPE_ID ) well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data) { - well_segment_type * segment = (well_segment_type*)util_malloc( sizeof * segment ); + well_segment_type * segment = new well_segment_type(); UTIL_TYPE_ID_INIT( segment , WELL_SEGMENT_TYPE_ID ); segment->link_count = 0; @@ -61,7 +64,6 @@ well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , segment->outlet_segment_id = outlet_segment_id; segment->branch_id = branch_id; segment->outlet_segment = NULL; - segment->connections = hash_alloc(); segment->depth = 0.0; segment->length = 0.0; @@ -116,8 +118,10 @@ well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , co void well_segment_free(well_segment_type * segment ) { - hash_free( segment->connections ); - free( segment ); + for (auto& pair : segment->connections) + well_conn_collection_free(pair.second); + + delete segment; } void well_segment_free__(void * arg) { @@ -196,7 +200,10 @@ void well_segment_link_strict( well_segment_type * segment , well_segment_type * bool well_segment_has_grid_connections( const well_segment_type * segment , const char * grid_name) { - return hash_has_key( segment->connections , grid_name ); + const auto it = segment->connections.find(grid_name); + if (it == segment->connections.end()) + return false; + return true; } @@ -208,13 +215,11 @@ bool well_segment_has_global_grid_connections( const well_segment_type * segment bool well_segment_add_connection( well_segment_type * segment , const char * grid_name , well_conn_type * conn) { int conn_segment_id = well_conn_get_segment_id( conn ); if (conn_segment_id == segment->segment_id) { - if (!well_segment_has_grid_connections( segment , grid_name )) - hash_insert_hash_owned_ref( segment->connections , grid_name , well_conn_collection_alloc() , well_conn_collection_free__ ); - { - well_conn_collection_type * connections = (well_conn_collection_type*)hash_get( segment->connections , grid_name ); - well_conn_collection_add_ref( connections , conn ); - } + if (!well_segment_has_grid_connections(segment, grid_name)) + segment->connections[grid_name] = well_conn_collection_alloc(); + + well_conn_collection_add_ref( segment->connections[grid_name] , conn ); return true; } else return false; @@ -223,7 +228,7 @@ bool well_segment_add_connection( well_segment_type * segment , const char * gri const well_conn_collection_type * well_segment_get_connections(const well_segment_type * segment , const char * grid_name ) { if (well_segment_has_grid_connections( segment , grid_name)) - return (const well_conn_collection_type*)hash_get( segment->connections , grid_name); + return segment->connections.at(grid_name); else return NULL; } diff --git a/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp b/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp index 841ee7d394..da9d1b3de8 100644 --- a/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -33,56 +35,61 @@ struct well_segment_collection_struct { - int_vector_type * segment_index_map; - vector_type * __segment_storage; + std::vector segment_index_map; + std::vector __segment_storage; }; well_segment_collection_type * well_segment_collection_alloc(void) { - well_segment_collection_type * segment_collection = (well_segment_collection_type*)util_malloc( sizeof * segment_collection ); - - segment_collection->__segment_storage = vector_alloc_new(); - segment_collection->segment_index_map = int_vector_alloc( 0 , -1 ); + well_segment_collection_type * segment_collection = new well_segment_collection_type(); return segment_collection; } void well_segment_collection_free(well_segment_collection_type * segment_collection ) { - vector_free( segment_collection->__segment_storage ); - int_vector_free( segment_collection->segment_index_map ); - free( segment_collection ); + for (int i = 0; i < static_cast(segment_collection->__segment_storage.size()); i++) + well_segment_free( segment_collection->__segment_storage[i] ); + delete segment_collection; } int well_segment_collection_get_size( const well_segment_collection_type * segment_collection ) { - return vector_get_size( segment_collection->__segment_storage ); + return segment_collection->__segment_storage.size(); } void well_segment_collection_add( well_segment_collection_type * segment_collection , well_segment_type * segment) { int segment_id = well_segment_get_id( segment ); - int current_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id ); - if (current_index >= 0) - vector_iset_owned_ref( segment_collection->__segment_storage , current_index , segment , well_segment_free__); + int current_index = -1; + if (segment_id < static_cast(segment_collection->segment_index_map.size())) + current_index = segment_collection->segment_index_map[segment_id]; + if (current_index >= 0) { + well_segment_free( segment_collection->__segment_storage[current_index] ); + segment_collection->__segment_storage[current_index] = segment; + } else { - int new_index = vector_get_size(segment_collection->__segment_storage); - vector_append_owned_ref( segment_collection->__segment_storage , segment , well_segment_free__); - int_vector_iset( segment_collection->segment_index_map , segment_id , new_index); + int new_index = segment_collection->__segment_storage.size(); + segment_collection->__segment_storage.push_back( segment ); + if ( segment_id >= static_cast(segment_collection->segment_index_map.size()) ) + segment_collection->segment_index_map.resize(segment_id+1, -1); + segment_collection->segment_index_map[segment_id] = new_index; } } well_segment_type * well_segment_collection_iget( const well_segment_collection_type * segment_collection , int index) { - return (well_segment_type*)vector_iget( segment_collection->__segment_storage , index ); + return segment_collection->__segment_storage[ index ]; } well_segment_type * well_segment_collection_get( const well_segment_collection_type * segment_collection , int segment_id) { - int internal_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id ); + int internal_index = -1; + if (segment_id < static_cast(segment_collection->segment_index_map.size())) + internal_index = segment_collection->segment_index_map[segment_id]; if (internal_index >= 0) return well_segment_collection_iget( segment_collection , internal_index ); else @@ -91,7 +98,9 @@ well_segment_type * well_segment_collection_get( const well_segment_collection_t bool well_segment_collection_has_segment( const well_segment_collection_type * segment_collection , int segment_id) { - int internal_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id ); + int internal_index = -1; + if (segment_id < static_cast(segment_collection->segment_index_map.size())) + internal_index = segment_collection->segment_index_map[segment_id]; if (internal_index >= 0) return true; else @@ -133,8 +142,8 @@ int well_segment_collection_load_from_kw( well_segment_collection_type * segment void well_segment_collection_link(const well_segment_collection_type * segment_collection) { - int index; - for (index = 0; index < vector_get_size( segment_collection->__segment_storage); index++) { + size_t index; + for (index = 0; index < segment_collection->__segment_storage.size(); index++) { well_segment_type * segment = well_segment_collection_iget( segment_collection , index ); int outlet_segment_id = well_segment_get_outlet_id( segment ); if (!well_segment_nearest_wellhead(segment)) { @@ -166,7 +175,7 @@ void well_segment_collection_add_branches( const well_segment_collection_type * well_branch_collection_type * branches ) { int iseg; for (iseg =0; iseg < well_segment_collection_get_size( segment_collection ); iseg++) { - const well_segment_type * segment = well_segment_collection_iget( segment_collection , iseg ); + well_segment_type * segment = well_segment_collection_iget( segment_collection , iseg ); if (well_segment_get_link_count( segment ) == 0) well_branch_collection_add_start_segment( branches , segment ); } diff --git a/ThirdParty/Ert/lib/ecl/well_state.cpp b/ThirdParty/Ert/lib/ecl/well_state.cpp index d0dc6c0273..67fedbe68e 100644 --- a/ThirdParty/Ert/lib/ecl/well_state.cpp +++ b/ThirdParty/Ert/lib/ecl/well_state.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_state.c' is part of ERT - Ensemble based Reservoir Tool. @@ -31,6 +31,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -105,7 +109,7 @@ links are as follows: Segment1: C2 Segment2: C3 Segment3: C4, C5 - Segment4: C6 + Segment4: C6state_free( Segment5: C7 Each segment has an outlet segment, which will link the segments @@ -164,7 +168,7 @@ coupledte implementation these objects are modelled as such: struct well_state_struct { UTIL_TYPE_ID_DECLARATION; - char * name; + std::string name; time_t valid_from_time; int valid_from_report; int global_well_nr; @@ -176,15 +180,15 @@ struct well_state_struct { double water_rate; double volume_rate; ert_ecl_unit_enum unit_system; - - hash_type * connections; // hash + + std::map connections; // hash well_segment_collection_type * segments; well_branch_collection_type * branches; /*****************************************************************/ - - vector_type * index_wellhead; // An well_conn_type instance representing the wellhead - indexed by grid_nr. - hash_type * name_wellhead; // An well_conn_type instance representing the wellhead - indexed by lgr_name. + + std::vector index_wellhead; // An well_conn_type instance representing the wellhead - indexed by grid_nr. + std::map name_wellhead; // An well_conn_type instance representing the wellhead - indexed by lgr_name. }; @@ -193,18 +197,15 @@ UTIL_IS_INSTANCE_FUNCTION( well_state , WELL_STATE_TYPE_ID) well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from) { - well_state_type * well_state = (well_state_type*)util_malloc( sizeof * well_state ); + well_state_type * well_state = new well_state_type(); UTIL_TYPE_ID_INIT( well_state , WELL_STATE_TYPE_ID ); - well_state->index_wellhead = vector_alloc_new(); - well_state->name_wellhead = hash_alloc(); - well_state->name = util_alloc_string_copy( well_name ); + well_state->name = well_name; well_state->valid_from_time = valid_from; well_state->valid_from_report = report_nr; well_state->open = open; well_state->type = type; well_state->global_well_nr = global_well_nr; - well_state->connections = hash_alloc(); well_state->segments = well_segment_collection_alloc(); well_state->branches = well_branch_collection_alloc(); well_state->is_MSW_well = false; @@ -291,8 +292,10 @@ void well_state_add_wellhead( well_state_type * well_state , const ecl_rsthead_t well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , well_nr ); if (wellhead != NULL) { - vector_safe_iset_owned_ref( well_state->index_wellhead , grid_nr , wellhead , well_conn_free__ ); - hash_insert_ref( well_state->name_wellhead , grid_name , wellhead ); + if (grid_nr >= static_cast(well_state->index_wellhead.size())) + well_state->index_wellhead.resize(grid_nr+1, NULL); + well_state->index_wellhead[grid_nr] = wellhead; + well_state->name_wellhead[grid_name] = wellhead; } } @@ -342,7 +345,7 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons { char * lgr_well_name = (char*)util_alloc_strip_copy( (const char*)ecl_kw_iget_ptr( zwel_kw , well_nr * header->nzwelz) ); - if ( strcmp( well_state->name , lgr_well_name) == 0) + if ( well_state->name == lgr_well_name) found = true; else well_nr++; @@ -406,27 +409,29 @@ static void well_state_add_connections__( well_state_type * well_state , int well_nr ) { ecl_rsthead_type * header = ecl_rsthead_alloc( rst_view , -1); - const ecl_kw_type * icon_kw = ecl_file_view_iget_named_kw( rst_view , ICON_KW , 0); const ecl_kw_type * iwel_kw = ecl_file_view_iget_named_kw( rst_view , IWEL_KW , 0); well_state_add_wellhead( well_state , header , iwel_kw , well_nr , grid_name , grid_nr ); - if (!well_state_has_grid_connections( well_state , grid_name )) - hash_insert_hash_owned_ref( well_state->connections , grid_name, well_conn_collection_alloc( ) , well_conn_collection_free__ ); + if (ecl_file_view_has_kw(rst_view, ICON_KW)) { + const ecl_kw_type * icon_kw = ecl_file_view_iget_named_kw( rst_view , ICON_KW , 0); + if (!well_state_has_grid_connections( well_state , grid_name )) + well_state->connections[grid_name] = well_conn_collection_alloc(); - { - ecl_kw_type * scon_kw = NULL; - if (ecl_file_view_has_kw( rst_view , SCON_KW)) - scon_kw = ecl_file_view_iget_named_kw( rst_view , SCON_KW , 0); + { + ecl_kw_type * scon_kw = NULL; + if (ecl_file_view_has_kw( rst_view , SCON_KW)) + scon_kw = ecl_file_view_iget_named_kw( rst_view , SCON_KW , 0); - ecl_kw_type * xcon_kw = NULL; - if (ecl_file_view_has_kw( rst_view , XCON_KW)) { - xcon_kw = ecl_file_view_iget_named_kw(rst_view, XCON_KW, 0); + ecl_kw_type * xcon_kw = NULL; + if (ecl_file_view_has_kw( rst_view , XCON_KW)) { + xcon_kw = ecl_file_view_iget_named_kw(rst_view, XCON_KW, 0); + } + + well_conn_collection_type * wellcc = well_state->connections[grid_name]; + well_conn_collection_load_from_kw( wellcc , iwel_kw , icon_kw , scon_kw, xcon_kw , well_nr , header ); } - - well_conn_collection_type * wellcc = (well_conn_collection_type*)hash_get( well_state->connections , grid_name ); - well_conn_collection_load_from_kw( wellcc , iwel_kw , icon_kw , scon_kw, xcon_kw , well_nr , header ); } ecl_rsthead_free( header ); } @@ -447,10 +452,19 @@ static void well_state_add_LGR_connections(well_state_type * well_state, int num_lgr = ecl_grid_get_num_lgr( grid ); for (int lgr_index = 0; lgr_index < num_lgr; lgr_index++) { ecl_file_view_type * lgr_view = ecl_file_view_add_blockview(file_view , LGR_KW , lgr_index); - const char * grid_name = ecl_grid_iget_lgr_name( grid , lgr_index ); - int well_nr = well_state_get_lgr_well_nr( well_state , lgr_view ); - if (well_nr >= 0) - well_state_add_connections__( well_state , lgr_view , grid_name , lgr_index + 1, well_nr ); + /* + Even though the grid has LGR information the restart file is not required + to have corresponding LGR information. This has for a long time been + unchecked, and there might be bugs lurking based on the incorrect + assumption that if the grid has LGR information then the corresponding LGR + information can also be found in the restart file. + */ + if (lgr_view) { + const char * grid_name = ecl_grid_iget_lgr_name( grid , lgr_index ); + int well_nr = well_state_get_lgr_well_nr( well_state , lgr_view ); + if (well_nr >= 0) + well_state_add_connections__( well_state , lgr_view , grid_name , lgr_index + 1, well_nr ); + } } } @@ -515,13 +529,12 @@ bool well_state_add_MSW2( well_state_type * well_state , if (segment_count > 0) { - hash_iter_type * grid_iter = hash_iter_alloc( well_state->connections ); - while (!hash_iter_is_complete( grid_iter )) { - const char * grid_name = hash_iter_get_next_key( grid_iter ); - const well_conn_collection_type * connections = (const well_conn_collection_type*)hash_get( well_state->connections , grid_name ); - well_segment_collection_add_connections( well_state->segments , grid_name , connections ); + + auto it = well_state->connections.begin(); + while (it != well_state->connections.end()) { + well_segment_collection_add_connections( well_state->segments , it->first.c_str() , it->second ); + it++; } - hash_iter_free( grid_iter ); well_segment_collection_link( well_state->segments ); well_segment_collection_add_branches( well_state->segments , well_state->branches ); @@ -607,14 +620,19 @@ well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view , void well_state_free( well_state_type * well ) { - hash_free( well->name_wellhead ); - vector_free( well->index_wellhead ); - hash_free( well->connections ); + + for (size_t i = 0; i < well->index_wellhead.size(); i++) { + if (well->index_wellhead[i]) + well_conn_free(well->index_wellhead[i]); + } + + for (auto& pair : well->connections) + well_conn_collection_free(pair.second); + well_segment_collection_free( well->segments ); well_branch_collection_free( well->branches ); - free( well->name ); - free( well ); + delete well; } /*****************************************************************/ @@ -631,22 +649,30 @@ time_t well_state_get_sim_time( const well_state_type * well_state ) { Will return NULL if no wellhead in this grid. */ const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr) { - return (const well_conn_type*)vector_safe_iget_const( well_state->index_wellhead , grid_nr ); + if (grid_nr < static_cast(well_state->index_wellhead.size())) + return well_state->index_wellhead[grid_nr]; + else + return NULL; +} + + +bool well_state_has_named_well_conn( const well_state_type * well_state , const char * grid_name ) { + const auto it = well_state->name_wellhead.find( grid_name ); + if (it == well_state->name_wellhead.end()) + return false; + return true; } const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name) { - if (hash_has_key( well_state->name_wellhead , grid_name)) - return (const well_conn_type*)hash_get( well_state->name_wellhead , grid_name ); - else - return NULL; + const auto it = well_state->name_wellhead.find( grid_name ); + if (it != well_state->name_wellhead.end()) + return it->second; + return NULL; } const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state ) { - if (hash_has_key( well_state->name_wellhead , ECL_GRID_GLOBAL_GRID)) - return (const well_conn_type*)hash_get( well_state->name_wellhead , ECL_GRID_GLOBAL_GRID ); - else - return NULL; + return well_state_get_wellhead( well_state, ECL_GRID_GLOBAL_GRID ); } @@ -664,15 +690,15 @@ int well_state_get_well_nr( const well_state_type * well_state ) { const char * well_state_get_name( const well_state_type * well_state ) { - return well_state->name; + return well_state->name.c_str(); } /*****************************************************************/ const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name) { - if (hash_has_key( well_state->connections , grid_name)) - return (const well_conn_collection_type*)hash_get( well_state->connections , grid_name); + if (well_state_has_grid_connections(well_state, grid_name) ) + return well_state->connections.at(grid_name); else return NULL; } @@ -684,10 +710,11 @@ const well_conn_collection_type * well_state_get_global_connections( const well_ bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name) { - if (hash_has_key( well_state->connections , grid_name)) - return true; - else + + const auto it = well_state->connections.find(grid_name); + if (it == well_state->connections.end()) return false; + return true; } diff --git a/ThirdParty/Ert/lib/ecl/well_ts.cpp b/ThirdParty/Ert/lib/ecl/well_ts.cpp index 6aa42d4c16..cfae4974c1 100644 --- a/ThirdParty/Ert/lib/ecl/well_ts.cpp +++ b/ThirdParty/Ert/lib/ecl/well_ts.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_ts.c' is part of ERT - Ensemble based Reservoir Tool. @@ -62,6 +62,10 @@ #include #include +#include +#include +#include + #include #include @@ -84,14 +88,14 @@ typedef struct { struct well_ts_struct { UTIL_TYPE_ID_DECLARATION; - char * well_name; - vector_type * ts; + std::string well_name; + std::vector ts; }; /******************************************************************/ static well_node_type * well_node_alloc( well_state_type * well_state) { - well_node_type * node = (well_node_type*)util_malloc( sizeof * node ); + well_node_type * node = new well_node_type(); UTIL_TYPE_ID_INIT( node , WELL_NODE_TYPE_ID ); node->report_nr = well_state_get_report_nr( well_state ); node->sim_time = well_state_get_sim_time( well_state ); @@ -100,41 +104,23 @@ static well_node_type * well_node_alloc( well_state_type * well_state) { } -static UTIL_SAFE_CAST_FUNCTION( well_node , WELL_NODE_TYPE_ID ) -static UTIL_SAFE_CAST_FUNCTION_CONST( well_node , WELL_NODE_TYPE_ID ) - - static void well_node_free( well_node_type * well_node ) { well_state_free( well_node->well_state ); - free( well_node ); + delete well_node; } -static void well_node_free__( void * arg ) { - well_node_type * node = well_node_safe_cast( arg ); - well_node_free( node ); -} - -static int well_node_time_cmp( const void * arg1 , const void * arg2) { - const well_node_type * node1 = well_node_safe_cast_const( arg1 ); - const well_node_type * node2 = well_node_safe_cast_const( arg2 ); - - if (node1->sim_time < node2->sim_time) - return -1; - else if (node1->sim_time == node2->sim_time) - return 0; - else - return 1; +static bool well_node_time_lt( const well_node_type * node1 , const well_node_type * node2) { + return (node1->sim_time < node2->sim_time); } /*****************************************************************/ static well_ts_type * well_ts_alloc_empty( ) { - well_ts_type * well_ts = (well_ts_type*)util_malloc( sizeof * well_ts ); + well_ts_type * well_ts = new well_ts_type(); UTIL_TYPE_ID_INIT( well_ts , WELL_TS_TYPE_ID ); - well_ts->ts = vector_alloc_new(); return well_ts; } @@ -143,22 +129,22 @@ static UTIL_SAFE_CAST_FUNCTION( well_ts , WELL_TS_TYPE_ID ) well_ts_type * well_ts_alloc( const char * well_name ) { well_ts_type * well_ts = well_ts_alloc_empty(); - well_ts->well_name = util_alloc_string_copy( well_name ); + well_ts->well_name = well_name; return well_ts; } -char * well_ts_get_name( const well_ts_type * well_ts) { - return well_ts->well_name; +const char * well_ts_get_name( const well_ts_type * well_ts) { + return well_ts->well_name.c_str(); } static int well_ts_get_index__( const well_ts_type * well_ts , int report_step , time_t sim_time , bool use_report) { - const int size = vector_get_size( well_ts->ts ); + const int size = well_ts->ts.size(); if (size == 0) return 0; else { - const well_node_type * first_node = (const well_node_type*)vector_iget_const( well_ts->ts , 0 ); - const well_node_type * last_node = (const well_node_type*)vector_get_last_const( well_ts->ts ); + const well_node_type * first_node = well_ts->ts[0]; + const well_node_type * last_node = well_ts->ts.back(); if (use_report) { if (report_step < first_node->report_nr) @@ -181,7 +167,7 @@ static int well_ts_get_index__( const well_ts_type * well_ts , int report_step , while (true) { int center_index = (lower_index + upper_index) / 2; - const well_node_type * center_node = (const well_node_type*)vector_iget_const( well_ts->ts , center_index ); + const well_node_type * center_node = well_ts->ts[center_index]; double cmp; if (use_report) cmp = center_node->report_nr - report_step; @@ -221,11 +207,11 @@ static int well_ts_get_index( const well_ts_type * well_ts , int report_step , t // Inline check that the index is correct { bool OK = true; - const well_node_type * node = (const well_node_type*)vector_iget_const( well_ts->ts , index ); + const well_node_type * node = well_ts->ts[index]; well_node_type * next_node = NULL; - if (index < (vector_get_size( well_ts->ts ) - 1)) - next_node = (well_node_type*)vector_iget( well_ts->ts , index + 1); + if (index < (static_cast(well_ts->ts.size()) - 1) ) + next_node = well_ts->ts[index + 1]; if (use_report) { if (index < 0) { @@ -265,24 +251,24 @@ static int well_ts_get_index( const well_ts_type * well_ts , int report_step , t void well_ts_add_well( well_ts_type * well_ts , well_state_type * well_state ) { well_node_type * new_node = well_node_alloc( well_state ); - vector_append_owned_ref( well_ts->ts , new_node , well_node_free__ ); + well_ts->ts.push_back( new_node ); - if (vector_get_size( well_ts->ts ) > 1) { - const well_node_type * last_node = (const well_node_type*)vector_get_last_const(well_ts->ts ); + if (well_ts->ts.size() > 1) { + const well_node_type * last_node = well_ts->ts.back(); if (new_node->sim_time < last_node->sim_time) // The new node is chronologically before the previous node; // i.e. we must sort the nodes in time. This should probably happen - // quite seldom: - vector_sort( well_ts->ts , well_node_time_cmp ); + // quite seldom: + std::sort( well_ts->ts.begin(), well_ts->ts.end(), well_node_time_lt ); } } void well_ts_free( well_ts_type * well_ts ){ - free( well_ts->well_name ); - vector_free( well_ts->ts ); - free( well_ts ); + for (size_t i = 0; i < well_ts->ts.size(); i++) + well_node_free( well_ts->ts[i] ); + delete well_ts; } @@ -294,7 +280,7 @@ void well_ts_free__( void * arg ) { int well_ts_get_size( const well_ts_type * well_ts) { - return vector_get_size( well_ts->ts ); + return well_ts->ts.size(); } @@ -304,12 +290,12 @@ well_state_type * well_ts_get_first_state( const well_ts_type * well_ts) { well_state_type * well_ts_get_last_state( const well_ts_type * well_ts) { - return well_ts_iget_state( well_ts , vector_get_size( well_ts->ts ) - 1); + return well_ts_iget_state( well_ts , well_ts->ts.size() - 1); } well_state_type * well_ts_iget_state( const well_ts_type * well_ts , int index) { - well_node_type * node = (well_node_type*)vector_iget( well_ts->ts , index ); + well_node_type * node = well_ts->ts[index]; return node->well_state; } diff --git a/ThirdParty/Ert/lib/geometry/geo_pointset.cpp b/ThirdParty/Ert/lib/geometry/geo_pointset.cpp index 0aa2777753..513c89cbf0 100644 --- a/ThirdParty/Ert/lib/geometry/geo_pointset.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_pointset.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_pointset.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/geo_polygon.cpp b/ThirdParty/Ert/lib/geometry/geo_polygon.cpp index e375bb07e5..67571ca5f5 100644 --- a/ThirdParty/Ert/lib/geometry/geo_polygon.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_polygon.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_polygon.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp b/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp index 043bffcb83..d3bcd4170f 100644 --- a/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. @@ -20,10 +20,12 @@ #include #include +#include +#include + #include #include #include -#include #include #include @@ -35,17 +37,16 @@ struct geo_polygon_collection_struct { UTIL_TYPE_ID_DECLARATION; vector_type * polygon_list; - hash_type * polygon_map; + std::map polygon_map; }; UTIL_IS_INSTANCE_FUNCTION( geo_polygon_collection , GEO_POLYGON_COLLECTION_TYPE_ID) geo_polygon_collection_type * geo_polygon_collection_alloc( ) { - geo_polygon_collection_type * polygons = (geo_polygon_collection_type*)util_malloc( sizeof * polygons ); + geo_polygon_collection_type * polygons = new geo_polygon_collection_type(); UTIL_TYPE_ID_INIT( polygons , GEO_POLYGON_COLLECTION_TYPE_ID ); polygons->polygon_list = vector_alloc_new(); - polygons->polygon_map = hash_alloc(); return polygons; } @@ -82,7 +83,7 @@ bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons vector_append_ref( polygons->polygon_list , polygon ); if (name) - hash_insert_ref( polygons->polygon_map , name , polygon ); + polygons->polygon_map[name] = polygon; return true; } @@ -91,7 +92,7 @@ bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons bool geo_polygon_collection_has_polygon( const geo_polygon_collection_type * polygons , const char * name) { if (name) - return hash_has_key( polygons->polygon_map , name ); + return (polygons->polygon_map.count(name) > 0); else return false; } @@ -99,8 +100,7 @@ bool geo_polygon_collection_has_polygon( const geo_polygon_collection_type * pol void geo_polygon_collection_free( geo_polygon_collection_type * polygons ) { vector_free( polygons->polygon_list ); - hash_free( polygons->polygon_map ); - free( polygons ); + delete polygons; } @@ -111,5 +111,5 @@ geo_polygon_type * geo_polygon_collection_iget_polygon(const geo_polygon_collect geo_polygon_type * geo_polygon_collection_get_polygon(const geo_polygon_collection_type * polygons , const char * polygon_name) { - return (geo_polygon_type*)hash_get( polygons->polygon_map , polygon_name ); + return polygons->polygon_map.at( polygon_name ); } diff --git a/ThirdParty/Ert/lib/geometry/geo_region.cpp b/ThirdParty/Ert/lib/geometry/geo_region.cpp index 5ce2a6f382..c8e4985abb 100644 --- a/ThirdParty/Ert/lib/geometry/geo_region.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_region.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_region.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/geo_surface.cpp b/ThirdParty/Ert/lib/geometry/geo_surface.cpp index 773da26113..00e76938e1 100644 --- a/ThirdParty/Ert/lib/geometry/geo_surface.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_surface.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_surface.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/geo_util.cpp b/ThirdParty/Ert/lib/geometry/geo_util.cpp index e8d0b1cbb1..5f80362a66 100644 --- a/ThirdParty/Ert/lib/geometry/geo_util.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_util.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp b/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp index f3f46e6f60..fe97113cd2 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp +++ b/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'geo_surface.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp b/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp index 7023a82446..8627ccde6a 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp +++ b/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp b/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp index c9fd440b54..b506064d79 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp +++ b/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'geo_surface.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp b/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp index 6c926632c0..06f7ee72d1 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp +++ b/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'geo_util_xlines.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp b/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp index 858fccfb59..b5e9900582 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp b/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp index 9a07836bf8..71a7c70264 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp @@ -1,5 +1,5 @@ /* - Copyright 2015 Statoil ASA. + Copyright 2015 Equinor ASA. This file is part of the Open Porous Media project (OPM). diff --git a/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp b/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp index 2f7d69fa09..e4312eb61b 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp @@ -1,5 +1,5 @@ /* - Copyright 2015 Statoil ASA. + Copyright 2015 Equinor ASA. This file is part of the Open Porous Media project (OPM). diff --git a/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp b/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp deleted file mode 100644 index b16c4ced38..0000000000 --- a/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef OPM_ERT_SMSPEC_HPP -#define OPM_ERT_SMSPEC_HPP - -#include -#include - -#include -#include - -namespace ERT { - - class smspec_node { - public: - smspec_node( const smspec_node& ); - smspec_node( smspec_node&& ); - - smspec_node& operator=( const smspec_node& ); - smspec_node& operator=( smspec_node&& ); - - static int cmp( const smspec_node& node1, const smspec_node& node2); - smspec_node( - ecl_smspec_var_type, - const std::string& wgname, - const std::string& keyword - ); - - smspec_node( const std::string& keyword ); - - smspec_node( const std::string& keyword, - const int dims[ 3 ], - const int ijk[ 3 ] ); - - smspec_node( const std::string& keyword, - const std::string& wellname, - const int dims[ 3 ], - const int ijk[ 3 ] ); - - smspec_node( const std::string& keyword, - const int dims[ 3 ], - int region ); - - int type() const; - const char* keyword() const; - const char* wgname() const; - const char* key1() const; - int num() const; - smspec_node_type* get(); - const smspec_node_type* get() const; - - private: - smspec_node( - ecl_smspec_var_type, - const char*, const char*, const char*, const char*, - const int[3], int, int = 0, float = 0 ); - - ert_unique_ptr< smspec_node_type, smspec_node_free > node; - }; - -} - -#endif //OPM_ERT_SMSPEC_HPP diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp index e88098554a..a08d496b28 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_box.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp index 6b04ac1523..2bcea05cf2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp index 9876aaf0ef..409a023512 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_endian_flip.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp index 8ddae75c74..eaafb00654 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp index f066fd1b5d..18abcaea6c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_file_kw.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp index 20ab40af07..7cceec3319 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. @@ -81,8 +81,8 @@ typedef struct ecl_file_transaction_struct ecl_file_transaction_type; void ecl_file_view_fwrite( const ecl_file_view_type * ecl_file_view , fortio_type * target , int offset); int ecl_file_view_iget_occurence( const ecl_file_view_type * ecl_file_view , int global_index); void ecl_file_view_fprintf_kw_list(const ecl_file_view_type * ecl_file_view , FILE * stream); - ecl_file_view_type * ecl_file_view_add_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); - ecl_file_view_type * ecl_file_view_add_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); + ecl_file_view_type * ecl_file_view_add_blockview(ecl_file_view_type * ecl_file_view , const char * header, int occurence); + ecl_file_view_type * ecl_file_view_add_blockview2(ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); ecl_file_view_type * ecl_file_view_add_restart_view(ecl_file_view_type * file_view , int seqnum_index, int report_step , time_t sim_time, double sim_days); ecl_file_view_type * ecl_file_view_alloc_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); ecl_file_view_type * ecl_file_view_alloc_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp index 41e09f34cd..b39de29fb2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp index 62a1b84ed1..3b42b0ed94 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grav.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp index 925508cf17..3097395f4e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grav_common.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp index 4efac56885..9fdd7fc75c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool. @@ -18,9 +18,7 @@ #ifndef ERT_ECL_GRID_H #define ERT_ECL_GRID_H -#ifdef __cplusplus -extern "C" { -#endif + #include #include @@ -32,6 +30,10 @@ extern "C" { #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define ECL_GRID_COORD_SIZE(nx,ny) (((nx) + 1) * ((ny) + 1) * 6) #define ECL_GRID_ZCORN_SIZE(nx,ny,nz) (((nx) * (ny) * (nz) * 8)) diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp index f67179badd..358c06d9cb 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp index 8870ffe54a..a515a15eeb 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_init_file.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp index d198d47ca6..104d5c74a6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_io_config.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp index 607c638af3..6e13c1be4c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp index 2113c18cd9..1e777d3d86 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_kw_grdecl.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp index 8ed4c594e7..b3697d54d6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp index 68ca00d61a..1e2b2d9106 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool. @@ -45,7 +45,8 @@ typedef struct { } ecl_nnc_type; - int ecl_nnc_export_get_size( const ecl_grid_type * grid ); +bool ecl_nnc_intersect_format(const ecl_grid_type * grid, const ecl_file_type * init_file); + int ecl_nnc_export_get_size( const ecl_grid_type * grid , const ecl_file_type * init_file ); int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data); ecl_kw_type * ecl_nnc_export_get_tranx_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 ); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp index 66c5742ede..dbca5d9d5e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp index 321b1f68d5..bf9acfa99f 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_region.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp index 96ba37abd6..07460401e2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_cell.h' is part of ERT - Ensemble based Reservoir Tool. @@ -76,7 +76,7 @@ UTIL_IS_INSTANCE_HEADER( ecl_rft_cell ); int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2); int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2); - + bool ecl_rft_cell_lt( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2); #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp index 02f23cb048..eb58c5e4d2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp index ab6dcd46c6..6ad7896f97 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool. @@ -62,7 +62,8 @@ double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index); double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index); void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set); double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ); -int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2); +int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2); +bool ecl_rft_node_lt(const ecl_rft_node_type * n1, const ecl_rft_node_type * n2); void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell); ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp index f4d6e5d4a8..7a36ef0ad1 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_rst_file.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp index 8c91a65e16..566f60517c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp index 5bfef485f8..5a5bea9578 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_smspec.h' is part of ERT - Ensemble based Reservoir Tool. @@ -29,12 +29,29 @@ #include #include +typedef struct ecl_smspec_struct ecl_smspec_type; + +#ifdef __cplusplus +#include +const std::vector& ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ); +const ecl::smspec_node& ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var); +const ecl::smspec_node& ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var); +const ecl::smspec_node& ecl_smspec_get_field_var_node( const ecl_smspec_type * smspec , const char * var); +const ecl::smspec_node& ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr); +const ecl::smspec_node& ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var); +const ecl::smspec_node& ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); +const ecl::smspec_node& ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); +const ecl::smspec_node& ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); +const ecl::smspec_node& ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ); +const ecl::smspec_node& ecl_smspec_iget_node_w_node_index( const ecl_smspec_type * smspec , int node_index ); +const ecl::smspec_node& ecl_smspec_iget_node_w_params_index( const ecl_smspec_type * smspec , int params_index ); +const ecl::smspec_node& ecl_smspec_iget_node(const ecl_smspec_type * smspec, int index); +#endif + #ifdef __cplusplus extern "C" { #endif -typedef struct ecl_smspec_struct ecl_smspec_type; - /** These are the different variable types, see table 3.4 in the @@ -47,10 +64,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type; */ int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_type * other); - const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ); - void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node); - void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node); - void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node ); + const int * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ); ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index ); bool ecl_smspec_needs_num( ecl_smspec_var_type var_type ); bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type ); @@ -71,39 +85,30 @@ typedef struct ecl_smspec_struct ecl_smspec_type; int ecl_smspec_get_date_year_index( const ecl_smspec_type * smspec ); - const smspec_node_type * ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var); int ecl_smspec_get_well_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); bool ecl_smspec_has_well_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); - const smspec_node_type * ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var); int ecl_smspec_get_group_var_params_index(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); bool ecl_smspec_has_group_var(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); - const smspec_node_type * ecl_smspec_get_field_var_node( const ecl_smspec_type * smspec , const char * var); int ecl_smspec_get_field_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *var); - const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr); int ecl_smspec_get_region_var_params_index(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); bool ecl_smspec_has_region_var(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); - const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var); int ecl_smspec_get_misc_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); bool ecl_smspec_has_misc_var(const ecl_smspec_type * ecl_smspec , const char *var); - const smspec_node_type * ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); - const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); - const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); int ecl_smspec_get_well_completion_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); bool ecl_smspec_has_well_completion_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); - const smspec_node_type * ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ); int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec , const char * lookup_kw); @@ -120,7 +125,6 @@ typedef struct ecl_smspec_struct ecl_smspec_type; - void ecl_smspec_init_var( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num, const char * unit ); void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys); stringlist_type * ecl_smspec_alloc_matching_general_var_list(const ecl_smspec_type * smspec , const char * pattern); @@ -138,21 +142,48 @@ typedef struct ecl_smspec_struct ecl_smspec_type; int ecl_smspec_get_restart_step(const ecl_smspec_type * ecl_smspec); const char * ecl_smspec_get_restart_case( const ecl_smspec_type * ecl_smspec); const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec); - const float_vector_type * ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ); const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ); int ecl_smspec_get_params_size( const ecl_smspec_type * smspec ); int ecl_smspec_num_nodes( const ecl_smspec_type * smspec); - const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index ); - char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname); bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * other); - void ecl_smspec_sort( ecl_smspec_type * smspec ); + // void ecl_smspec_sort( ecl_smspec_type * smspec ); ert_ecl_unit_enum ecl_smspec_get_unit_system(const ecl_smspec_type * smspec); + #ifdef __cplusplus } #endif + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const ecl::smspec_node& node); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, int num, const char * unit, float default_value); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, const char * unit, float default_value); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, const char * wgname, const char * unit, float default_value); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, const char * wgname, int num, const char * unit, float default_value); +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, const char * keyword, int num, const char * unit, float default_value); + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, + int params_index, + const char * keyword, + const char * wgname, + int num, + const char * unit, + float default_value); + +const ecl::smspec_node * ecl_smspec_add_node(ecl_smspec_type * ecl_smspec, + int params_index, + const char * keyword, + const char * wgname, + int num, + const char * unit, + const char * lgr, + int lgr_i, int lgr_j, int lgr_k, + float default_value); + + + + #endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp index 84f8977fbb..c41d9091d4 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_subsidence.h' is part of ERT - Ensemble based Reservoir Tool. @@ -47,6 +47,12 @@ extern "C" { double utm_x, double utm_y , double depth, double youngs_modulus, double poisson_ratio, double seabed); + double ecl_subsidence_eval_geertsma_rporv( const ecl_subsidence_type * subsidence , const char * base, const char * monitor , ecl_region_type * region , + double utm_x, double utm_y , double depth, + double youngs_modulus, double poisson_ratio, double seabed); + + + #ifdef __cplusplus } diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp index a66529fb45..201384b878 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum.h' is part of ERT - Ensemble based Reservoir Tool. @@ -58,8 +58,8 @@ typedef struct ecl_sum_vector_struct ecl_sum_vector_type; typedef struct ecl_sum_struct ecl_sum_type; void ecl_sum_fmt_init_summary_x( const ecl_sum_type * ecl_sum , ecl_sum_fmt_type * fmt ); - double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const smspec_node_type * node); - double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const smspec_node_type * node); + double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const ecl::smspec_node * node); + double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const ecl::smspec_node * node); double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time); void ecl_sum_set_unified( ecl_sum_type * ecl_sum , bool unified ); @@ -93,7 +93,7 @@ typedef struct ecl_sum_struct ecl_sum_type; ecl_sum_type * ecl_sum_fread_alloc_case(const char * , const char * key_join_string); ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart); ecl_sum_type * ecl_sum_fread_alloc_case2__(const char * , const char * key_join_string , bool include_restart, bool lazy_load, int file_options); - ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times); + ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation); bool ecl_sum_case_exists( const char * input_file ); /* Accessor functions : */ @@ -130,7 +130,7 @@ typedef struct ecl_sum_struct ecl_sum_type; double ecl_sum_get_general_var(const ecl_sum_type * ecl_sum , int time_index , const char * lookup_kw); int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const char * lookup_kw); - const smspec_node_type * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw); + const ecl::smspec_node * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw); bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw); bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw); double ecl_sum_get_general_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var); @@ -190,7 +190,7 @@ typedef struct ecl_sum_struct ecl_sum_type; stringlist_type * ecl_sum_alloc_well_var_list( const ecl_sum_type * ecl_sum ); stringlist_type * ecl_sum_alloc_matching_general_var_list(const ecl_sum_type * ecl_sum , const char * pattern); void ecl_sum_select_matching_general_var_list( const ecl_sum_type * ecl_sum , const char * pattern , stringlist_type * keys); - const ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ); + ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ); ecl_smspec_var_type ecl_sum_identify_var_type(const char * var); ecl_smspec_var_type ecl_sum_get_var_type( const ecl_sum_type * ecl_sum , const char * gen_key); bool ecl_sum_var_is_rate( const ecl_sum_type * ecl_sum , const char * gen_key); @@ -230,8 +230,8 @@ typedef struct ecl_sum_struct ecl_sum_type; void ecl_sum_fwrite( const ecl_sum_type * ecl_sum ); bool ecl_sum_can_write( const ecl_sum_type * ecl_sum ); void ecl_sum_fwrite_smspec( const ecl_sum_type * ecl_sum ); - smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_node_type * node); - smspec_node_type * ecl_sum_add_var(ecl_sum_type * ecl_sum , + const ecl::smspec_node * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const ecl::smspec_node * node); + const ecl::smspec_node * ecl_sum_add_var(ecl_sum_type * ecl_sum , const char * keyword , const char * wgname , int num , @@ -256,10 +256,10 @@ typedef struct ecl_sum_struct ecl_sum_type; double ecl_sum_iget_last_value(const ecl_sum_type * ecl_sum, int param_index); double ecl_sum_get_last_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); - double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); + double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const ecl::smspec_node *node); double ecl_sum_iget_first_value(const ecl_sum_type * ecl_sum, int param_index); double ecl_sum_get_first_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); - double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); + double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const ecl::smspec_node *node); void ecl_sum_init_datetime64_vector(const ecl_sum_type * ecl_sum, int64_t * data, int multiplier); void ecl_sum_init_double_vector_interp(const ecl_sum_type * ecl_sum, const char * gen_key, const time_t_vector_type * time_points, double * data); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp index 0c6fdbc0b1..22ab10a768 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool. @@ -75,8 +75,8 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ; int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data ); int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data ); - double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node); - double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node); + double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const ecl::smspec_node& smspec_node); + double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const ecl::smspec_node& smspec_node); int ecl_sum_data_get_length( const ecl_sum_data_type * data ); int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index); @@ -92,14 +92,14 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ; void ecl_sum_data_init_datetime64_vector(const ecl_sum_data_type * data, int64_t * output_data, int multiplier); void ecl_sum_data_init_double_frame(const ecl_sum_data_type * data, const ecl_sum_vector_type * keywords, double *output_data); - double_vector_type * ecl_sum_data_alloc_seconds_solution( const ecl_sum_data_type * data , const smspec_node_type * node , double value, bool rates_clamp_lower); + double_vector_type * ecl_sum_data_alloc_seconds_solution( const ecl_sum_data_type * data , const ecl::smspec_node& node , double value, bool rates_clamp_lower); void ecl_sum_data_init_double_frame_interp(const ecl_sum_data_type * data, const ecl_sum_vector_type * keywords, const time_t_vector_type * time_points, double * output_data); void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, - const smspec_node_type * smspec_node, + const ecl::smspec_node& smspec_node, const time_t_vector_type * time_points, double * output_data); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp index d68088f976..bb4a216441 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_sum_index.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp index 4fc332ea00..ac113a5559 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ecl_sum_tstep.h' is part of ERT - Ensemble based Reservoir Tool. @@ -19,15 +19,15 @@ #ifndef ERT_ECL_SUM_TSTEP_H #define ERT_ECL_SUM_TSTEP_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; ecl_sum_tstep_type * ecl_sum_tstep_alloc_remap_copy( const ecl_sum_tstep_type * src , const ecl_smspec_type * new_smspec, float default_value , const int * params_map); @@ -42,6 +42,9 @@ typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; ecl_sum_tstep_type * ecl_sum_tstep_alloc_new( int report_step , int ministep , float sim_seconds , const ecl_smspec_type * smspec ); + void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const ecl::smspec_node& smspec_node , float value); + double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const ecl::smspec_node& smspec_node); + double ecl_sum_tstep_iget(const ecl_sum_tstep_type * ministep , int index); time_t ecl_sum_tstep_get_sim_time(const ecl_sum_tstep_type * ministep); double ecl_sum_tstep_get_sim_days(const ecl_sum_tstep_type * ministep); @@ -50,7 +53,7 @@ typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; int ecl_sum_tstep_get_report(const ecl_sum_tstep_type * ministep); int ecl_sum_tstep_get_ministep(const ecl_sum_tstep_type * ministep); - void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vector_type * index_map , fortio_type * fortio); + void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int * index_map , int index_map_size, fortio_type * fortio); void ecl_sum_tstep_iset( ecl_sum_tstep_type * tstep , int index , float value); /// scales with value; equivalent to iset( iget() * scalar) @@ -59,8 +62,6 @@ typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; /// adds addend to tstep[index]; equivalent to iset( iget() + addend) void ecl_sum_tstep_ishift(ecl_sum_tstep_type * tstep, int index, float addend); - void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node , float value); - double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node); void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_key , float value); double ecl_sum_tstep_get_from_key( const ecl_sum_tstep_type * tstep , const char * gen_key); @@ -75,5 +76,7 @@ typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; #ifdef __cplusplus } + + #endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp index c9e4ed9c42..b04dee0c8e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ecl_sum_vector.h' is part of ERT - Ensemble based Reservoir Tool. @@ -19,14 +19,14 @@ #ifndef ERT_ECL_SUM_VECTOR_H #define ERT_ECL_SUM_VECTOR_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct ecl_sum_vector_struct ecl_sum_vector_type; void ecl_sum_vector_free( ecl_sum_vector_type * keylist ); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp index a218330974..305498057e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_type.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp index ecee98a662..c752ff4438 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ecl_units.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp index 0cf1ada4b7..590068d135 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp index 5d9ebbc27a..ec0b8ad41a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'fault_block.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp index 745fa509d9..2d84d396dd 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'fault_block_layer.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fortio.h b/ThirdParty/Ert/lib/include/ert/ecl/fortio.h index 93a56eb827..c2228d784c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fortio.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/fortio.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'fortio.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp index b7955cf404..510f86d89d 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp b/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp index 450ee240d3..27c0f268f4 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'layer.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp index 91858cefbf..a6b6efc0a5 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'nnc_info.h' is part of ERT - Ensemble based Reservoir Tool. @@ -19,16 +19,24 @@ #ifndef ERT_NNC_INFO_H #define ERT_NNC_INFO_H -#ifdef __cplusplus -extern "C" { -#endif #include #include #include - typedef struct nnc_info_struct nnc_info_type; +typedef struct nnc_info_struct nnc_info_type; + +#ifdef __cplusplus +#include + const std::vector& nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr); + const std::vector& nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index); + const std::vector& nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info); +#endif + +#ifdef __cplusplus +extern "C" { +#endif UTIL_IS_INSTANCE_HEADER(nnc_info); @@ -36,13 +44,10 @@ extern "C" { void nnc_info_free( nnc_info_type * nnc_info ); void nnc_info_add_nnc(nnc_info_type * nnc_info, int lgr_nr, int global_cell_number, int nnc_index); - const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index); nnc_vector_type * nnc_info_iget_vector( const nnc_info_type * nnc_info , int lgr_index); - const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr); nnc_vector_type * nnc_info_get_vector( const nnc_info_type * nnc_info , int lgr_nr); - const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info); nnc_vector_type * nnc_info_get_self_vector( const nnc_info_type * nnc_info ); int nnc_info_get_lgr_nr(const nnc_info_type * nnc_info ); @@ -52,6 +57,7 @@ extern "C" { bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 ); nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ); + bool nnc_info_has_grid_index_list( const nnc_info_type * nnc_info, int lgr_nr ); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp index 3c5f6c304c..741bbaa5aa 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'nnc_vector.h' is part of ERT - Ensemble based Reservoir Tool. @@ -19,14 +19,21 @@ #ifndef ERT_NNC_VECTOR_H #define ERT_NNC_VECTOR_H -#ifdef __cplusplus -extern "C" { -#endif #include #include - typedef struct nnc_vector_struct nnc_vector_type; +typedef struct nnc_vector_struct nnc_vector_type; + +#ifdef __cplusplus +#include + const std::vector& nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector); + const std::vector& nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector); +#endif + +#ifdef __cplusplus +extern "C" { +#endif UTIL_IS_INSTANCE_HEADER(nnc_vector); @@ -36,8 +43,6 @@ extern "C" { nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector); void nnc_vector_free( nnc_vector_type * nnc_vector ); void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number, int nnc_index); - const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector); - const int_vector_type * nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector); int nnc_vector_get_lgr_nr(const nnc_vector_type * nnc_vector ); void nnc_vector_free__(void * arg); int nnc_vector_get_size( const nnc_vector_type * nnc_vector ); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h index e0e4b77ccd..b058fc8898 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h @@ -4,6 +4,133 @@ to switch to include the new hpp header directly in your code. */ -#include +#include +#include + +#ifndef ERT_SMSPEC_NODE_H +#define ERT_SMSPEC_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DUMMY_WELL ":+:+:+:+" +#define IS_DUMMY_WELL(well) (strcmp((well) , DUMMY_WELL) == 0) +#define SMSPEC_PARAMS_INDEX_INVALID -77 + + +#define SMSPEC_TIME_KEYWORD "TIME" +#define SMSPEC_TIME_NUMS_VALUE -32676 + +#define SMSPEC_YEARS_KEYWORD "YEARS" +#define SMSPEC_YEARS_NUMS_VALUE -32676 + +typedef enum {ECL_SMSPEC_INVALID_VAR = 0 , + ECL_SMSPEC_FIELD_VAR = 1 , /* X */ + ECL_SMSPEC_REGION_VAR = 2 , /* X */ + ECL_SMSPEC_GROUP_VAR = 3 , /* X */ + ECL_SMSPEC_WELL_VAR = 4 , /* X */ + ECL_SMSPEC_SEGMENT_VAR = 5 , /* X */ + ECL_SMSPEC_BLOCK_VAR = 6 , /* X */ + ECL_SMSPEC_AQUIFER_VAR = 7 , + ECL_SMSPEC_COMPLETION_VAR = 8 , /* X */ + ECL_SMSPEC_NETWORK_VAR = 9 , + ECL_SMSPEC_REGION_2_REGION_VAR = 10 , + ECL_SMSPEC_LOCAL_BLOCK_VAR = 11 , /* X */ + ECL_SMSPEC_LOCAL_COMPLETION_VAR = 12 , /* X */ + ECL_SMSPEC_LOCAL_WELL_VAR = 13 , /* X */ + ECL_SMSPEC_MISC_VAR = 14 /* X */} ecl_smspec_var_type; + +#define SMSPEC_NUMS_INVALID -991199 +#define SMSPEC_NUMS_WELL 1 +#define SMSPEC_NUMS_GROUP 2 +#define SMSPEC_NUMS_FIELD 0 + +#define SMSPEC_TYPE_ID 61550451 + + char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k); + char * smspec_alloc_completion_ijk_key( const char * join_string , const char * keyword, const char * wgname , int i , int j , int k); + char * smspec_alloc_completion_num_key( const char * join_string , const char * keyword, const char * wgname , int num); + char * smspec_alloc_group_key( const char * join_string , const char * keyword , const char * wgname); + char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname); + char * smspec_alloc_region_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_region_2_region_r1r2_key( const char * join_string , const char * keyword , int r1, int r2); + char * smspec_alloc_region_2_region_num_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_segment_key( const char * join_string , const char * keyword , const char * wgname , int num); + char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_local_well_key( const char * join_string , const char * keyword , const char * lgr_name , const char * wgname); + char * smspec_alloc_local_block_key( const char * join_string , const char * keyword , const char * lgr_name , int i , int j , int k); + char * smspec_alloc_local_completion_key( const char * join_string, const char * keyword , const char * lgr_name , const char * wgname , int i , int j , int k); + + bool smspec_node_identify_total(const char * keyword, ecl_smspec_var_type var_type); + bool smspec_node_identify_rate(const char * keyword); + + bool smspec_node_equal( const void * node1, const void * node2); + + void smspec_node_init( void * smspec_node, + ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num); + + void * smspec_node_alloc( int param_index, + const char * keyword , + const char * wgname, + int num, + const char * unit , + const int grid_dims[3] , + float default_value, + const char * key_join_string); + + void * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * lgr , + const char * key_join_string , + int lgr_i, int lgr_j , int lgr_k, + int param_index, + float default_value); + + void * smspec_node_alloc_copy( const void* ); + + void smspec_node_free( void * index ); + void smspec_node_free__(void * arg); + void smspec_node_set_params_index( void * smspec_node , int params_index); + int smspec_node_get_params_index( const void * smspec_node ); + const char * smspec_node_get_gen_key1( const void * smspec_node); + const char * smspec_node_get_gen_key2( const void * smspec_node); + ecl_smspec_var_type smspec_node_get_var_type( const void * smspec_node); + int smspec_node_get_num( const void * smspec_node); + const char * smspec_node_get_wgname( const void * smspec_node); + const char * smspec_node_get_keyword( const void * smspec_node); + const char * smspec_node_get_unit( const void * smspec_node); + bool smspec_node_is_rate( const void * smspec_node ); + bool smspec_node_is_total( const void * smspec_node ); + bool smspec_node_is_historical( const void * smspec_node ); + bool smspec_node_need_nums( const void * smspec_node ); + void smspec_node_fprintf( const void * smspec_node , FILE * stream); + + float smspec_node_get_default( const void * smspec_node); + + const int* smspec_node_get_ijk( const void * smpsec_node ); + const char* smspec_node_get_lgr_name( const void * smpsec_node ); + const int* smspec_node_get_lgr_ijk( const void * smpsec_node ); + + int smspec_node_get_R1( const void * smpsec_node ); + int smspec_node_get_R2( const void * smpsec_node ); + + bool smspec_node_lt( const void * node1, const void * node2); + bool smspec_node_gt( const void * node1, const void * node2); + int smspec_node_cmp( const void * node1, const void * node2); + int smspec_node_cmp__( const void * node1, const void * node2); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp index a8dfc0dba2..50dd00e451 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'smspec_node.h' is part of ERT - Ensemble based Reservoir Tool. @@ -17,132 +17,110 @@ */ -#ifndef ERT_SMSPEC_NODE_H -#define ERT_SMSPEC_NODE_H +#ifndef ERT_SMSPEC_NODE_HPP +#define ERT_SMSPEC_NODE_HPP #include #include -#ifdef __cplusplus -extern "C" { -#endif +#include +#include -#define DUMMY_WELL ":+:+:+:+" -#define IS_DUMMY_WELL(well) (strcmp((well) , DUMMY_WELL) == 0) -#define SMSPEC_PARAMS_INDEX_INVALID -77 +#include + +#include -#define SMSPEC_TIME_KEYWORD "TIME" -#define SMSPEC_TIME_NUMS_VALUE -32676 +namespace ecl { -#define SMSPEC_YEARS_KEYWORD "YEARS" -#define SMSPEC_YEARS_NUMS_VALUE -32676 + class smspec_node { + private: + std::string wgname; + std::string keyword; /* The value of the KEYWORDS vector for this elements. */ + std::string unit; /* The value of the UNITS vector for this elements. */ + int num; /* The value of the NUMS vector for this elements - NB this will have the value SMSPEC_NUMS_INVALID if the smspec file does not have a NUMS vector. */ + std::string lgr_name; /* The lgr name of the current variable - will be NULL for non-lgr variables. */ + std::array lgr_ijk; -typedef enum {ECL_SMSPEC_INVALID_VAR = 0 , - ECL_SMSPEC_FIELD_VAR = 1 , /* X */ - ECL_SMSPEC_REGION_VAR = 2 , /* X */ - ECL_SMSPEC_GROUP_VAR = 3 , /* X */ - ECL_SMSPEC_WELL_VAR = 4 , /* X */ - ECL_SMSPEC_SEGMENT_VAR = 5 , /* X */ - ECL_SMSPEC_BLOCK_VAR = 6 , /* X */ - ECL_SMSPEC_AQUIFER_VAR = 7 , - ECL_SMSPEC_COMPLETION_VAR = 8 , /* X */ - ECL_SMSPEC_NETWORK_VAR = 9 , - ECL_SMSPEC_REGION_2_REGION_VAR = 10 , - ECL_SMSPEC_LOCAL_BLOCK_VAR = 11 , /* X */ - ECL_SMSPEC_LOCAL_COMPLETION_VAR = 12 , /* X */ - ECL_SMSPEC_LOCAL_WELL_VAR = 13 , /* X */ - ECL_SMSPEC_MISC_VAR = 14 /* X */} ecl_smspec_var_type; + /*------------------------------------------- All members below this line are *derived* quantities. */ + std::string gen_key1; /* The main composite key, i.e. WWCT:OP3 for this element. */ + std::string gen_key2; /* Some of the ijk based elements will have both a xxx:i,j,k and a xxx:num key. Some of the region_2_region elements will have both a xxx:num and a xxx:r2-r2 key. Mostly NULL. */ + ecl_smspec_var_type var_type; /* The variable type */ + std::array ijk; /* The ijk coordinates (NB: OFFSET 1) corresponding to the nums value - will be NULL if not relevant. */ + bool rate_variable; /* Is this a rate variable (i.e. WOPR) or a state variable (i.e. BPR). Relevant when doing time interpolation. */ + bool total_variable; /* Is this a total variable like WOPT? */ + bool historical; /* Does the name end with 'H'? */ + int params_index; /* The index of this variable (applies to all the vectors - in particular the PARAMS vectors of the summary files *.Snnnn / *.UNSMRY ). */ + float default_value; /* Default value for this variable. */ -#define SMSPEC_NUMS_INVALID -991199 -#define SMSPEC_NUMS_WELL 1 -#define SMSPEC_NUMS_GROUP 2 -#define SMSPEC_NUMS_FIELD 0 + static ecl_smspec_var_type identify_special_var( const char * var ); + void set_wgname(const char * wgname); + void set_num( const int grid_dims[3] , int num_); + void set_gen_keys( const char * key_join_string_); + void decode_R1R2( int * r1 , int * r2) const; + void set_lgr_ijk( int lgr_i , int lgr_j , int lgr_k); - typedef struct smspec_node_struct smspec_node_type; + public: - char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k); - char * smspec_alloc_completion_ijk_key( const char * join_string , const char * keyword, const char * wgname , int i , int j , int k); - char * smspec_alloc_completion_num_key( const char * join_string , const char * keyword, const char * wgname , int num); - char * smspec_alloc_group_key( const char * join_string , const char * keyword , const char * wgname); - char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname); - char * smspec_alloc_region_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_region_2_region_r1r2_key( const char * join_string , const char * keyword , int r1, int r2); - char * smspec_alloc_region_2_region_num_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_segment_key( const char * join_string , const char * keyword , const char * wgname , int num); - char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_local_well_key( const char * join_string , const char * keyword , const char * lgr_name , const char * wgname); - char * smspec_alloc_local_block_key( const char * join_string , const char * keyword , const char * lgr_name , int i , int j , int k); - char * smspec_alloc_local_completion_key( const char * join_string, const char * keyword , const char * lgr_name , const char * wgname , int i , int j , int k); + static ecl_smspec_var_type valid_type(const char * keyword, const char * wgname, int num); + int cmp(const smspec_node& node2) const; + static int cmp(const smspec_node& node1, const smspec_node& node2); - bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2); + smspec_node(int param_index, + const char * keyword , + const char * wgname, + int num, + const char * unit , + const int grid_dims[3] , + float default_value, + const char * key_join_string); - void smspec_node_init( smspec_node_type * smspec_node, - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num); + smspec_node(int param_index, + const char * keyword , + const char * wgname , + const char * unit , + const char * lgr , + int lgr_i, int lgr_j , int lgr_k, + float default_value, + const char * key_join_string); - smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num , int param_index, float default_value); + smspec_node(int param_index, const char * keyword, const char * unit, float default_value); + smspec_node(int param_index, const char * keyword, int num, const char * unit, const int grid_dims[3], float default_value, const char * key_join_string); + smspec_node(int param_index, const char * keyword, int num, const char * unit, float default_value, const char * key_join_string); + smspec_node(int param_index, const char * keyword, const char * wgname, const char * unit, float default_value, const char * key_join_string); + smspec_node(int param_index, const char * keyword, const char * wgname, int num, const char * unit, float default_value, const char * key_join_string); + smspec_node(const smspec_node& node, int param_index); - smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * lgr , - const char * key_join_string , - int lgr_i, int lgr_j , int lgr_k, - int param_index, - float default_value); + static ecl_smspec_var_type identify_var_type(const char * var); - smspec_node_type * smspec_node_alloc_new(int params_index, float default_value); - smspec_node_type * smspec_node_alloc_copy( const smspec_node_type* ); + static int cmp( const smspec_node * node1, const smspec_node * node2) { + return node1->cmp(*node2); + } - void smspec_node_free( smspec_node_type * index ); - void smspec_node_free__(void * arg); - void smspec_node_set_params_index( smspec_node_type * smspec_node , int params_index); - int smspec_node_get_params_index( const smspec_node_type * smspec_node ); - const char * smspec_node_get_gen_key1( const smspec_node_type * smspec_node); - const char * smspec_node_get_gen_key2( const smspec_node_type * smspec_node); - ecl_smspec_var_type smspec_node_get_var_type( const smspec_node_type * smspec_node); - int smspec_node_get_num( const smspec_node_type * smspec_node); - const char * smspec_node_get_wgname( const smspec_node_type * smspec_node); - const char * smspec_node_get_keyword( const smspec_node_type * smspec_node); - const char * smspec_node_get_unit( const smspec_node_type * smspec_node); - void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit ); - bool smspec_node_is_rate( const smspec_node_type * smspec_node ); - bool smspec_node_is_total( const smspec_node_type * smspec_node ); - bool smspec_node_is_historical( const smspec_node_type * smspec_node ); - bool smspec_node_need_nums( const smspec_node_type * smspec_node ); - void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream); + int get_R1() const; + int get_R2() const; + const char * get_gen_key1() const; + const char * get_gen_key2() const; + ecl_smspec_var_type get_var_type() const; + int get_num() const; + const char * get_wgname() const; + const char * get_keyword() const; + const char * get_unit() const; + bool is_rate() const; + bool is_total() const; + bool is_historical() const; + bool need_nums() const; + void fprintf__( FILE * stream) const; + int get_params_index() const; + float get_default() const; + const std::array& get_ijk() const; + const char * get_lgr_name() const; + const std::array& get_lgr_ijk() const; - void smspec_node_set_default( smspec_node_type * smspec_node , float default_value); - float smspec_node_get_default( const smspec_node_type * smspec_node); + }; - const int* smspec_node_get_ijk( const smspec_node_type * smpsec_node ); - const char* smspec_node_get_lgr_name( const smspec_node_type * smpsec_node ); - const int* smspec_node_get_lgr_ijk( const smspec_node_type * smpsec_node ); - - int smspec_node_get_R1( const smspec_node_type * smpsec_node ); - int smspec_node_get_R2( const smspec_node_type * smpsec_node ); - - int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2); - int smspec_node_cmp__( const void * node1, const void * node2); - bool smspec_node_identify_total(const char * keyword, ecl_smspec_var_type var_type); - bool smspec_node_identify_rate(const char * keyword); - -#ifdef __cplusplus } -#endif + #endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp index d7aca7a963..c8c942ce96 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_branch_collection.h' is part of ERT - Ensemble based Reservoir Tool. @@ -40,7 +40,7 @@ extern "C" { int well_branch_collection_get_size( const well_branch_collection_type * branches ); const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index ); const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id); - bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment); + bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , well_segment_type * start_segment); UTIL_IS_INSTANCE_HEADER( well_branch_collection ); diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp index 610779ab5d..eabcbc421b 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_conn.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp index 3cc9a178c8..e08fe23674 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_conn_collection.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp index 41a2ade9f2..833e5c9b00 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_const.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp index b7bad41564..b3474c0db5 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp index 1270fba0d8..2060487ded 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp index 084cfea8da..cee97fe73d 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp index fc4dd95d45..270d1171bb 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'well_segment_collection.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp index c41e215685..b6151b9aae 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_state.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp index 5044b685b0..572462790b 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'well_ts.h' is part of ERT - Ensemble based Reservoir Tool. @@ -37,7 +37,7 @@ extern "C" { well_state_type * well_ts_get_state_from_report( const well_ts_type * well_ts , int report_nr); well_state_type * well_ts_iget_state( const well_ts_type * well_ts , int index); int well_ts_get_size( const well_ts_type * well_ts); - char * well_ts_get_name( const well_ts_type * well_ts); + const char * well_ts_get_name( const well_ts_type * well_ts); well_state_type * well_ts_get_first_state( const well_ts_type * well_ts); well_state_type * well_ts_get_last_state( const well_ts_type * well_ts); diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp index 7e549e6852..d591c513f0 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_pointset.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp index b7287644b8..675942701a 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_polygon.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp index 1ee312ee10..36777e1a8a 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'geo_polygon_collection.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp index e719112d2c..882c1553e4 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_region.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp index 8a827b5b88..b5c77dc136 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_surface.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp index a988963dbc..b02d56df83 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'geo_util.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/atomic.h b/ThirdParty/Ert/lib/include/ert/util/atomic.h index 08aae0110e..16cf9a1f2d 100644 --- a/ThirdParty/Ert/lib/include/ert/util/atomic.h +++ b/ThirdParty/Ert/lib/include/ert/util/atomic.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'atomic.h' is part of ERT - Ensemble based Reservoir Tool. @@ -30,124 +30,124 @@ /** - * Atomic type. - */ +�* Atomic type. +�*/ typedef struct { volatile int counter; } atomic_t; -#define ATOMIC_INIT(i)  { (i) } +#define ATOMIC_INIT(i) �{ (i) } /** - * Read atomic variable - * @param v pointer of type atomic_t - * - * Atomically reads the value of @v. - */ +�* Read atomic variable +�* @param v pointer of type atomic_t +�* +�* Atomically reads the value of @v. +�*/ #define atomic_read(v) ((v)->counter) /** - * Set atomic variable - * @param v pointer of type atomic_t - * @param i required value - */ +�* Set atomic variable +�* @param v pointer of type atomic_t +�* @param i required value +�*/ #define atomic_set(v,i) (((v)->counter) = (i)) /** - * Add to the atomic variable - * @param i integer value to add - * @param v pointer of type atomic_t - */ +�* Add to the atomic variable +�* @param i integer value to add +�* @param v pointer of type atomic_t +�*/ static inline void atomic_add( int i, atomic_t *v ) { (void)__sync_add_and_fetch(&v->counter, i); } /** - * Subtract the atomic variable - * @param i integer value to subtract - * @param v pointer of type atomic_t - * - * Atomically subtracts @i from @v. - */ +�* Subtract the atomic variable +�* @param i integer value to subtract +�* @param v pointer of type atomic_t +�* +�* Atomically subtracts @i from @v. +�*/ static inline void atomic_sub( int i, atomic_t *v ) { (void)__sync_sub_and_fetch(&v->counter, i); } /** - * Subtract value from variable and test result - * @param i integer value to subtract - * @param v pointer of type atomic_t - * - * Atomically subtracts @i from @v and returns - * true if the result is zero, or false for all - * other cases. - */ +�* Subtract value from variable and test result +�* @param i integer value to subtract +�* @param v pointer of type atomic_t +�* +�* Atomically subtracts @i from @v and returns +�* true if the result is zero, or false for all +�* other cases. +�*/ static inline int atomic_sub_and_test( int i, atomic_t *v ) { return !(__sync_sub_and_fetch(&v->counter, i)); } /** - * Increment atomic variable - * @param v pointer of type atomic_t - * - * Atomically increments @v by 1. - */ +�* Increment atomic variable +�* @param v pointer of type atomic_t +�* +�* Atomically increments @v by 1. +�*/ static inline void atomic_inc( atomic_t *v ) { (void)__sync_fetch_and_add(&v->counter, 1); } /** - * @brief decrement atomic variable - * @param v: pointer of type atomic_t - * - * Atomically decrements @v by 1.  Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ +�* @brief decrement atomic variable +�* @param v: pointer of type atomic_t +�* +�* Atomically decrements @v by 1. �Note that the guaranteed +�* useful range of an atomic_t is only 24 bits. +�*/ static inline void atomic_dec( atomic_t *v ) { (void)__sync_fetch_and_sub(&v->counter, 1); } /** - * @brief Decrement and test - * @param v pointer of type atomic_t - * - * Atomically decrements @v by 1 and - * returns true if the result is 0, or false for all other - * cases. - */ +�* @brief Decrement and test +�* @param v pointer of type atomic_t +�* +�* Atomically decrements @v by 1 and +�* returns true if the result is 0, or false for all other +�* cases. +�*/ static inline int atomic_dec_and_test( atomic_t *v ) { return !(__sync_sub_and_fetch(&v->counter, 1)); } /** - * @brief Increment and test - * @param v pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ +�* @brief Increment and test +�* @param v pointer of type atomic_t +�* +�* Atomically increments @v by 1 +�* and returns true if the result is zero, or false for all +�* other cases. +�*/ static inline int atomic_inc_and_test( atomic_t *v ) { return !(__sync_add_and_fetch(&v->counter, 1)); } /** - * @brief add and test if negative - * @param v pointer of type atomic_t - * @param i integer value to add - * - * Atomically adds @i to @v and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. - */ +�* @brief add and test if negative +�* @param v pointer of type atomic_t +�* @param i integer value to add +�* +�* Atomically adds @i to @v and returns true +�* if the result is negative, or false when +�* result is greater than or equal to zero. +�*/ static inline int atomic_add_negative( int i, atomic_t *v ) { return (__sync_add_and_fetch(&v->counter, i) < 0); @@ -168,14 +168,14 @@ static inline int atomic_add_negative( int i, atomic_t *v ) // ////As a second example, consider a compare and swap operation, frequently used in lock-free algorithms. Once again, it's trivially: ///** -// * @brief compare and swap -// * @param v pointer of type atomic_t -// * -// * If the current value of @b v is @b oldval, -// * then write @b newval into @b v. Returns #TRUE if -// * the comparison is successful and @b newval was -// * written. -// */ +//�* @brief compare and swap +//�* @param v pointer of type atomic_t +//�* +//�* If the current value of @b v is @b oldval, +//�* then write @b newval into @b v. Returns #TRUE if +//�* the comparison is successful and @b newval was +//�* written. +//�*/ //static inline int atomic_cas( atomic_t *v, int oldval, int newval ) //{ // return __sync_bool_compare_and_swap(&v->counter, oldval, newval); diff --git a/ThirdParty/Ert/lib/include/ert/util/buffer.hpp b/ThirdParty/Ert/lib/include/ert/util/buffer.hpp index 167028a46b..0784c33c4b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/buffer.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/buffer.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'buffer.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp b/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp index 83c39ae8b2..c431152a91 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ecl_version.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/hash.hpp b/ThirdParty/Ert/lib/include/ert/util/hash.hpp index deae544285..4fdc1426ab 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp b/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp index 8579068ebb..bc0a7194b8 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash_node.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp b/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp index 2af6319e41..4a830e1374 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash_sll.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp b/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp index 9658cd411b..781842d127 100644 --- a/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'lookup_table.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/mzran.hpp b/ThirdParty/Ert/lib/include/ert/util/mzran.hpp index 06315a06ce..fbabf0d3c1 100644 --- a/ThirdParty/Ert/lib/include/ert/util/mzran.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/mzran.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'mzran.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp b/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp index 344a3aa0f3..57c91d6698 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'node_ctype.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/node_data.hpp b/ThirdParty/Ert/lib/include/ert/util/node_data.hpp index 4e572f1836..a4aa3d0ad4 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/node_data.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'node_data.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/parser.hpp b/ThirdParty/Ert/lib/include/ert/util/parser.hpp index d00e311f0f..250cea4fc9 100644 --- a/ThirdParty/Ert/lib/include/ert/util/parser.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/parser.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'parser.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp b/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp index 7da9f9fc27..237852e3ac 100644 --- a/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'path_stack.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp b/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp index 60662c2e9b..539c2d4e50 100644 --- a/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'perm_vector.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/rng.hpp b/ThirdParty/Ert/lib/include/ert/util/rng.hpp index 2964296877..2576ae7143 100644 --- a/ThirdParty/Ert/lib/include/ert/util/rng.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/rng.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'rng.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp b/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp index 10507fa5d9..9a6c894e76 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ssize_t.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/statistics.hpp b/ThirdParty/Ert/lib/include/ert/util/statistics.hpp index 5a14bb390a..27da8dda20 100644 --- a/ThirdParty/Ert/lib/include/ert/util/statistics.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/statistics.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'statistics.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/string_util.hpp b/ThirdParty/Ert/lib/include/ert/util/string_util.hpp index dc43464a76..e6f5d212a2 100644 --- a/ThirdParty/Ert/lib/include/ert/util/string_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/string_util.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'string_util.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp b/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp index 8e8176739d..0596c178ef 100644 --- a/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'stringlist.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/test_util.hpp b/ThirdParty/Ert/lib/include/ert/util/test_util.hpp index 0e3087681d..939fc516fd 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/test_util.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'test_util.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp b/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp index e988012536..8faff93d22 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'test_work_area.h' is part of ERT - Ensemble based Reservoir Tool. @@ -20,36 +20,58 @@ #ifndef ERT_TEST_WORK_AREA_H #define ERT_TEST_WORK_AREA_H +#include + +namespace ecl { +namespace util { + +class TestArea { +public: + TestArea(const std::string& test_name, bool store_area = false); + ~TestArea(); + const std::string& test_cwd() const; + const std::string& original_cwd() const; + + void copy_directory(const std::string input_directory) const; + void copy_directory_content(const std::string input_directory) const; + bool copy_parent(const std::string input_path) const; + bool copy_parent_content(const std::string original_path) const; + + void copy_file(const std::string& input_src_file) const; + std::string original_path(const std::string& input_path) const; + +private: + bool store; + std::string cwd; + std::string org_cwd; +}; + + +} +} + +typedef ecl::util::TestArea test_work_area_type; + #ifdef __cplusplus extern "C" { #endif #include -#include - - typedef struct test_work_area_struct test_work_area_type; - char * test_work_area_alloc_input_path( const test_work_area_type * work_area , const char * input_path ); test_work_area_type * test_work_area_alloc(const char * test_name ); + test_work_area_type * test_work_area_alloc__(const char * test_name, bool store_area ); test_work_area_type * test_work_area_alloc_relative(const char * prefix , const char * test_path); - void test_work_area_set_store( test_work_area_type * work_area , bool store); void test_work_area_free(test_work_area_type * work_area); const char * test_work_area_get_cwd( const test_work_area_type * work_area ); const char * test_work_area_get_original_cwd( const test_work_area_type * work_area ); - void test_work_area_install_file( test_work_area_type * work_area , const char * input_src_file ); - void test_work_area_copy_directory( test_work_area_type * work_area , const char * input_directory); - void test_work_area_copy_directory_content( test_work_area_type * work_area , const char * input_directory); - void test_work_area_copy_file( test_work_area_type * work_area , const char * input_file); - bool test_work_area_copy_parent_directory( test_work_area_type * work_area , const char * input_path); - bool test_work_area_copy_parent_content( test_work_area_type * work_area , const char * input_path); - void test_work_area_sync( test_work_area_type * work_area); - - test_work_area_type * temp_area_alloc_relative(const char * prefix , const char * test_path); - test_work_area_type * temp_area_alloc(const char * test_path); - - UTIL_IS_INSTANCE_HEADER( test_work_area ); + void test_work_area_install_file( const test_work_area_type * work_area , const char * input_src_file ); + void test_work_area_copy_directory( const test_work_area_type * work_area , const char * input_directory); + void test_work_area_copy_directory_content( const test_work_area_type * work_area , const char * input_directory); + void test_work_area_copy_file( const test_work_area_type * work_area , const char * input_file); + bool test_work_area_copy_parent_directory( const test_work_area_type * work_area , const char * input_path); + bool test_work_area_copy_parent_content( const test_work_area_type * work_area , const char * input_path); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h b/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h index be605c0ba3..b5b6111692 100644 --- a/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h +++ b/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'thread_pool1.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp b/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp index 939a2748e4..c35438a68a 100644 --- a/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. This is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/timer.hpp b/ThirdParty/Ert/lib/include/ert/util/timer.hpp index 8830222065..619c5b6164 100644 --- a/ThirdParty/Ert/lib/include/ert/util/timer.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/timer.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'timer.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp index f607faf163..69b7bf638b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'type_vector_functions.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/util.h b/ThirdParty/Ert/lib/include/ert/util/util.h index 5d44346560..fff69fc5ac 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util.h +++ b/ThirdParty/Ert/lib/include/ert/util/util.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'util.h' is part of ERT - Ensemble based Reservoir Tool. @@ -96,16 +96,9 @@ typedef bool (walk_dir_callback_ftype) (const char * , /* The current director void *); /* Arbitrary argument */ - -typedef enum {left_pad = 0, - right_pad = 1, - center_pad = 2} string_alignement_type; - - //#define UTIL_CXX_MALLOC(var , num_elm) (typeof (var)) util_malloc( (num_elm) * sizeof var) char * util_get_timezone(void); time_t util_make_datetime_utc(int , int , int , int , int , int ); bool util_make_datetime_utc_validated(int sec, int min, int hour , int mday , int month , int year, time_t * t); - void util_fprintf_date_utc(time_t , FILE * ); time_t util_make_date_utc(int , int , int); time_t util_make_pure_date_utc(time_t t); void util_inplace_forward_seconds_utc(time_t * t , double seconds); @@ -128,9 +121,6 @@ typedef enum {left_pad = 0, char * util_alloc_sprintf_va(const char * fmt , va_list ap); char * util_alloc_sprintf(const char * , ...); char * util_realloc_sprintf(char * , const char * , ...); - void util_fprintf_int(int , int , FILE * ); - void util_fprintf_string(const char * , int , string_alignement_type , FILE * ); - void util_fprintf_double(double , int , int , char , FILE *); bool util_fscanf_date_utc(FILE * , time_t *); bool util_sscanf_date_utc(const char * , time_t *); bool util_sscanf_isodate(const char * , time_t *); @@ -237,7 +227,6 @@ typedef enum {left_pad = 0, char * util_alloc_filename(const char * , const char * , const char * ); char * util_realloc_filename(char * , const char * , const char * , const char * ); char * util_alloc_strip_copy(const char *); - void util_set_strip_copy(char * , const char *); char * util_alloc_string_sum(const char ** , int); char * util_strcat_realloc(char *, const char * ); char * util_alloc_string_copy(const char *); diff --git a/ThirdParty/Ert/lib/include/ert/util/util.hpp b/ThirdParty/Ert/lib/include/ert/util/util.hpp index 8d293d4382..e7ca212096 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/util.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. This is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/util_endian.h b/ThirdParty/Ert/lib/include/ert/util/util_endian.h index 96f2399f4a..4a4e145fa9 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util_endian.h +++ b/ThirdParty/Ert/lib/include/ert/util/util_endian.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'util_endian.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/util_unlink.h b/ThirdParty/Ert/lib/include/ert/util/util_unlink.h index 3fc1e232c5..4d0766de6e 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util_unlink.h +++ b/ThirdParty/Ert/lib/include/ert/util/util_unlink.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'util_unlink.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/vector.hpp b/ThirdParty/Ert/lib/include/ert/util/vector.hpp index ff4f526bc2..ffcf764572 100644 --- a/ThirdParty/Ert/lib/include/ert/util/vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/vector.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vector.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/include/ert/util/vector_util.hpp b/ThirdParty/Ert/lib/include/ert/util/vector_util.hpp new file mode 100644 index 0000000000..6ddc913466 --- /dev/null +++ b/ThirdParty/Ert/lib/include/ert/util/vector_util.hpp @@ -0,0 +1,52 @@ +/* + Copyright (C) 2018 Equinor ASA, Norway. + + The file 'vector_util.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 + for more details. +*/ + +#include + +#include +#include + +template +int vector_util_index(const std::vector& vec, T value) { + + int index; + auto iter = find(vec.begin(), vec.end(), value); + if (iter == vec.end()) + index = -1; + else + index = iter - vec.begin(); + return index; +} + + +template +void vector_util_fprintf(const std::vector& vec , FILE * stream , const char * name , const char * fmt) { + size_t i; + if (name != NULL) + fprintf(stream , "%s = [" , name); + else + fprintf(stream , "["); + + for (i = 0; i < vec.size(); i++) { + fprintf(stream , fmt , vec[i]); + if (i < (vec.size() - 1)) + fprintf(stream , ", "); + } + + fprintf(stream , "]\n"); +} diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp index cb96cee2e7..60543c500e 100644 --- a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'ecl_grid_cache.h' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp index 3435cc6017..e323a307f6 100644 --- a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp @@ -141,7 +141,7 @@ private: void build_index(); void fwrite_report( int report_step , fortio_type * fortio) const; bool check_file( ecl_file_type * ecl_file ); - void add_ecl_file(int report_step, const ecl_file_view_type * summary_view, const ecl_smspec_type * smspec); + void add_ecl_file(int report_step, const ecl_file_view_type * summary_view); }; diff --git a/ThirdParty/Ert/lib/util/buffer.cpp b/ThirdParty/Ert/lib/util/buffer.cpp index 909b220f91..64eaf25dec 100644 --- a/ThirdParty/Ert/lib/util/buffer.cpp +++ b/ThirdParty/Ert/lib/util/buffer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'buffer.c' is part of ERT - Ensemble based Reservoir Tool. @@ -563,12 +563,36 @@ void buffer_replace_string( buffer_type * buffer , size_t offset , size_t old_si touching internal state. */ +namespace { + + /* + This homemade strstr() implementation is used here because we can not + guarantee that the buffer->data is '\0' terminated and then normal strstr() + gives undefined behaviour - problem found with address sanitizer. + */ + + const char * memcmp_strstr(const char * buffer, size_t buffer_size, const char * expr) { + size_t N = strlen(expr); + const char * pos = buffer; + while (true) { + if (buffer_size < N) + return NULL; + + if (memcmp(pos, expr, N) == 0) + return pos; + + pos++; + buffer_size--; + } + } +} + bool buffer_strstr( buffer_type * buffer , const char * expr ) { bool match = false; if (strlen(expr) > 0) { - char * match_ptr = strstr( &buffer->data[buffer->pos] , expr ); + const char * match_ptr = memcmp_strstr( &buffer->data[buffer->pos], buffer->content_size - buffer->pos, expr ); if (match_ptr) { buffer->pos += match_ptr - &buffer->data[buffer->pos]; match = true; diff --git a/ThirdParty/Ert/lib/util/cxx_string_util.cpp b/ThirdParty/Ert/lib/util/cxx_string_util.cpp index 5927039620..b49197b540 100644 --- a/ThirdParty/Ert/lib/util/cxx_string_util.cpp +++ b/ThirdParty/Ert/lib/util/cxx_string_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Equinor Statoil ASA, Norway. + Copyright (C) 2018 Equinor Equinor ASA, Norway. The file 'cxx_string_util.cpp' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/hash.cpp b/ThirdParty/Ert/lib/util/hash.cpp index a085abe6b9..214664a444 100644 --- a/ThirdParty/Ert/lib/util/hash.cpp +++ b/ThirdParty/Ert/lib/util/hash.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash.c' is part of ERT - Ensemble based Reservoir Tool. @@ -82,11 +82,6 @@ static void * __hash_get_node(const hash_type *__hash , const char *key, bool ab hash_type * hash = (hash_type *) __hash; /* The net effect is no change - but .... ?? */ hash_node_type * node = NULL; { - if (key == NULL) - { - return NULL; - } - const uint32_t global_index = hash->hashf(key , strlen(key)); const uint32_t table_index = (global_index % hash->size); diff --git a/ThirdParty/Ert/lib/util/hash_node.cpp b/ThirdParty/Ert/lib/util/hash_node.cpp index 1a983e0ba7..66e099879e 100644 --- a/ThirdParty/Ert/lib/util/hash_node.cpp +++ b/ThirdParty/Ert/lib/util/hash_node.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash_node.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/hash_sll.cpp b/ThirdParty/Ert/lib/util/hash_sll.cpp index 6f3ec0f623..080462cfaf 100644 --- a/ThirdParty/Ert/lib/util/hash_sll.cpp +++ b/ThirdParty/Ert/lib/util/hash_sll.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'hash_sll.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/lookup_table.cpp b/ThirdParty/Ert/lib/util/lookup_table.cpp index 616a54eac6..2f453a8d19 100644 --- a/ThirdParty/Ert/lib/util/lookup_table.cpp +++ b/ThirdParty/Ert/lib/util/lookup_table.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'lookup_table.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/mzran.cpp b/ThirdParty/Ert/lib/util/mzran.cpp index fd1bc353b5..a042988ff9 100644 --- a/ThirdParty/Ert/lib/util/mzran.cpp +++ b/ThirdParty/Ert/lib/util/mzran.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'mzran.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/node_ctype.cpp b/ThirdParty/Ert/lib/util/node_ctype.cpp index b50ce095fd..8db8504f1f 100644 --- a/ThirdParty/Ert/lib/util/node_ctype.cpp +++ b/ThirdParty/Ert/lib/util/node_ctype.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'node_ctype.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/node_data.cpp b/ThirdParty/Ert/lib/util/node_data.cpp index ae7d2a3653..728cbf8566 100644 --- a/ThirdParty/Ert/lib/util/node_data.cpp +++ b/ThirdParty/Ert/lib/util/node_data.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'node_data.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/parser.cpp b/ThirdParty/Ert/lib/util/parser.cpp index 48b963575e..8b187214d1 100644 --- a/ThirdParty/Ert/lib/util/parser.cpp +++ b/ThirdParty/Ert/lib/util/parser.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'parser.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/path.cpp b/ThirdParty/Ert/lib/util/path.cpp index 30d206e9e3..d0cb5418a8 100644 --- a/ThirdParty/Ert/lib/util/path.cpp +++ b/ThirdParty/Ert/lib/util/path.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool. @@ -15,6 +15,7 @@ See the GNU General Public License at for more details. */ +#include #include @@ -55,10 +56,16 @@ namespace ecl { { const char * c_str = fname.c_str(); + const char * return_raw; if (end_pos == std::string::npos || end_pos < offset) - return util_alloc_string_copy( &c_str[offset] ); + return_raw = util_alloc_string_copy( &c_str[offset] ); + else + return_raw = util_alloc_substring_copy(c_str, offset, end_pos - offset); + std::string return_value = return_raw; + free( (void*)return_raw ); + return return_value; + - return util_alloc_substring_copy(c_str, offset, end_pos - offset); } } @@ -71,7 +78,11 @@ namespace ecl { if (last_slash == std::string::npos || end_pos > last_slash) { const char * c_str = fname.c_str(); - return util_alloc_substring_copy( c_str, end_pos + 1, fname.size() - end_pos - 1); + + const char * return_raw = util_alloc_substring_copy( c_str, end_pos + 1, fname.size() - end_pos - 1); + std::string return_value = return_raw; + free( (void*)return_raw ); + return return_value; } return ""; diff --git a/ThirdParty/Ert/lib/util/path_stack.cpp b/ThirdParty/Ert/lib/util/path_stack.cpp index 9ae4ff9433..fd6f03565f 100644 --- a/ThirdParty/Ert/lib/util/path_stack.cpp +++ b/ThirdParty/Ert/lib/util/path_stack.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/perm_vector.cpp b/ThirdParty/Ert/lib/util/perm_vector.cpp index 459eced207..03e52ed6fc 100644 --- a/ThirdParty/Ert/lib/util/perm_vector.cpp +++ b/ThirdParty/Ert/lib/util/perm_vector.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'perm_vector.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/rng.cpp b/ThirdParty/Ert/lib/util/rng.cpp index f0daadcb2f..b5822d76ab 100644 --- a/ThirdParty/Ert/lib/util/rng.cpp +++ b/ThirdParty/Ert/lib/util/rng.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'rng.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/statistics.cpp b/ThirdParty/Ert/lib/util/statistics.cpp index 9aa170b849..7dfec8be3b 100644 --- a/ThirdParty/Ert/lib/util/statistics.cpp +++ b/ThirdParty/Ert/lib/util/statistics.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'statistics.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/string_util.cpp b/ThirdParty/Ert/lib/util/string_util.cpp index 37f258fea7..41f2b3f353 100644 --- a/ThirdParty/Ert/lib/util/string_util.cpp +++ b/ThirdParty/Ert/lib/util/string_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'string_util.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/stringlist.cpp b/ThirdParty/Ert/lib/util/stringlist.cpp index 237deabc03..879d1fa5d9 100644 --- a/ThirdParty/Ert/lib/util/stringlist.cpp +++ b/ThirdParty/Ert/lib/util/stringlist.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'stringlist.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/test_util.cpp b/ThirdParty/Ert/lib/util/test_util.cpp index 0e4349f7e0..e52612b558 100644 --- a/ThirdParty/Ert/lib/util/test_util.cpp +++ b/ThirdParty/Ert/lib/util/test_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'test_util.c' is part of ERT - Ensemble based Reservoir Tool. @@ -37,6 +37,7 @@ void test_error_exit( const char * fmt , ...) { s = util_alloc_sprintf_va(fmt , ap); va_end(ap); fprintf(stderr, "%s", s); + free(s); exit(1); } diff --git a/ThirdParty/Ert/lib/util/test_work_area.cpp b/ThirdParty/Ert/lib/util/test_work_area.cpp index 32a6267b4c..df7643ef2f 100644 --- a/ThirdParty/Ert/lib/util/test_work_area.cpp +++ b/ThirdParty/Ert/lib/util/test_work_area.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'test_work_area.c' is part of ERT - Ensemble based Reservoir Tool. @@ -25,19 +25,16 @@ #include #endif +#include + #include #include #include #include #include -#include -#include -#ifdef ERT_HAVE_OPENDIR -#include -#include -#endif +#include "detail/util/path.hpp" /* This file implements a small work area implementation to be used for @@ -96,82 +93,65 @@ #define TEST_WORK_AREA_TYPE_ID 1107355 -struct test_work_area_struct { - UTIL_TYPE_ID_DECLARATION; - bool store; - char * cwd; - char * original_cwd; - bool change_dir; +static char * test_work_area_alloc_prefix( ) { +#ifdef HAVE_WINDOWS_GET_TEMP_PATH - /* - There have been issues where a test like this: + char tmp_path[MAX_PATH]; + GetTempPath( MAX_PATH , tmp_path ); + return util_alloc_string_copy( tmp_path ); - 1. Create new file in test area. - 2. Open file for reading. - - Fail randomly at step 2 with "File not found", although the file - is clearly there when checking afterwards. Inspired by this - article: https:/lwn.net/Articles/457667/ we try to call fsync() on - the directory file descriptor. - */ -#ifdef ERT_HAVE_OPENDIR - DIR * dir_stream; -#endif - int dir_fd; -}; - - - - -static test_work_area_type * test_work_area_alloc__(const char * prefix , const char * test_path, bool change_dir) { - test_work_area_type * work_area = NULL; - - if (util_is_directory( prefix )) { - char * test_cwd = util_alloc_sprintf(FULL_PATH_FMT , prefix , test_path ); - util_make_path( test_cwd ); - if (true) { - work_area = (test_work_area_type*)util_malloc( sizeof * work_area ); - - UTIL_TYPE_ID_INIT( work_area , TEST_WORK_AREA_TYPE_ID ); - work_area->original_cwd = util_alloc_cwd(); - work_area->cwd = test_cwd; - work_area->change_dir = change_dir; - if (change_dir ) - if(util_chdir( work_area->cwd ) != 0) - util_abort("%s: Failed to move into temporary directory: %s", __func__, test_cwd); - - test_work_area_set_store( work_area , DEFAULT_STORE); - -#ifdef ERT_HAVE_OPENDIR - work_area->dir_stream = opendir( work_area->cwd ); - if (work_area->dir_stream) - work_area->dir_fd = dirfd( work_area->dir_stream ); - else - work_area->dir_fd = -1; #else - work_area->dir_fd = -1 + + const char * prefix_path = getenv("TMPDIR"); + +#ifdef P_tmpdir + if (!prefix_path) + prefix_path = P_tmpdir; #endif - } else - free( test_cwd ); + + if (!prefix_path) + prefix_path = _PATH_TMP; + + return util_alloc_realpath(prefix_path); + +#endif +} + + + +namespace ecl { +namespace util { + +static bool test_work_area_copy_parent__( const TestArea * work_area , const std::string& input_path, bool copy_content) { + char * full_path; + + if (util_is_abs_path( input_path.c_str() )) + full_path = util_alloc_string_copy( input_path.c_str() ); + else + full_path = util_alloc_filename( work_area->original_cwd().c_str( ) , input_path.c_str() , NULL); + + if (util_entry_exists( full_path)) { + char * parent_path = util_alloc_parent_path( full_path ); + + if (copy_content) + work_area->copy_directory_content(std::string(parent_path)); + else + work_area->copy_directory(std::string(parent_path)); + + free( full_path ); + free( parent_path ); + return true; + } else { + free( full_path ); + return false; } - return work_area; } -test_work_area_type * test_work_area_alloc_relative(const char * prefix , const char * test_path) { - return test_work_area_alloc__(prefix , test_path , true ); -} - - -test_work_area_type * temp_area_alloc_relative(const char * prefix , const char * test_path) { - return test_work_area_alloc__(prefix , test_path , false ); -} - - -UTIL_IS_INSTANCE_FUNCTION( test_work_area , TEST_WORK_AREA_TYPE_ID) - -static test_work_area_type * test_work_area_alloc_with_prefix(const char * prefix , const char * test_name, bool change_dir) { - if (test_name) { +TestArea::TestArea(const std::string& test_name, bool store_area) : + store(store_area) +{ + char * prefix = test_work_area_alloc_prefix(); unsigned int random_int; util_fread_dev_urandom( sizeof random_int, (char *) &random_int); random_int = random_int % 100000000; @@ -183,216 +163,177 @@ static test_work_area_type * test_work_area_alloc_with_prefix(const char * prefi #else char * user_name = util_alloc_sprintf("ert-test-%08u" , random_int); #endif - char * test_path = util_alloc_sprintf( TEST_PATH_FMT , user_name , test_name , random_int); - test_work_area_type * work_area = test_work_area_alloc__( prefix , test_path, change_dir); + + char * test_path = util_alloc_sprintf( TEST_PATH_FMT , user_name , test_name.c_str() , random_int); + char * test_cwd = util_alloc_sprintf(FULL_PATH_FMT , prefix , test_path ); + util_make_path( test_cwd ); + + { + char * cwd_tmp = util_alloc_cwd(); + this->org_cwd = cwd_tmp; + free(cwd_tmp); + } + this->cwd = test_cwd; + if (util_chdir( this->cwd.c_str() ) != 0) + util_abort("%s: Failed to move into temporary directory: %s", __func__, this->cwd.c_str()); + free( test_path ); free( user_name ); - return work_area; - } else + free( test_cwd ); + free( prefix ); +} + +TestArea::~TestArea() { + if (!this->store) + util_clear_directory( this->cwd.c_str() , true , true ); + + util_chdir( this->org_cwd.c_str() ); +} + +const std::string& TestArea::test_cwd() const { + return this->cwd; +} + +const std::string& TestArea::original_cwd() const { + return this->org_cwd; +} + +std::string TestArea::original_path(const std::string& input_path) const { + if (util_is_abs_path( input_path.c_str() )) + return std::string(input_path); + else { + char * fname = util_alloc_filename( this->original_cwd().c_str(), input_path.c_str() , NULL); + + std::string return_string = std::string(fname); + free(fname); + + return return_string; + } +} + + +void TestArea::copy_file(const std::string& input_src_file) const { + std::string src_file = this->original_path(input_src_file); + + if (util_file_exists( src_file.c_str() )) { + char * target_name = util_split_alloc_filename( input_src_file.c_str() ); + char * target_file = util_alloc_filename( this->test_cwd().c_str() , target_name , NULL ); + util_copy_file( src_file.c_str(), target_file ); + free( target_file ); + free( target_name ); + } +} + +void TestArea::copy_directory(const std::string input_directory) const { + std::string src_directory = this->original_path(input_directory); + util_copy_directory(src_directory.c_str() , this->test_cwd().c_str() ); +} + +void TestArea::copy_directory_content(const std::string input_directory) const { + std::string src_directory = this->original_path(input_directory); + util_copy_directory_content(src_directory.c_str() , this->test_cwd().c_str() ); +} + +bool TestArea::copy_parent(const std::string input_path) const { + return test_work_area_copy_parent__(this, input_path, false); +} + +bool TestArea::copy_parent_content(const std::string input_path) const { + return test_work_area_copy_parent__(this, input_path, true); +} + +} +} + +/*****************************************************************/ +/* C API */ + +test_work_area_type * test_work_area_alloc__(const char * test_name, bool store_area) { + if (test_name) + return new ecl::util::TestArea(test_name, store_area); + else return NULL; } -static char * test_work_area_alloc_prefix( ) { -#ifdef HAVE_WINDOWS_GET_TEMP_PATH - - char tmp_path[MAX_PATH]; - GetTempPath( MAX_PATH , tmp_path ); - return util_alloc_string_copy( tmp_path ); - -#else - - const char * prefix_path = getenv("TMPDIR"); - - #ifdef P_tmpdir - if (!prefix_path) - prefix_path = P_tmpdir; - #endif - - if (!prefix_path) - prefix_path = _PATH_TMP; - - return util_alloc_realpath(prefix_path); - -#endif -} - - test_work_area_type * test_work_area_alloc(const char * test_name) { - test_work_area_type * work_area; - { - char * tmp_prefix = test_work_area_alloc_prefix( ); - work_area = test_work_area_alloc_with_prefix( tmp_prefix , test_name , true); - free( tmp_prefix ); - } - return work_area; + return test_work_area_alloc__(test_name, false); } -test_work_area_type * temp_area_alloc(const char * path) { - test_work_area_type * work_area; - { - char * tmp_prefix = test_work_area_alloc_prefix( ); - work_area = test_work_area_alloc_with_prefix( tmp_prefix , path , false ); - free( tmp_prefix ); - } - return work_area; -} - - - -void test_work_area_set_store( test_work_area_type * work_area , bool store) { - work_area->store = store; -} - - -void test_work_area_sync( test_work_area_type * work_area) { -#ifdef ERT_HAVE_OPENDIR - if (work_area->dir_fd >= 0) - fsync( work_area->dir_fd ); -#endif -} void test_work_area_free(test_work_area_type * work_area) { - if (!work_area->store) - util_clear_directory( work_area->cwd , true , true ); - - if (work_area->change_dir) - util_chdir( work_area->original_cwd ); - -#ifdef ERT_HAVE_OPENDIR - if (work_area->dir_stream) - closedir( work_area->dir_stream ); -#endif - - free( work_area->original_cwd ); - free( work_area->cwd ); - free( work_area ); + delete work_area; } const char * test_work_area_get_cwd( const test_work_area_type * work_area ) { - return work_area->cwd; + return work_area->test_cwd().c_str(); } const char * test_work_area_get_original_cwd( const test_work_area_type * work_area ) { - return work_area->original_cwd; + return work_area->original_cwd().c_str(); } + char * test_work_area_alloc_input_path( const test_work_area_type * work_area , const char * input_path ) { - if (util_is_abs_path( input_path )) - return util_alloc_string_copy( input_path ); - else { - if (work_area->change_dir) - return util_alloc_filename( work_area->original_cwd , input_path , NULL); - else - return util_alloc_string_copy( input_path ); - } + std::string relocated_input_path = work_area->original_path(std::string(input_path)); + return util_alloc_string_copy(relocated_input_path.c_str()); } + + /** The point of this function is that the test code should be able to access the file @input_file independent of the fact that it has changed path. If @input_file is an absolute path the function will - do nothing, if @input_file is a realtive path the function will + do nothing, if @input_file is a relative path the function will copy @input_file from the location relative to the original cwd to the corresponding location relative to the test cwd. */ - -void test_work_area_install_file( test_work_area_type * work_area , const char * input_src_file ) { - if (util_is_abs_path( input_src_file )) +void test_work_area_install_file( const test_work_area_type * work_area , const char * input_src_file ) { + if (util_is_abs_path( input_src_file)) return; else { - char * src_file = test_work_area_alloc_input_path( work_area , input_src_file ); - char * src_path = NULL; + std::string src_file = work_area->original_path(input_src_file); + std::string src_path = ecl::util::path::dirname(input_src_file); - util_alloc_file_components( input_src_file , &src_path , NULL , NULL); - if (!util_entry_exists( src_path )) - util_make_path( src_path ); + if (!util_entry_exists( src_path.c_str() )) + util_make_path( src_path.c_str() ); - if (util_file_exists( src_file )) { - char * target_file = util_alloc_filename( work_area->cwd , input_src_file , NULL ); - util_copy_file( src_file , target_file ); + if (util_file_exists( src_file.c_str() )) { + char * target_file = util_alloc_filename( work_area->test_cwd().c_str(), input_src_file, NULL ); + util_copy_file( src_file.c_str() , target_file ); free( target_file ); } - free( src_file ); - free( src_path ); } } -void test_work_area_copy_directory( test_work_area_type * work_area , const char * input_directory) { - char * src_directory = test_work_area_alloc_input_path( work_area , input_directory ); - util_copy_directory(src_directory , work_area->cwd ); - free( src_directory ); - test_work_area_sync( work_area ); +void test_work_area_copy_file( const test_work_area_type * work_area , const char * input_file) { + if (input_file) + work_area->copy_file(std::string(input_file)); } -void test_work_area_copy_directory_content( test_work_area_type * work_area , const char * input_directory) { - char * src_directory = test_work_area_alloc_input_path( work_area , input_directory ); - util_copy_directory_content(src_directory , work_area->cwd ); - free( src_directory ); - test_work_area_sync( work_area ); +void test_work_area_copy_directory( const test_work_area_type * work_area , const char * input_directory) { + work_area->copy_directory(std::string(input_directory)); } - -void test_work_area_copy_file( test_work_area_type * work_area , const char * input_file) { - if (input_file) { - char * src_file = test_work_area_alloc_input_path( work_area , input_file ); - - if (util_file_exists( src_file )) { - char * target_name = util_split_alloc_filename( input_file ); - char * target_file = util_alloc_filename( work_area->cwd , target_name , NULL ); - util_copy_file( src_file , target_file ); - free( target_file ); - free( target_name ); - } - free( src_file ); - test_work_area_sync( work_area ); - } +void test_work_area_copy_directory_content( const test_work_area_type * work_area , const char * input_directory) { + work_area->copy_directory_content(std::string(input_directory)); } - -static bool test_work_area_copy_parent__( test_work_area_type * work_area , const char * input_path, bool copy_content) { - char * full_path; - - if (util_is_abs_path( input_path )) - full_path = util_alloc_string_copy( input_path ); - else - full_path = util_alloc_filename( work_area->original_cwd , input_path , NULL); - - if (util_entry_exists( full_path)) { - char * parent_path = NULL; - - parent_path = util_alloc_parent_path( full_path ); - - if (copy_content) - test_work_area_copy_directory_content( work_area , parent_path ); - else - test_work_area_copy_directory( work_area , parent_path ); - - free( full_path ); - free( parent_path ); - test_work_area_sync( work_area ); - return true; - } else { - free( full_path ); - return false; - } +bool test_work_area_copy_parent_directory( const test_work_area_type * work_area , const char * input_path) { + return work_area->copy_parent(std::string(input_path)); } -bool test_work_area_copy_parent_directory( test_work_area_type * work_area , const char * input_path) { - return test_work_area_copy_parent__( work_area , input_path , false ); -} - - -bool test_work_area_copy_parent_content( test_work_area_type * work_area , const char * input_path) { - return test_work_area_copy_parent__( work_area , input_path , true ); +bool test_work_area_copy_parent_content( const test_work_area_type * work_area , const char * input_path) { + return work_area->copy_parent_content(std::string(input_path)); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp index 06d76bfc28..07cb596216 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_addr2line.c' is part of ERT - Ensemble based Reservoir Tool. @@ -28,7 +28,6 @@ void test_lookup(bool valid_address, bool change_cwd) { const char * file = __FILE__; - const char * func = __func__; int line; const int max_bt = 50; void *bt_addr[max_bt]; @@ -45,7 +44,6 @@ void test_lookup(bool valid_address, bool change_cwd) { util_chdir("/tmp"); if (valid_address) { test_assert_false( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr)); - test_assert_string_equal( func_name , func ); test_assert_string_equal( file_name , NULL ); test_assert_int_equal( 0 , line_nr); } else { @@ -59,7 +57,6 @@ void test_lookup(bool valid_address, bool change_cwd) { } else { if (valid_address) { test_assert_true( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr)); - test_assert_string_equal( func_name , func ); test_assert_string_equal( file_name , file ); test_assert_int_equal( line , line_nr ); } else { @@ -90,6 +87,7 @@ int main( int argc , char ** argv) { util_chdir(path); dot_name = util_alloc_sprintf("./%s" , name); util_spawn_blocking(dot_name, 0, NULL, NULL, NULL); + free(dot_name); exit(0); } else { printf("Testing internal lookup ....\n"); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp index cfdf63fda2..c8a80b4d30 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp @@ -8,36 +8,33 @@ #include -bool checkPath(const char * path, const char * directory, const char * base_name, const char * extension) { +void checkPath(const char * path, const char * directory, const char * base_name, const char * extension) { char * dir; char * base; char * ext; util_alloc_file_components(path, &dir, &base, &ext); - bool success = true; - - success = success && (util_string_equal(dir, directory) || dir == directory); - success = success && (util_string_equal(base, base_name) || base == base_name); - success = success && (util_string_equal(ext, extension) || ext == extension); + test_assert_string_equal(dir, directory); + test_assert_string_equal(base, base_name); + test_assert_string_equal(ext, extension); free(dir); free(base); free(ext); - return success; } int main(int argc , char ** argv) { - test_assert_true(checkPath("/dir/filename.ext", "/dir", "filename", "ext")); - test_assert_true(checkPath("/dir/subdir/filename.ext", "/dir/subdir", "filename", "ext")); - test_assert_true(checkPath("/dir/subdir/filename.name.ext", "/dir/subdir", "filename.name", "ext")); - test_assert_true(checkPath("/dir/subdir/filename", "/dir/subdir", "filename", NULL)); - test_assert_true(checkPath("filename.ext", NULL, "filename", "ext")); - test_assert_true(checkPath("filename", NULL, "filename", NULL)); - test_assert_true(checkPath(".filename", NULL, ".filename", NULL)); - test_assert_true(checkPath(".filename.ext", NULL, ".filename", "ext")); - - exit(0); + checkPath("/dir/filename.ext", "/dir", "filename", "ext"); + checkPath("/dir/subdir/filename.ext", "/dir/subdir", "filename", "ext"); + checkPath("/dir/subdir/filename.name.ext", "/dir/subdir", "filename.name", "ext"); + checkPath("/dir/subdir/filename", "/dir/subdir", "filename", NULL); + checkPath("filename.ext", NULL, "filename", "ext"); + checkPath("filename", NULL, "filename", NULL); + checkPath(".filename", NULL, ".filename", NULL); + checkPath(".filename.ext", NULL, ".filename", "ext"); + checkPath("./SPECASE1", ".", "SPECASE1", NULL); + checkPath("/absolute/path/to/CASE", "/absolute/path/to", "CASE", NULL); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp index d9b9f45acf..19f2212795 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_approx_equal.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp index d5982d27bd..a3e9753f53 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_before_after.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp index 4c3ee41585..4a1e49ad2c 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_binary_split.c' is part of ERT - Ensemble based Reservoir Tool. @@ -25,18 +25,22 @@ void test_split(const char * test_string , bool split_on_first , const char * tr char * part1; char * part2; - util_binary_split_string( test_string , ":" , split_on_first , &part1 , &part2 ); test_assert_string_equal( true1 , part1 ); test_assert_string_equal( true2 , part2 ); + free(part1); + free(part2); util_binary_split_string( test_string , ":;" , split_on_first , &part1 , &part2 ); test_assert_string_equal( true1 , part1 ); test_assert_string_equal( true2 , part2 ); + free(part1); + free(part2); util_binary_split_string( test_string , ";" , split_on_first , &part1 , &part2 ); test_assert_string_equal( test_string , part1 ); test_assert_string_equal( NULL , part2 ); + free(part1); } int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp index a42768df2f..b510933274 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Statoil ASA, Norway. + Copyright (C) 2015 Equinor ASA, Norway. The file 'ert_util_buffer.c' is part of ERT - Ensemble based Reservoir Tool. @@ -68,6 +68,7 @@ void test_buffer_strstr() { test_assert_true( buffer_strstr( buffer , "ABC" )); test_assert_true( buffer_strstr( buffer , "BC" )); test_assert_false( buffer_strstr( buffer , "ABC" )); + buffer_free(buffer); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp index bd84459deb..f465ac7031 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ert_util_chdir.c' is part of ERT - Ensemble based Reservoir Tool. @@ -24,8 +24,8 @@ void test_chdir() { - test_work_area_type * work_area = test_work_area_alloc("test-area"); - const char * cwd = test_work_area_get_cwd( work_area ); + ecl::util::TestArea ta("chdir"); + const char * cwd = ta.test_cwd().c_str(); test_assert_false( util_chdir_file( "/file/does/not/exist")); test_assert_false( util_chdir_file( cwd )); @@ -34,8 +34,13 @@ void test_chdir() { fclose( stream ); } test_assert_true( util_chdir_file( "path/FILE" )); - test_assert_string_equal( util_alloc_cwd() , util_alloc_filename( cwd, "path", NULL)); - test_work_area_free( work_area ); + { + char * new_cwd = util_alloc_cwd(); + char * fname = util_alloc_filename(cwd, "path", NULL); + test_assert_string_equal( new_cwd, fname ); + free(new_cwd); + free(fname); + } } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp index e56640ada0..65932ab25c 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_clamp.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp index 6ccb4f99ed..1fd0012cff 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'enkf_util_copy_file.c' is part of ERT - Ensemble based Reservoir Tool. @@ -36,7 +36,7 @@ void test_copy_file( const char * executable ) { mode0 = stat_buf.st_mode; { - test_work_area_type * test_area = test_work_area_alloc( "executable-copy" ); + ecl::util::TestArea ta("copy_file"); util_copy_file( executable , "test.x"); test_assert_true( util_file_exists( "test.x" )); @@ -44,7 +44,6 @@ void test_copy_file( const char * executable ) { mode1 = stat_buf.st_mode; test_assert_true( mode0 == mode1 ); - test_work_area_free( test_area ); } } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp index 0b59b4fa69..e04523deb8 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_cwd_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -24,10 +24,11 @@ int main(int argc , char ** argv) { char * cwd = argv[1]; - printf("cwd :%s\n",util_alloc_cwd()); + char * cwd_alloc = util_alloc_cwd(); + printf("cwd :%s\n",cwd_alloc); printf("argv[1]:%s\n",argv[1]); - if (!util_is_cwd(cwd)) + if (!util_is_cwd(cwd_alloc)) test_error_exit("Hmmm did not recognize:%s as cwd\n",cwd); if (util_is_cwd("/some/path")) diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp index 2564784ee0..3673653497 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. This file is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp index 25e29b5a42..13bf0f5c1f 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_file_readable.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp index d42150605e..a88c8f5027 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_PATH_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp index d157750e23..c75b8ee219 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_hash_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp index 30a2ea8d39..a87a6b86f1 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. The file 'ert_util_mkdir_p.c' is part of ERT - Ensemble based Reservoir Tool. @@ -24,7 +24,7 @@ int main(int argc , char ** argv) { - test_work_area_type * work_area = test_work_area_alloc("Test_area"); + ecl::util::TestArea ta("mkdir"); // Regular use test_assert_true( util_mkdir_p("some/path/with/many/levels")); @@ -45,6 +45,5 @@ int main(int argc , char ** argv) { chmod("read_only", 0555); test_assert_false(util_mkdir_p("read_only/no/not/this")); - test_work_area_free(work_area); exit(0); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp index ff1f117020..8b46860ba6 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'ert_util_normal_path.c' is part of ERT - Ensemble based Reservoir Tool. @@ -32,7 +32,7 @@ void test_path(const char * input_path, const char * expected_path) { void test_relative() { - test_work_area_type * work_area = test_work_area_alloc("Work"); + ecl::util::TestArea ta("relative_path"); util_make_path("level0/level1/level2"); test_path( "level0/level1/../", "level0"); @@ -48,11 +48,10 @@ void test_relative() { util_chdir("level0/level1"); test_path("../../level0/level1/level2/../file.txt" , "file.txt"); test_path("../../level0/level1/level2/../" , ""); - test_work_area_free( work_area ); } void test_beyond_root() { - test_work_area_type * work_area = test_work_area_alloc("Work"); + ecl::util::TestArea("beyond_root"); char * cwd = util_alloc_cwd( ); char * backref_cwd1 = util_alloc_sprintf("../../../../../../../../../../../%s" , cwd ); char * backref_cwd2 = util_alloc_sprintf("/../../../../../../../../../../../%s" , cwd ); @@ -61,7 +60,6 @@ void test_beyond_root() { free( backref_cwd1 ); free( backref_cwd2 ); free( cwd ); - test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp index b5af351b93..7e3d5bdeef 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_parent_path.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp index ddc26dbaf0..89e0cd018a 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_path_stack_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp index 58f8e69ba3..a9291d3630 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_ping.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp index 7f8c6e814e..2862e07060 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_realpath.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp index e19b336e99..2de2b0ea13 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_relpath_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp index ed12cffa83..c309769072 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_rng.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp index 19d402f031..127c7847dd 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. The file 'ert_util_spawn.c' is part of ERT - Ensemble based Reservoir Tool. @@ -59,7 +59,7 @@ bool check_script(const char* script) { } void test_spawn_no_redirect() { - test_work_area_type * test_area = test_work_area_alloc("spawn1"); + ecl::util::TestArea ta("spawn1"); { int status; make_script("script" , stdout_msg , stderr_msg); @@ -77,7 +77,6 @@ void test_spawn_no_redirect() { test_assert_int_equal( status , 0 ); } } - test_work_area_free( test_area ); } @@ -136,7 +135,7 @@ void * test_spawn_redirect__( const char * path ) { void test_spawn_redirect() { - test_work_area_type * test_area = test_work_area_alloc("spawn1"); + ecl::util::TestArea ta("test_redirect"); { make_script("script" , stdout_msg , stderr_msg); util_addmode_if_owner( "script" , S_IRUSR + S_IWUSR + S_IXUSR + S_IRGRP + S_IWGRP + S_IXGRP + S_IROTH + S_IXOTH); /* u:rwx g:rwx o:rx */ @@ -144,14 +143,13 @@ void test_spawn_redirect() { test_spawn_redirect__( NULL ); } - test_work_area_free( test_area ); } void test_spawn_redirect_threaded() { const int num = 128; // Generate the scripts on disk first - test_work_area_type * test_area = test_work_area_alloc("spawn1_threaded"); + ecl::util::TestArea("spawn1_threaded"); int * path_codes = (int *)util_calloc(num, sizeof *path_codes); stringlist_type * script_fullpaths = stringlist_alloc_new(); for (int i=0; i < num; i++) { @@ -180,7 +178,6 @@ void test_spawn_redirect_threaded() { stringlist_free(script_fullpaths); free(path_codes); - test_work_area_free( test_area ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp index 4fce2b4e81..c759c624f7 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2018 Equinor ASA, Norway. The file 'ert_util_split_path.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp index 60f4d180e1..f2d885b816 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. + Copyright (C) 2014 Equinor ASA, Norway. The file 'ert_util_sscan_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp index ea859328f1..2ecfe9aef9 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_statistics.c' is part of ERT - Ensemble based Reservoir Tool. @@ -32,6 +32,8 @@ void test_mean_std() { test_assert_double_equal( statistics_mean( d ) , 0.50 ); test_assert_double_equal( statistics_std( d ) , 0.50 ); + + double_vector_free( d ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp index a7042a38eb..27742cc4ff 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_strcat_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -28,8 +28,11 @@ void test_strcat(char * s1 , const char *s2 , const char * expected) { char * cat = util_strcat_realloc(s1 , s2 ); if (test_check_string_equal( cat , expected )) free( cat ); - else - test_error_exit("util_strcat_realloc(%s,%s) Got:%s expected:%s \n",s1,s2,cat , expected); + else { + fprintf(stderr, "util_strcat_realloc(%s,%s) Got:%s expected:%s \n",s1,s2,cat , expected); + free(cat); + exit(1); + } } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp index 65389d7176..872578336c 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_string_util.c' is part of ERT - Ensemble based Reservoir Tool. @@ -60,6 +60,7 @@ void test_active_list() { test_assert_true( string_util_update_active_list("4-6" , active_list) ); test_int_vector( active_list , 13 , 0,1,3,4,5,6,7,8,9,10,14,15,16); + int_vector_free(active_list); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp index 1ad4c890a7..f01c422819 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_stringlist_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -36,15 +36,25 @@ void test_char() { { char ** copy = stringlist_alloc_char_copy( s ); int i; + bool equal = true; for (i=0; i < stringlist_get_size( s ); i++) { if (strcmp( stringlist_iget( s , i ) , copy[i]) != 0) - exit(1); - + equal = false; + free(copy[i]); } + free(copy); + if (!equal) + test_assert_false("Bug in test_char() function\n"); } + stringlist_free(s); } +void test_alloc_join(const stringlist_type * s, const char * sep, const char * expected) { + char * j = stringlist_alloc_joined_string(s, sep); + test_assert_string_equal(j, expected); + free(j); +} void test_join() { const char * elt0 = "AAA"; @@ -55,13 +65,8 @@ void test_join() { const char * elt5 = "FFF"; stringlist_type * s = stringlist_alloc_new(); + test_alloc_join(s, "!!!", ""); - { - // empty join - const char* empty_join = stringlist_alloc_joined_string(s, "!!!"); - test_assert_not_NULL(empty_join); - test_assert_string_equal("", empty_join); - } stringlist_append_copy( s , elt0 ); stringlist_append_copy( s , elt1 ); @@ -71,28 +76,37 @@ void test_join() { const char * sep1 = "!!!"; const char * sep2 = " abc "; - const char * j0 = stringlist_alloc_joined_string( s, sep0); - const char * j1 = stringlist_alloc_joined_string( s, sep1); - const char * j2 = stringlist_alloc_joined_string( s, sep2); + test_alloc_join(s, sep0, "AAABBBCCC"); + test_alloc_join(s, sep1, "AAA!!!BBB!!!CCC"); + test_alloc_join(s, sep2, "AAA abc BBB abc CCC"); - test_assert_string_equal( j0, "AAABBBCCC"); - test_assert_string_equal( j1, "AAA!!!BBB!!!CCC"); - test_assert_string_equal( j2, "AAA abc BBB abc CCC"); + { + stringlist_type * s1 = stringlist_alloc_new(); - stringlist_type * s1 = stringlist_alloc_new(); - stringlist_append_copy( s1 , elt0 ); - test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep0)); - test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep1)); - test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep2)); + stringlist_append_copy( s1 , elt0 ); + test_alloc_join(s1, sep0, "AAA"); + test_alloc_join(s1, sep1, "AAA"); + test_alloc_join(s1, sep2, "AAA"); - stringlist_type * sub = stringlist_alloc_new(); - stringlist_append_copy( sub , elt0 ); - stringlist_append_copy( sub , elt1 ); - stringlist_append_copy( sub , elt2 ); - stringlist_append_copy( sub , elt3 ); - stringlist_append_copy( sub , elt4 ); - stringlist_append_copy( sub , elt5 ); - test_assert_string_equal( "CCC:DDD:EEE", stringlist_alloc_joined_substring( sub, 2, 5, ":")); + stringlist_free(s1); + } + { + stringlist_type * sub = stringlist_alloc_new(); + stringlist_append_copy( sub , elt0 ); + stringlist_append_copy( sub , elt1 ); + stringlist_append_copy( sub , elt2 ); + stringlist_append_copy( sub , elt3 ); + stringlist_append_copy( sub , elt4 ); + stringlist_append_copy( sub , elt5 ); + { + char * j = stringlist_alloc_joined_substring( sub, 2, 5, ":"); + test_assert_string_equal( "CCC:DDD:EEE", j); + free(j); + } + + stringlist_free(sub); + } + stringlist_free(s); } @@ -112,6 +126,8 @@ void test_reverse() { test_assert_string_equal( s2 , stringlist_iget(s , 0 )); test_assert_string_equal( s1 , stringlist_iget(s , 1 )); test_assert_string_equal( s0 , stringlist_iget(s , 2 )); + + stringlist_free(s); } @@ -136,6 +152,7 @@ void test_iget_as_int() { value = stringlist_iget_as_int( s , 2 , NULL); test_assert_int_equal( value , -1); } + stringlist_free(s); } @@ -161,6 +178,7 @@ void test_iget_as_double() { test_assert_double_equal( value , -1); test_assert_false( valid ); } + stringlist_free(s); } @@ -235,12 +253,14 @@ void test_iget_as_bool() { test_assert_false( value ); test_assert_false( valid ); } + stringlist_free(s); } void test_empty() { stringlist_type * s = stringlist_alloc_new(); stringlist_fprintf( s , "\n" , stdout ); + stringlist_free(s); } void test_front_back() { @@ -347,7 +367,7 @@ bool not_FILE_predicate(const char * name, const void * arg) { void test_predicate_matching() { - test_work_area_type * work_area = test_work_area_alloc("predicate_test"); + ecl::util::TestArea ta("stringlist"); stringlist_type * s = stringlist_alloc_new(); stringlist_append_copy(s, "s"); stringlist_select_files(s, "does/not/exist", NULL, NULL); @@ -358,7 +378,7 @@ void test_predicate_matching() { FILE * f = util_fopen("FILE.txt", "w"); fclose(f); } - stringlist_select_files(s , test_work_area_get_cwd(work_area), NULL, NULL); + stringlist_select_files(s , ta.test_cwd().c_str(), NULL, NULL); test_assert_int_equal(1, stringlist_get_size(s)); { char * exp = util_alloc_abs_path("FILE.txt"); @@ -370,7 +390,7 @@ void test_predicate_matching() { test_assert_int_equal(1, stringlist_get_size(s)); test_assert_string_equal( "FILE.txt", stringlist_iget(s, 0)); - stringlist_select_files(s , test_work_area_get_cwd(work_area), FILE_predicate, NULL); + stringlist_select_files(s , ta.test_cwd().c_str(), FILE_predicate, NULL); test_assert_int_equal(1, stringlist_get_size(s)); { char * exp = util_alloc_abs_path("FILE.txt"); @@ -378,11 +398,10 @@ void test_predicate_matching() { free(exp); } - stringlist_select_files(s , test_work_area_get_cwd(work_area), not_FILE_predicate, NULL); + stringlist_select_files(s , ta.test_cwd().c_str(), not_FILE_predicate, NULL); test_assert_int_equal(0, stringlist_get_size(s)); stringlist_free(s); - test_work_area_free(work_area); } @@ -399,6 +418,7 @@ void test_unique() { stringlist_append_copy( s, "S2"); test_assert_false( stringlist_unique( s )); + stringlist_free(s); } int main( int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp index 567323c8eb..04b6e84ad0 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_str_str_int_format.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp index 802e8e69cf..7376df2d50 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_type_vector_functions.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp index 1a447db084..5ef217d461 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_type_vector_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -94,10 +94,12 @@ void test_contains() { int_vector_type * int_vector = int_vector_alloc( 0 , 100); test_assert_false( int_vector_contains( int_vector , 100 )); + int_vector_resize( int_vector, 1, 100 ); int_vector_iset( int_vector , 0 , 77 ); test_assert_false( int_vector_contains( int_vector , 100 )); test_assert_true( int_vector_contains( int_vector , 77 )); + int_vector_resize( int_vector, 11, 100 ); int_vector_iset( int_vector , 10 , 33 ); test_assert_true( int_vector_contains( int_vector , 100 )); test_assert_true( int_vector_contains( int_vector , 77 )); @@ -120,12 +122,15 @@ void test_contains_sorted() { test_assert_false( int_vector_contains( int_vector , 100 )); test_assert_true( int_vector_contains( int_vector , 89 )); test_assert_true( int_vector_contains( int_vector , 109 )); + + int_vector_free(int_vector); } void test_div() { int_vector_type * int_vector = int_vector_alloc( 0 , 100); + int_vector_resize( int_vector, 11, 100 ); int_vector_iset( int_vector , 10 , 100 ); int_vector_div( int_vector , 10 ); { @@ -133,6 +138,7 @@ void test_div() { for (i=0; i < int_vector_size( int_vector ); i++) test_assert_int_equal( 10 , int_vector_iget( int_vector , i )); } + int_vector_free(int_vector); } void test_memcpy_from_data() { @@ -239,6 +245,8 @@ void test_idel_insert() { void test_iset_block() { int_vector_type * vec = int_vector_alloc(0,0); + int_vector_resize( vec, 10, 0 ); + int_vector_resize( vec, 20, 77 ); int_vector_iset_block( vec , 10 , 10 , 77 ); test_assert_int_equal( int_vector_size( vec ) , 20 ); { @@ -263,8 +271,8 @@ void test_resize() { int i; int def = 77; int_vector_type * vec = int_vector_alloc(0,def); - int_vector_resize( vec , 10 ); - test_assert_int_equal( int_vector_size( vec ) , 10 ); + int_vector_resize( vec , 10 , def); + test_assert_int_equal( int_vector_size( vec ) , 10 ); for (i=0; i < 10; i++) test_assert_int_equal( int_vector_iget( vec , i ) , def ); @@ -272,12 +280,12 @@ void test_resize() { for (i=5; i < 10; i++) test_assert_int_equal( int_vector_iget( vec , i ) , 5 ); - int_vector_resize( vec , 5 ); + int_vector_resize( vec , 5 , def); test_assert_int_equal( int_vector_size( vec ) , 5 ); for (i=0; i < 5; i++) test_assert_int_equal( int_vector_iget( vec , i ) , def ); - int_vector_resize( vec , 10 ); + int_vector_resize( vec , 10, def ); test_assert_int_equal( int_vector_size( vec ) , 10 ); for (i=0; i < 10; i++) test_assert_int_equal( int_vector_iget( vec , i ) , def ); @@ -345,9 +353,9 @@ void test_empty() { void test_equal_index() { - int_vector_type * v1 = int_vector_alloc(0,0); - int_vector_type * v2 = int_vector_alloc(0,0); - int_vector_type * v3 = int_vector_alloc(0,0); + int_vector_type * v1 = int_vector_alloc(5,0); + int_vector_type * v2 = int_vector_alloc(5,0); + int_vector_type * v3 = int_vector_alloc(5,0); for (int i=0; i < 5; i++) { int_vector_iset(v1,i,i); @@ -373,10 +381,18 @@ void test_equal_index() { int_vector_free(v3); } +void test_misc() { + int_vector_type * v = int_vector_alloc(5, 123); + test_assert_int_equal( int_vector_iget(v, 2), 123 ); + int_vector_resize(v, 20, 0); + test_assert_int_equal( int_vector_iget(v, 4), 123); + test_assert_int_equal( int_vector_iget(v, 9), 0 ); + test_assert_int_equal( int_vector_iget(v, 19), 0); + int_vector_free(v); +} -int main(int argc , char ** argv) { - +void misc_int_vector_test() { int_vector_type * int_vector = int_vector_alloc( 0 , 99); test_abort(); @@ -385,8 +401,10 @@ int main(int argc , char ** argv) { test_assert_true( int_vector_is_instance( int_vector )); test_assert_false( double_vector_is_instance( int_vector )); + int_vector_resize( int_vector, 3, 99 ); int_vector_iset( int_vector , 2 , 0); int_vector_insert( int_vector , 2 , 77 ); + int_vector_resize( int_vector, 6, 99 ); int_vector_iset( int_vector , 5 , -10); assert_equal( int_vector_iget(int_vector , 0 ) == 99 ); @@ -428,6 +446,12 @@ int main(int argc , char ** argv) { test_assert_int_equal( int_vector_iget( int_vector , 3 ) , -245); test_assert_int_equal( int_vector_get_last( int_vector ) , -935); + int_vector_free(int_vector); +} + +int main(int argc , char ** argv) { + test_misc(); + misc_int_vector_test(); { int_vector_type * v1 = int_vector_alloc(0,0); int_vector_type * v2 = int_vector_alloc(0,0); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp index a2873abd6c..4d755633e7 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. + Copyright (C) 2016 Equinor ASA, Norway. This is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp index ade1cb5f99..8a44cd2168 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_vector_test.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp index 29e344729a..2c462290a6 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'ert_util_PATH_test.c' is part of ERT - Ensemble based Reservoir Tool. @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -48,10 +49,9 @@ void test_get_original_cwd() { void create_test_area(const char * test_name , bool store) { char * pre_cwd = util_alloc_cwd(); - test_work_area_type * work_area = test_work_area_alloc( test_name ); + test_work_area_type * work_area = test_work_area_alloc__( test_name, store ); char * work_path = util_alloc_string_copy( test_work_area_get_cwd( work_area )); - test_work_area_set_store( work_area , store ); test_assert_true( util_is_directory( work_path )); test_work_area_free( work_area ); test_assert_bool_equal( store , util_entry_exists( work_path )); @@ -158,31 +158,14 @@ void test_copy_parent_content( const char * path ) { } -void test_with_prefix() { - test_work_area_type * work_area = test_work_area_alloc( "with-prefix" ); - - util_make_path( "PREFIX" ); - { - test_work_area_type * sub_area = test_work_area_alloc_relative("PREFIX" , "sub-work" ); - test_assert_true( test_work_area_is_instance( sub_area )); - test_work_area_free( sub_area ); - test_assert_true( util_entry_exists("PREFIX/sub-work")); - } - { - test_work_area_type * sub_area = test_work_area_alloc_relative("DoesNotExist" , "sub-work" ); - test_assert_NULL( sub_area ); - } - test_work_area_free( work_area ); -} - void test_update_store() { { - test_work_area_type * work_area = test_work_area_alloc( "update-store1" ); + test_work_area_type * work_area = test_work_area_alloc__( "update-store1" , true); char * work_cwd = util_alloc_string_copy( test_work_area_get_cwd( work_area )); - test_work_area_set_store( work_area , true ); test_work_area_free( work_area ); test_assert_true( util_entry_exists( work_cwd )); + free(work_cwd); } { @@ -190,22 +173,23 @@ void test_update_store() { char * work_cwd = util_alloc_string_copy( test_work_area_get_cwd( work_area )); test_work_area_free( work_area ); test_assert_false( util_entry_exists( work_cwd )); + free(work_cwd); } { - test_work_area_type * work_area = test_work_area_alloc( "update-store3" ); + test_work_area_type * work_area = test_work_area_alloc__( "update-store3" , false); char * work_cwd = util_alloc_string_copy( test_work_area_get_cwd( work_area )); - test_work_area_set_store( work_area , false ); test_work_area_free( work_area ); test_assert_false( util_entry_exists( work_cwd )); + free(work_cwd); } { - test_work_area_type * work_area = test_work_area_alloc( "update-store4" ); + test_work_area_type * work_area = test_work_area_alloc__( "update-store4" , true); char * work_cwd = util_alloc_string_copy( test_work_area_get_cwd( work_area )); - test_work_area_set_store( work_area , true); test_work_area_free( work_area ); test_assert_true( util_entry_exists( work_cwd )); + free(work_cwd); } } @@ -215,10 +199,12 @@ int main(int argc , char ** argv) { const char * abs_path_file = argv[2]; const char * rel_directory = argv[3]; - create_test_area("STORE-TEST" , true ); - create_test_area("DEL-TEST" , false); + create_test_area("STORE-TEST", true ); + create_test_area("DEL-TEST", false); + test_install_file_exists( rel_path_file ); test_install_file_exists( abs_path_file ); + test_copy_directory( rel_directory ); test_input(); test_get_cwd(); @@ -233,8 +219,6 @@ int main(int argc , char ** argv) { test_copy_parent_content( rel_path_file ); test_copy_parent_content( abs_path_file ); - test_with_prefix(); test_update_store(); - exit(0); } diff --git a/ThirdParty/Ert/lib/util/tests/test_area.cpp b/ThirdParty/Ert/lib/util/tests/test_area.cpp new file mode 100644 index 0000000000..9f580ae18f --- /dev/null +++ b/ThirdParty/Ert/lib/util/tests/test_area.cpp @@ -0,0 +1,34 @@ +/* + Copyright (C) 2019 Equinor ASA, Norway. + + The file 'test_area.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 + for more details. +*/ +#include + +#include +#include + +void test_create() { + ecl::util::TestArea ta("Name"); + + test_assert_true( ta.test_cwd() != ta.original_cwd() ); + +} + + + +int main(int argc, char **argv) { + test_create(); +} diff --git a/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp b/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp index 1700de5a3b..f2679ae6d8 100644 --- a/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp +++ b/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Statoil ASA, Norway. + Copyright (C) 2015 Equinor ASA, Norway. The file 'test_thread_pool.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/timer.cpp b/ThirdParty/Ert/lib/util/timer.cpp index c333a20663..7c87a9c8c3 100644 --- a/ThirdParty/Ert/lib/util/timer.cpp +++ b/ThirdParty/Ert/lib/util/timer.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'timer.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/type_vector_functions.cpp b/ThirdParty/Ert/lib/util/type_vector_functions.cpp index 2dec9f3f1e..9daf66111e 100644 --- a/ThirdParty/Ert/lib/util/type_vector_functions.cpp +++ b/ThirdParty/Ert/lib/util/type_vector_functions.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'ert_util_vector_function.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/util.c b/ThirdParty/Ert/lib/util/util.c index 9ae01521b7..84048565e2 100644 --- a/ThirdParty/Ert/lib/util/util.c +++ b/ThirdParty/Ert/lib/util/util.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'util.c' is part of ERT - Ensemble based Reservoir Tool. @@ -996,7 +996,9 @@ char * util_alloc_normal_path( const char * input_path ) { return util_alloc_realpath__( input_path ); char * realpath = util_alloc_realpath__(input_path); - return util_alloc_rel_path( NULL , realpath ); + char * rel_path = util_alloc_rel_path( NULL , realpath ); + free( realpath ); + return rel_path; } @@ -2153,8 +2155,6 @@ int util_fmove( FILE * stream , long offset , long shift) { #ifdef HAVE_WINDOWS__ACCESS bool util_access(const char * entry, int mode) { - if (!entry) return false; - return (_access(entry, mode) == 0); } @@ -2162,8 +2162,6 @@ bool util_access(const char * entry, int mode) { #ifdef HAVE_POSIX_ACCESS bool util_access(const char * entry, mode_t mode) { - if (!entry) return false; - return (access(entry, mode) == 0); } #endif @@ -2890,13 +2888,6 @@ bool util_fscanf_date_utc(FILE *stream , time_t *t) { */ -void util_fprintf_date_utc(time_t t , FILE * stream) { - int mday,year,month; - - util_set_datetime_values_utc(t , NULL , NULL , NULL , &mday , &month , &year); - fprintf(stream , "%02d/%02d/%4d", mday,month,year); -} - char * util_alloc_date_string_utc( time_t t ) { int mday,year,month; @@ -3070,22 +3061,6 @@ time_t util_make_pure_date_utc(time_t t) { /*****************************************************************/ -void util_set_strip_copy(char * copy , const char *src) { - const char null_char = '\0'; - const char space_char = ' '; - int src_index = 0; - int target_index = 0; - while (src[src_index] == space_char) - src_index++; - - while (src[src_index] != null_char && src[src_index] != space_char) { - copy[target_index] = src[src_index]; - src_index++; - target_index++; - } - copy[target_index] = null_char; -} - /** The function will allocate a new copy of src where leading and @@ -4334,53 +4309,6 @@ void * util_realloc_copy(void * org_ptr , const void * src , size_t byte_size ) /*****************************************************************/ -/** - These small functions write formatted values onto a stream. The - main point about these functions is to avoid creating small one-off - format strings. The character base_fmt should be 'f' or 'g' -*/ - -void util_fprintf_double(double value , int width , int decimals , char base_fmt , FILE * stream) { - char * fmt = util_alloc_sprintf("%c%d.%d%c" , '%' , width , decimals , base_fmt); - fprintf(stream , fmt , value); - free(fmt); -} - - -void util_fprintf_int(int value , int width , FILE * stream) { - char fmt[32]; - sprintf(fmt , "%%%dd" , width); - fprintf(stream , fmt , value); -} - - - -void util_fprintf_string(const char * s , int width_ , string_alignement_type alignement , FILE * stream) { - char fmt[32]; - size_t i; - size_t width = width_; - if (alignement == left_pad) { - i = 0; - if (width > strlen(s)) { - for (i=0; i < (width - strlen(s)); i++) - fputc(' ' , stream); - } - fprintf(stream , "%s", s); - } else if (alignement == right_pad) { - sprintf(fmt , "%%-%lus" , width); - fprintf(stream , fmt , s); - } else { - int total_pad = width - strlen(s); - int front_pad = total_pad / 2; - int back_pad = total_pad - front_pad; - int i; - util_fprintf_string(s , front_pad + strlen(s) , left_pad , stream); - for (i=0; i < back_pad; i++) - fputc(' ' , stream); - } -} - - diff --git a/ThirdParty/Ert/lib/util/util_endian.cpp b/ThirdParty/Ert/lib/util/util_endian.cpp index 0613f0e639..a8a03f7af8 100644 --- a/ThirdParty/Ert/lib/util/util_endian.cpp +++ b/ThirdParty/Ert/lib/util/util_endian.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. + Copyright (C) 2012 Equinor ASA, Norway. The file 'util_endian.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/util_lfs.c b/ThirdParty/Ert/lib/util/util_lfs.c index d6d9c1f735..422e87fd63 100644 --- a/ThirdParty/Ert/lib/util/util_lfs.c +++ b/ThirdParty/Ert/lib/util/util_lfs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. + Copyright (C) 2013 Equinor ASA, Norway. The file 'util_lfs.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/util_unlink.cpp b/ThirdParty/Ert/lib/util/util_unlink.cpp index be7d633665..74200f572d 100644 --- a/ThirdParty/Ert/lib/util/util_unlink.cpp +++ b/ThirdParty/Ert/lib/util/util_unlink.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. + Copyright (C) 2017 Equinor ASA, Norway. The file 'util_unlink.c' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/lib/util/vector.cpp b/ThirdParty/Ert/lib/util/vector.cpp index 27da7ff790..9c8fdd6d76 100644 --- a/ThirdParty/Ert/lib/util/vector.cpp +++ b/ThirdParty/Ert/lib/util/vector.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vector.c' is part of ERT - Ensemble based Reservoir Tool. @@ -589,6 +589,7 @@ int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp vector_sort_node_type * sort_data = vector_alloc_sort_data( vector , cmp ); int_vector_type * sort_perm = int_vector_alloc(0,0); int i; + int_vector_resize( sort_perm, vector->size, 0 ); for (i = 0; i < vector->size; i++) int_vector_iset( sort_perm , i , sort_data[i].index); diff --git a/ThirdParty/Ert/lib/util/vector_template.cpp b/ThirdParty/Ert/lib/util/vector_template.cpp index de5ee77a28..d9811f01ce 100644 --- a/ThirdParty/Ert/lib/util/vector_template.cpp +++ b/ThirdParty/Ert/lib/util/vector_template.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vector_template.c' is part of ERT - Ensemble based Reservoir Tool. @@ -47,29 +47,29 @@ ------------------------------------ - ·-----·-----· + �-----�-----� 1. | 77 | 77 | size = 0, alloc_size = 2 - ·-----·-----· + �-----�-----� - ·-----·-----· + �-----�-----� 2. | 1 | 77 | size = 1, alloc_size = 2 - ·-----·-----· + �-----�-----� - ·-----·-----· + �-----�-----� 3. | 1 | 0 | size = 2, alloc_size = 2 - ·-----·-----· + �-----�-----� - ·-----·-----·-----·-----· + �-----�-----�-----�-----� 4. | 1 | 0 | 12 | 77 | size = 3, alloc_size = 4 - ·-----·-----·-----·-----· + �-----�-----�-----�-----� - ·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----· + �-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----� 5. | 1 | 0 | 12 | 77 | 77 | 77 | 78 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | size = 7, alloc_size = 12, default = 77 - ·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----· + �-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----� - ·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----· + �-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----� 6. | 1 | 0 | 12 | 77 | 77 | 77 | 78 | 99 | 99 | 99 | 99 | 99 | 99 | 99 | 99 | 99 | size = 7, alloc_size = 12, default = 99 - ·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----·-----· + �-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----�-----� 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @@ -137,14 +137,14 @@ UTIL_SAFE_CAST_FUNCTION(@TYPE@_vector , TYPE_VECTOR_ID); UTIL_IS_INSTANCE_FUNCTION(@TYPE@_vector , TYPE_VECTOR_ID); -static void @TYPE@_vector_realloc_data__(@TYPE@_vector_type * vector , int new_alloc_size) { +static void @TYPE@_vector_realloc_data__(@TYPE@_vector_type * vector , int new_alloc_size, @TYPE@ default_value) { if (new_alloc_size != vector->alloc_size) { if (vector->data_owner) { if (new_alloc_size > 0) { int i; vector->data = (@TYPE@*)util_realloc(vector->data , new_alloc_size * sizeof * vector->data ); for (i=vector->alloc_size; i < new_alloc_size; i++) - vector->data[i] = vector->default_value; + vector->data[i] = default_value; } else { if (vector->alloc_size > 0) { free(vector->data); @@ -163,7 +163,7 @@ static void @TYPE@_vector_memmove(@TYPE@_vector_type * vector , int offset , int util_abort("%s: offset:%d left_shift:%d - invalid \n",__func__ , offset , -shift); if ((shift + vector->size > vector->alloc_size)) - @TYPE@_vector_realloc_data__( vector , util_int_min( 2*vector->alloc_size , shift + vector->size )); + @TYPE@_vector_realloc_data__( vector , util_int_min( 2*vector->alloc_size , shift + vector->size ), vector->default_value); { size_t move_size = (vector->size - offset) * sizeof(@TYPE@); @@ -230,7 +230,7 @@ static @TYPE@_vector_type * @TYPE@_vector_alloc__(int init_size , @TYPE@ default @TYPE@_vector_set_read_only( vector , false ); if (init_size > 0) - @TYPE@_vector_iset( vector , init_size - 1 , default_value ); /* Filling up the init size elements with the default value */ + @TYPE@_vector_resize( vector , init_size , default_value ); /* Filling up the init size elements with the default value */ return vector; } @@ -253,11 +253,18 @@ static @TYPE@_vector_type * @TYPE@_vector_alloc__(int init_size , @TYPE@ default new_size > current_size: The vector will grow by adding default elements at the end. */ -void @TYPE@_vector_resize( @TYPE@_vector_type * vector , int new_size ) { - if (new_size <= vector->size) - vector->size = new_size; - else - @TYPE@_vector_iset( vector , new_size - 1 , vector->default_value); +void @TYPE@_vector_resize( @TYPE@_vector_type * vector , int new_size, @TYPE@ default_value ) { + if (new_size > vector->size) { + if (new_size > vector->alloc_size) { + for (int i = vector->size; i < vector->alloc_size; i++) + vector->data[i] = default_value; + @TYPE@_vector_realloc_data__( vector, 2 * new_size, default_value); + } + else + for (int i = vector->size; i < new_size; i++) + vector->data[i] = default_value; + } + vector->size = new_size; } @@ -341,7 +348,8 @@ void @TYPE@_vector_memcpy_data_block( @TYPE@_vector_type * target , const @TYPE@ void @TYPE@_vector_memcpy_from_data( @TYPE@_vector_type * target , const @TYPE@ * src , int src_size ) { @TYPE@_vector_reset( target ); - @TYPE@_vector_iset( target , src_size - 1 , 0 ); + //@TYPE@_vector_iset( target , src_size - 1 , 0 ); + @TYPE@_vector_resize( target, src_size, 0); memcpy( target->data , src , src_size * sizeof * target->data ); } @@ -397,7 +405,7 @@ void @TYPE@_vector_memcpy( @TYPE@_vector_type * target, const @TYPE@_vector_type @TYPE@_vector_type * @TYPE@_vector_alloc_copy( const @TYPE@_vector_type * src) { @TYPE@_vector_type * copy = @TYPE@_vector_alloc( src->size , src->default_value ); - @TYPE@_vector_realloc_data__( copy , src->alloc_size ); + @TYPE@_vector_realloc_data__( copy , src->alloc_size, src->default_value ); copy->size = src->size; memcpy(copy->data , src->data , src->alloc_size * sizeof * src->data ); return copy; @@ -616,7 +624,7 @@ void @TYPE@_vector_iset(@TYPE@_vector_type * vector , int index , @TYPE@ value) util_abort("%s: Sorry - can NOT set negative indices. called with index:%d \n",__func__ , index); { if (vector->alloc_size <= index) - @TYPE@_vector_realloc_data__(vector , 2 * (index + 1)); /* Must have ( + 1) here to ensure we are not doing 2*0 */ + @TYPE@_vector_realloc_data__(vector , 2 * (index + 1), vector->default_value); /* Must have ( + 1) here to ensure we are not doing 2*0 */ vector->data[index] = value; if (index >= vector->size) { int i; @@ -729,7 +737,10 @@ void @TYPE@_vector_insert( @TYPE@_vector_type * vector , int index , @TYPE@ valu void @TYPE@_vector_append(@TYPE@_vector_type * vector , @TYPE@ value) { - @TYPE@_vector_iset(vector , vector->size , value); + //@TYPE@_vector_iset(vector , vector->size , value); + int size = vector->size; + @TYPE@_vector_resize(vector, size+1, 0); + vector->data[size] = value; } @@ -746,7 +757,7 @@ void @TYPE@_vector_free_container(@TYPE@_vector_type * vector) { void @TYPE@_vector_free_data(@TYPE@_vector_type * vector) { @TYPE@_vector_reset(vector); - @TYPE@_vector_realloc_data__(vector , 0); + @TYPE@_vector_realloc_data__(vector , 0, vector->default_value); } @@ -848,7 +859,7 @@ void @TYPE@_vector_set_many(@TYPE@_vector_type * vector , int index , const @TYP { int min_size = index + length; if (min_size > vector->alloc_size) - @TYPE@_vector_realloc_data__(vector , 2 * min_size); + @TYPE@_vector_realloc_data__(vector , 2 * min_size, vector->default_value); memcpy( &vector->data[index] , data , length * sizeof * data); if (min_size > vector->size) vector->size = min_size; @@ -931,7 +942,7 @@ void @TYPE@_vector_append_vector(@TYPE@_vector_type * vector , const @TYPE@_vect */ void @TYPE@_vector_shrink(@TYPE@_vector_type * vector) { - @TYPE@_vector_realloc_data__(vector , vector->size); + @TYPE@_vector_realloc_data__(vector , vector->size, vector->default_value); } @@ -1420,7 +1431,7 @@ void @TYPE@_vector_fprintf(const @TYPE@_vector_type * vector , FILE * stream , c vector_resize based on the input size. */ void @TYPE@_vector_fread_data( @TYPE@_vector_type * vector , int size, FILE * stream) { - @TYPE@_vector_realloc_data__( vector , size ); + @TYPE@_vector_realloc_data__( vector , size, vector->default_value ); util_fread( vector->data , sizeof * vector->data , size , stream , __func__); vector->size = size; } diff --git a/ThirdParty/Ert/lib/vector_template.h.in b/ThirdParty/Ert/lib/vector_template.h.in index c11dc38d34..8850800e2e 100644 --- a/ThirdParty/Ert/lib/vector_template.h.in +++ b/ThirdParty/Ert/lib/vector_template.h.in @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vector_template.h' is part of ERT - Ensemble based Reservoir Tool. @@ -61,7 +61,7 @@ typedef @TYPE@ (@TYPE@_ftype) (@TYPE@); int @TYPE@_vector_get_min_index(const @TYPE@_vector_type * vector, bool reverse); int @TYPE@_vector_get_max_index(const @TYPE@_vector_type * vector, bool reverse); @TYPE@ @TYPE@_vector_iadd( @TYPE@_vector_type * vector , int index , @TYPE@ delta); - void @TYPE@_vector_resize( @TYPE@_vector_type * vector , int new_size ); + void @TYPE@_vector_resize( @TYPE@_vector_type * vector , int new_size , @TYPE@ default_value ); void @TYPE@_vector_iset(@TYPE@_vector_type * , int , @TYPE@); void @TYPE@_vector_iset_block(@TYPE@_vector_type * vector , int index , int block_size , @TYPE@ value); void @TYPE@_vector_idel_block( @TYPE@_vector_type * vector , int index , int block_size); diff --git a/ThirdParty/Ert/lib/vector_template.hpp.in b/ThirdParty/Ert/lib/vector_template.hpp.in index f4574fdda5..cc98127f36 100644 --- a/ThirdParty/Ert/lib/vector_template.hpp.in +++ b/ThirdParty/Ert/lib/vector_template.hpp.in @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. + Copyright (C) 2011 Equinor ASA, Norway. The file 'vector_template.hpp' is part of ERT - Ensemble based Reservoir Tool. diff --git a/ThirdParty/Ert/python/CMakeLists.txt b/ThirdParty/Ert/python/CMakeLists.txt index 6463a7704c..8f9cf51d9f 100644 --- a/ThirdParty/Ert/python/CMakeLists.txt +++ b/ThirdParty/Ert/python/CMakeLists.txt @@ -35,3 +35,6 @@ if (BUILD_TESTS) add_subdirectory( tests ) endif() +if(RST_DOC) + add_subdirectory( docs ) +endif() diff --git a/ThirdParty/Ert/python/docs/CMakeLists.txt b/ThirdParty/Ert/python/docs/CMakeLists.txt new file mode 100644 index 0000000000..58516cf894 --- /dev/null +++ b/ThirdParty/Ert/python/docs/CMakeLists.txt @@ -0,0 +1,60 @@ +find_package(Sphinx REQUIRED) + +set(DOC_INSTALL_PREFIX "share/libecl/docs") +set(doc_build "${PROJECT_BINARY_DIR}/doc_build") +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/code" DESTINATION ${doc_build}) + +configure_file(index.rst.in "${doc_build}/index.rst") +configure_file(conf.py.in "${doc_build}/conf.py") + +add_custom_target(api-doc ALL + COMMAND sphinx-apidoc -e -o "${doc_build}/api" ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} tests + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} + DEPENDS ecl) + +add_custom_target(html-doc ALL + COMMAND sphinx-build -b html -d ${doc_build}/doctrees ${doc_build} ${doc_build}/html + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} + DEPENDS api-doc) + +INSTALL( DIRECTORY ${doc_build}/html DESTINATION ${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_PREFIX}) + + +# This command will configure sphinx to create a LaTeX version of the manual in +# ${doc_build}/latex - this can then subsequently be compiled with pdflatex to +# generate a pdf document. +# +# The LaTeX code generated by sphinx uses some packages which are not +# installed on RHEL 6/7, those sty files are therefor bundled with this +# project and copied manually to the LaTeX directory. +# +# Observe that at least on stock ubuntu 16.04 cmake will complain with a message: +# +# -- Could NOT find LATEX (missing: pdflatex) +# +# even in situatons where pdflatex is found and works ok; in this case the +# PDFLATEX_COMPILER variable is set and the pdf generation seems to work as +# expected. +find_package(LATEX COMPONENTS pdflatex) +if (PDFLATEX_COMPILER) + set(latex_workdir "${doc_build}/latex") + + add_custom_target(latex-doc ALL + COMMAND sphinx-build -b latex -d ${doc_build}/doctrees ${doc_build} ${latex_workdir} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} + DEPENDS api-doc) + + file(GLOB sty_files "latex/*.sty") + file(COPY ${sty_files} DESTINATION ${latex_workdir}) + + # The pdflatex command is issued twice to let latex resolve references + # correctly. + add_custom_target(pdf-doc ALL + COMMAND ${PDFLATEX_COMPILER} "libecl.tex" + COMMAND ${PDFLATEX_COMPILER} "libecl.tex" + DEPENDS latex-doc + WORKING_DIRECTORY ${latex_workdir}) + + install(FILES ${latex_workdir}/libecl.pdf DESTINATION ${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_PREFIX}/pdf) +endif() + diff --git a/ThirdParty/Ert/docs/code/index.rst b/ThirdParty/Ert/python/docs/code/index.rst similarity index 90% rename from ThirdParty/Ert/docs/code/index.rst rename to ThirdParty/Ert/python/docs/code/index.rst index 8ebb5c1196..35405bde17 100644 --- a/ThirdParty/Ert/docs/code/index.rst +++ b/ThirdParty/Ert/python/docs/code/index.rst @@ -7,5 +7,4 @@ Contents: :maxdepth: 1 python/index - C/index diff --git a/ThirdParty/Ert/docs/code/python/eclipse/index.rst b/ThirdParty/Ert/python/docs/code/python/eclipse/index.rst similarity index 100% rename from ThirdParty/Ert/docs/code/python/eclipse/index.rst rename to ThirdParty/Ert/python/docs/code/python/eclipse/index.rst diff --git a/ThirdParty/Ert/docs/code/python/examples/eclipse/index.rst b/ThirdParty/Ert/python/docs/code/python/examples/eclipse/index.rst similarity index 100% rename from ThirdParty/Ert/docs/code/python/examples/eclipse/index.rst rename to ThirdParty/Ert/python/docs/code/python/examples/eclipse/index.rst diff --git a/ThirdParty/Ert/docs/code/python/examples/geo/index.rst b/ThirdParty/Ert/python/docs/code/python/examples/geo/index.rst similarity index 100% rename from ThirdParty/Ert/docs/code/python/examples/geo/index.rst rename to ThirdParty/Ert/python/docs/code/python/examples/geo/index.rst diff --git a/ThirdParty/Ert/docs/code/python/examples/index.rst b/ThirdParty/Ert/python/docs/code/python/examples/index.rst similarity index 81% rename from ThirdParty/Ert/docs/code/python/examples/index.rst rename to ThirdParty/Ert/python/docs/code/python/examples/index.rst index d5f7978c2f..90b577182b 100644 --- a/ThirdParty/Ert/docs/code/python/examples/index.rst +++ b/ThirdParty/Ert/python/docs/code/python/examples/index.rst @@ -7,4 +7,3 @@ Examples Eclipse results Geometric objects - Full ert cases diff --git a/ThirdParty/Ert/docs/code/python/index.rst b/ThirdParty/Ert/python/docs/code/python/index.rst similarity index 54% rename from ThirdParty/Ert/docs/code/python/index.rst rename to ThirdParty/Ert/python/docs/code/python/index.rst index 80e9b8d0f0..ec5233c5e3 100644 --- a/ThirdParty/Ert/docs/code/python/index.rst +++ b/ThirdParty/Ert/python/docs/code/python/index.rst @@ -9,5 +9,3 @@ Python documentation introduction/index Overview of ert Python examples/index - ert package - autogenerated API documentation <../../API/python/ert> - ert_gui package - autogenerated API documentation <../../API/python/ert_gui> diff --git a/ThirdParty/Ert/docs/code/python/introduction/index.rst b/ThirdParty/Ert/python/docs/code/python/introduction/index.rst similarity index 100% rename from ThirdParty/Ert/docs/code/python/introduction/index.rst rename to ThirdParty/Ert/python/docs/code/python/introduction/index.rst diff --git a/ThirdParty/Ert/docs/code/python/packages/eclipse/index.rst b/ThirdParty/Ert/python/docs/code/python/packages/eclipse/index.rst similarity index 100% rename from ThirdParty/Ert/docs/code/python/packages/eclipse/index.rst rename to ThirdParty/Ert/python/docs/code/python/packages/eclipse/index.rst diff --git a/ThirdParty/Ert/docs/code/python/packages/index.rst b/ThirdParty/Ert/python/docs/code/python/packages/index.rst similarity index 86% rename from ThirdParty/Ert/docs/code/python/packages/index.rst rename to ThirdParty/Ert/python/docs/code/python/packages/index.rst index f7522ecb6c..04ebdc6959 100644 --- a/ThirdParty/Ert/docs/code/python/packages/index.rst +++ b/ThirdParty/Ert/python/docs/code/python/packages/index.rst @@ -4,10 +4,7 @@ The ert packages .. toctree:: :maxdepth: 1 - util/index.rst eclipse/index.rst - well/index.rst - geometry/index.rst Currently only the package targeted at working with Eclipse files, diff --git a/ThirdParty/Ert/docs/conf.py.in b/ThirdParty/Ert/python/docs/conf.py.in similarity index 93% rename from ThirdParty/Ert/docs/conf.py.in rename to ThirdParty/Ert/python/docs/conf.py.in index 2bde72df1c..7d57a51d49 100644 --- a/ThirdParty/Ert/docs/conf.py.in +++ b/ThirdParty/Ert/python/docs/conf.py.in @@ -19,7 +19,7 @@ import os # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath('${PYTHON_INSTALL_PREFIX}')) +sys.path.insert(0, os.path.join('${PROJECT_BINARY_DIR}','${PYTHON_INSTALL_PREFIX}')) # -- General configuration ------------------------------------------------ @@ -47,17 +47,17 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'ert' -copyright = u'2014, Statoil ASA' +project = u'libecl' +copyright = u'2014, Equinor ASA' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '${ERT_VERSION_MAJOR}.${ERT_VERSION_MINOR}' +version = '${LIBECL_VERSION_MAJOR}.${LIBECL_VERSION_MINOR}' # The full version, including alpha/beta/rc tags. -release = '${ERT_VERSION_MAJOR}.${ERT_VERSION_MINOR}.${ERT_VERSION_MICRO}' +release = '${LIBECL_VERSION_MAJOR}.${LIBECL_VERSION_MINOR}.${LIBECL_VERSION_MICRO}' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -180,7 +180,7 @@ html_static_path = ['_static'] #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'ertdoc' +htmlhelp_basename = 'libecldoc' # -- Options for LaTeX output --------------------------------------------- @@ -200,8 +200,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'ert.tex', u'ert Documentation', - u'Statoil ASA', 'manual'), + ('index', 'libecl.tex', u'libecl documentation', + u'Equinor ASA', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -230,8 +230,8 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'ert', u'ert Documentation', - [u'Statoil ASA'], 1) + ('index', 'libecl', u'libecl documentation', + [u'Equinor ASA'], 1) ] # If true, show URL addresses after external links. @@ -244,8 +244,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'ert', u'ert Documentation', - u'Statoil ASA', 'ert', 'One line description of project.', + ('index', 'libecl', u'libecl ocumentation', + u'Equinor ASA', 'ert', 'One line description of project.', 'Miscellaneous'), ] @@ -266,9 +266,9 @@ texinfo_documents = [ # Bibliographic Dublin Core info. epub_title = u'ert' -epub_author = u'Statoil ASA' -epub_publisher = u'Statoil ASA' -epub_copyright = u'2014, Statoil ASA' +epub_author = u'Equinor ASA' +epub_publisher = u'Equinor ASA' +epub_copyright = u'2014, Equinor ASA' # The basename for the epub file. It defaults to the project name. #epub_basename = u'ert' diff --git a/ThirdParty/Ert/docs/examples/avg_pressure.py b/ThirdParty/Ert/python/docs/examples/avg_pressure.py similarity index 96% rename from ThirdParty/Ert/docs/examples/avg_pressure.py rename to ThirdParty/Ert/python/docs/examples/avg_pressure.py index 45dd786802..aa502b8c77 100644 --- a/ThirdParty/Ert/docs/examples/avg_pressure.py +++ b/ThirdParty/Ert/python/docs/examples/avg_pressure.py @@ -3,7 +3,8 @@ import sys import matplotlib.pyplot as plt # Import the required symbols from the ecl.ecl package. -from ecl.ecl import EclFile, EclGrid, EclRegion, EclRestartFile +from ecl.eclfile import EclFile, EclRestartFile +from ecl.grid import EclGrid, EclRegion # Calculate the average pressure for all the cells in the region using diff --git a/ThirdParty/Ert/docs/examples/cmp_nnc.py b/ThirdParty/Ert/python/docs/examples/cmp_nnc.py similarity index 69% rename from ThirdParty/Ert/docs/examples/cmp_nnc.py rename to ThirdParty/Ert/python/docs/examples/cmp_nnc.py index 1e1ff2f52c..248d3000f2 100644 --- a/ThirdParty/Ert/docs/examples/cmp_nnc.py +++ b/ThirdParty/Ert/python/docs/examples/cmp_nnc.py @@ -1,7 +1,8 @@ #!/usr/bin/env python import sys from operator import itemgetter -from ecl.ecl import EclFile, EclGrid +from ecl.eclfile import EclFile +from ecl.grid import EclGrid @@ -22,10 +23,15 @@ if __name__ == "__main__": nnc_list = sorted(nnc_list, key = itemgetter(0)) for (g1,g2,T) in nnc_list: + # grid_ijk assumes 0-based indexing, g1/g2 are 1-based (FORTRAN) + # Convert them to zero based ones. + g1 = g1 - 1 + g2 = g2 - 1 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) + # print 1-based indices just like in eclipse PRT files + print "(%02d,%02d,%02d) -> (%02d,%02d,%02d) T:%g" % (i1+1,j1+1,k1+1,i2+1,j2+1,k2+1,T) diff --git a/ThirdParty/Ert/docs/examples/grid_info.py b/ThirdParty/Ert/python/docs/examples/grid_info.py similarity index 94% rename from ThirdParty/Ert/docs/examples/grid_info.py rename to ThirdParty/Ert/python/docs/examples/grid_info.py index 3a226a929f..20ffdb0cab 100644 --- a/ThirdParty/Ert/docs/examples/grid_info.py +++ b/ThirdParty/Ert/python/docs/examples/grid_info.py @@ -1,6 +1,6 @@ #!/usr/bin/env python import sys -from ecl.ecl import EclGrid, EclRegion +from ecl.grid import EclGrid, EclRegion def volume_min_max(grid): diff --git a/ThirdParty/Ert/docs/index.rst.in b/ThirdParty/Ert/python/docs/index.rst.in similarity index 87% rename from ThirdParty/Ert/docs/index.rst.in rename to ThirdParty/Ert/python/docs/index.rst.in index f75b6f9116..9d688b5183 100644 --- a/ThirdParty/Ert/docs/index.rst.in +++ b/ThirdParty/Ert/python/docs/index.rst.in @@ -7,10 +7,8 @@ Contents: :maxdepth: 1 :numbered: - user/index code/index - ${ERT_DOC_LINK} - + api/ecl Indices and tables ================== diff --git a/ThirdParty/Ert/python/docs/latex/capt-of.sty b/ThirdParty/Ert/python/docs/latex/capt-of.sty new file mode 100644 index 0000000000..b40978ad2c --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/capt-of.sty @@ -0,0 +1,33 @@ +%% +%% This is file `capt-of.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% capt-of.dtx (with options: `package') +%% ---------------------------------------------------------------------- +%% The capt-off package -- float-style captions outside of floats +%% Copyright (c) 2010 Robin Fairbairns +%% +%% This work may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License, either version 1.3c of this license or (at +%% your option) any later version. The latest version of this license is in: +%% http://www.latex-project.org/lppl.txt, and version 1.3c or later is part +%% of all distributions of LaTeX version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This work consists of the files capt-of.dtx, capt-of.ins, and README +%% and the derived files footmisc.sty (not distributed from the archive) +%% and footmisc.pdf. +%% ----------------------------------------------------------------------- +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{capt-of}% + [2009/12/29 v0.2 + standard captions outside of floats% + ]% $Id: footmisc.dtx,v 4.20 2005/03/17 13:41:58 rf Exp rf10 $ +\newcommand\captionof[1]{\def\@captype{#1}\caption} +\endinput +%% +%% End of file `capt-of.sty'. diff --git a/ThirdParty/Ert/python/docs/latex/fncychap.sty b/ThirdParty/Ert/python/docs/latex/fncychap.sty new file mode 100644 index 0000000000..f0a9c97e22 --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/fncychap.sty @@ -0,0 +1,701 @@ +%% Copyright 2007 Ulf Lindgren +% +% This work may be distributed and/or modified under the conditions of the LaTeX +% Project Public License, either version 1.3 of this license or (at your option) +% any later version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX version +% 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Ulf Lindgren. +% +% This work consists of all files listed in manifest.txt. +% +%% This statement added 2010/12/10 by Clea F. Rees following correspondence +%% between Ulf Lindgren and Karl Berry concerning licensing. + +%%% Copyright Ulf A. Lindgren +%%% +%%% Note Premission is granted to modify this file under +%%% the condition that it is saved using another +%%% file and package name. +%%% +%%% Revision 1.1 (1997) +%%% +%%% Jan. 8th Modified package name base date option +%%% Jan. 22th Modified FmN and FmTi for error in book.cls +%%% \MakeUppercase{#}->{\MakeUppercase#} +%%% Apr. 6th Modified Lenny option to prevent undesired +%%% skip of line. +%%% Nov. 8th Fixed \@chapapp for AMS +%%% +%%% Revision 1.2 (1998) +%%% +%%% Feb. 11th Fixed appendix problem related to Bjarne +%%% Aug. 11th Fixed problem related to 11pt and 12pt +%%% suggested by Tomas Lundberg. THANKS! +%%% +%%% Revision 1.3 (2004) +%%% Sep. 20th problem with frontmatter, mainmatter and +%%% backmatter, pointed out by Lapo Mori +%%% +%%% Revision 1.31 (2004) +%%% Sep. 21th problem with the Rejne definition streched text +%%% caused ugly gaps in the vrule aligned with the title +%%% text. Kindly pointed out to me by Hendri Adriaens +%%% +%%% Revision 1.32 (2005) +%%% Jun. 23th compatibility problem with the KOMA class 'scrbook.cls' +%%% a remedy is a redefinition of '\@schapter' in +%%% line with that used in KOMA. The problem was pointed +%%% out to me by Mikkel Holm Olsen +%%% +%%% Revision 1.33 (2005) +%%% Aug. 9th misspelled ``TWELV'' corrected, the error was pointed +%%% out to me by George Pearson +%%% +%%% Revision 1.34 (2007) +%%% Added an alternative to Lenny provided by Peter +%%% Osborne (2005-11-28) +%%% Corrected front, main and back matter, based on input +%%% from Bas van Gils (2006-04-24) +%%% Jul. 30th Added Bjornstrup option provided by Jean-Marc +%%% Francois (2007-01-05). +%%% Reverted to \MakeUppercase{#} see rev 1.1, solved +%%% problem with MakeUppercase and MakeLowercase pointed +%%% out by Marco Feuerstein (2007-06-06) + + +%%% Last modified Jul. 2007 + +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesPackage{fncychap} + [2007/07/30 v1.34 + LaTeX package (Revised chapters)] + +%%%% For conditional inclusion of color +\newif\ifusecolor +\usecolorfalse + + + +%%%% DEFINITION OF Chapapp variables +\newcommand{\CNV}{\huge\bfseries} +\newcommand{\ChNameVar}[1]{\renewcommand{\CNV}{#1}} + + +%%%% DEFINITION OF TheChapter variables +\newcommand{\CNoV}{\huge\bfseries} +\newcommand{\ChNumVar}[1]{\renewcommand{\CNoV}{#1}} + +\newif\ifUCN +\UCNfalse +\newif\ifLCN +\LCNfalse +\def\ChNameLowerCase{\LCNtrue\UCNfalse} +\def\ChNameUpperCase{\UCNtrue\LCNfalse} +\def\ChNameAsIs{\UCNfalse\LCNfalse} + +%%%%% Fix for AMSBook 971008 + +\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{} + + +%%%%% Fix for Bjarne and appendix 980211 + +\newif\ifinapp +\inappfalse +\renewcommand\appendix{\par + \setcounter{chapter}{0}% + \setcounter{section}{0}% + \inapptrue% + \renewcommand\@chapapp{\appendixname}% + \renewcommand\thechapter{\@Alph\c@chapter}} + +%%%%% Fix for frontmatter, mainmatter, and backmatter 040920 + +\@ifundefined{@mainmatter}{\newif\if@mainmatter \@mainmattertrue}{} + +%%%%% + + + +\newcommand{\FmN}[1]{% +\ifUCN + {\MakeUppercase{#1}}\LCNfalse +\else + \ifLCN + {\MakeLowercase{#1}}\UCNfalse + \else #1 + \fi +\fi} + + +%%%% DEFINITION OF Title variables +\newcommand{\CTV}{\Huge\bfseries} +\newcommand{\ChTitleVar}[1]{\renewcommand{\CTV}{#1}} + +%%%% DEFINITION OF the basic rule width +\newlength{\RW} +\setlength{\RW}{1pt} +\newcommand{\ChRuleWidth}[1]{\setlength{\RW}{#1}} + +\newif\ifUCT +\UCTfalse +\newif\ifLCT +\LCTfalse +\def\ChTitleLowerCase{\LCTtrue\UCTfalse} +\def\ChTitleUpperCase{\UCTtrue\LCTfalse} +\def\ChTitleAsIs{\UCTfalse\LCTfalse} +\newcommand{\FmTi}[1]{% +\ifUCT + {\MakeUppercase{#1}}\LCTfalse +\else + \ifLCT + {\MakeLowercase{#1}}\UCTfalse + \else {#1} + \fi +\fi} + + + +\newlength{\mylen} +\newlength{\myhi} +\newlength{\px} +\newlength{\py} +\newlength{\pyy} +\newlength{\pxx} + + +\def\mghrulefill#1{\leavevmode\leaders\hrule\@height #1\hfill\kern\z@} + +\newcommand{\DOCH}{% + \CNV\FmN{\@chapapp}\space \CNoV\thechapter + \par\nobreak + \vskip 20\p@ + } +\newcommand{\DOTI}[1]{% + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@ + } +\newcommand{\DOTIS}[1]{% + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@ + } + +%%%%%% SONNY DEF + +\DeclareOption{Sonny}{% + \ChNameVar{\Large\sf} + \ChNumVar{\Huge} + \ChTitleVar{\Large\sf} + \ChRuleWidth{0.5pt} + \ChNameUpperCase + \renewcommand{\DOCH}{% + \raggedleft + \CNV\FmN{\@chapapp}\space \CNoV\thechapter + \par\nobreak + \vskip 40\p@} + \renewcommand{\DOTI}[1]{% + \CTV\raggedleft\mghrulefill{\RW}\par\nobreak + \vskip 5\p@ + \CTV\FmTi{#1}\par\nobreak + \mghrulefill{\RW}\par\nobreak + \vskip 40\p@} + \renewcommand{\DOTIS}[1]{% + \CTV\raggedleft\mghrulefill{\RW}\par\nobreak + \vskip 5\p@ + \CTV\FmTi{#1}\par\nobreak + \mghrulefill{\RW}\par\nobreak + \vskip 40\p@} +} + +%%%%%% LENNY DEF + +\DeclareOption{Lenny}{% + + \ChNameVar{\fontsize{14}{16}\usefont{OT1}{phv}{m}{n}\selectfont} + \ChNumVar{\fontsize{60}{62}\usefont{OT1}{ptm}{m}{n}\selectfont} + \ChTitleVar{\Huge\bfseries\rm} + \ChRuleWidth{1pt} + \renewcommand{\DOCH}{% + \settowidth{\px}{\CNV\FmN{\@chapapp}} + \addtolength{\px}{2pt} + \settoheight{\py}{\CNV\FmN{\@chapapp}} + \addtolength{\py}{1pt} + + \settowidth{\mylen}{\CNV\FmN{\@chapapp}\space\CNoV\thechapter} + \addtolength{\mylen}{1pt} + \settowidth{\pxx}{\CNoV\thechapter} + \addtolength{\pxx}{-1pt} + + \settoheight{\pyy}{\CNoV\thechapter} + \addtolength{\pyy}{-2pt} + \setlength{\myhi}{\pyy} + \addtolength{\myhi}{-1\py} + \par + \parbox[b]{\textwidth}{% + \rule[\py]{\RW}{\myhi}% + \hskip -\RW% + \rule[\pyy]{\px}{\RW}% + \hskip -\px% + \raggedright% + \CNV\FmN{\@chapapp}\space\CNoV\thechapter% + \hskip1pt% + \mghrulefill{\RW}% + \rule{\RW}{\pyy}\par\nobreak% + \vskip -\baselineskip% + \vskip -\pyy% + \hskip \mylen% + \mghrulefill{\RW}\par\nobreak% + \vskip \pyy}% + \vskip 20\p@} + + + \renewcommand{\DOTI}[1]{% + \raggedright + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@} + + \renewcommand{\DOTIS}[1]{% + \raggedright + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@} + } + +%%%%%% Peter Osbornes' version of LENNY DEF + +\DeclareOption{PetersLenny}{% + +% five new lengths +\newlength{\bl} % bottom left : orig \space +\setlength{\bl}{6pt} +\newcommand{\BL}[1]{\setlength{\bl}{#1}} +\newlength{\br} % bottom right : orig 1pt +\setlength{\br}{1pt} +\newcommand{\BR}[1]{\setlength{\br}{#1}} +\newlength{\tl} % top left : orig 2pt +\setlength{\tl}{2pt} +\newcommand{\TL}[1]{\setlength{\tl}{#1}} +\newlength{\trr} % top right :orig 1pt +\setlength{\trr}{1pt} +\newcommand{\TR}[1]{\setlength{\trr}{#1}} +\newlength{\blrule} % top right :orig 1pt +\setlength{\trr}{0pt} +\newcommand{\BLrule}[1]{\setlength{\blrule}{#1}} + + + \ChNameVar{\fontsize{14}{16}\usefont{OT1}{phv}{m}{n}\selectfont} + \ChNumVar{\fontsize{60}{62}\usefont{OT1}{ptm}{m}{n}\selectfont} + \ChTitleVar{\Huge\bfseries\rm} + \ChRuleWidth{1pt} +\renewcommand{\DOCH}{% + + +%%%%%%% tweaks for 1--9 and A--Z +\ifcase\c@chapter\relax% +\or\BL{-3pt}\TL{-4pt}\BR{0pt}\TR{-6pt}%1 +\or\BL{0pt}\TL{-4pt}\BR{2pt}\TR{-4pt}%2 +\or\BL{0pt}\TL{-4pt}\BR{2pt}\TR{-4pt}%3 +\or\BL{0pt}\TL{5pt}\BR{2pt}\TR{-4pt}%4 +\or\BL{0pt}\TL{3pt}\BR{2pt}\TR{-4pt}%5 +\or\BL{-1pt}\TL{0pt}\BR{2pt}\TR{-2pt}%6 +\or\BL{0pt}\TL{-3pt}\BR{2pt}\TR{-2pt}%7 +\or\BL{0pt}\TL{-3pt}\BR{2pt}\TR{-2pt}%8 +\or\BL{0pt}\TL{-3pt}\BR{-4pt}\TR{-2pt}%9 +\or\BL{-3pt}\TL{-3pt}\BR{2pt}\TR{-7pt}%10 +\or\BL{-6pt}\TL{-6pt}\BR{0pt}\TR{-9pt}%11 +\or\BL{-6pt}\TL{-6pt}\BR{2pt}\TR{-7pt}%12 +\or\BL{-5pt}\TL{-5pt}\BR{0pt}\TR{-9pt}%13 +\or\BL{-6pt}\TL{-6pt}\BR{0pt}\TR{-9pt}%14 +\or\BL{-3pt}\TL{-3pt}\BR{3pt}\TR{-6pt}%15 +\or\BL{-3pt}\TL{-3pt}\BR{3pt}\TR{-6pt}%16 +\or\BL{-5pt}\TL{-3pt}\BR{-8pt}\TR{-6pt}%17 +\or\BL{-5pt}\TL{-5pt}\BR{0pt}\TR{-9pt}%18 +\or\BL{-3pt}\TL{-3pt}\BR{-6pt}\TR{-9pt}%19 +\or\BL{0pt}\TL{0pt}\BR{0pt}\TR{-5pt}%20 +\fi + +\ifinapp\ifcase\c@chapter\relax% +\or\BL{0pt}\TL{14pt}\BR{5pt}\TR{-19pt}%A +\or\BL{0pt}\TL{-5pt}\BR{-3pt}\TR{-8pt}%B +\or\BL{-3pt}\TL{-2pt}\BR{1pt}\TR{-6pt}\BLrule{0pt}%C +\or\BL{0pt}\TL{-5pt}\BR{-3pt}\TR{-8pt}\BLrule{0pt}%D +\or\BL{0pt}\TL{-5pt}\BR{2pt}\TR{-3pt}%E +\or\BL{0pt}\TL{-5pt}\BR{-10pt}\TR{-1pt}%F +\or\BL{-3pt}\TL{0pt}\BR{0pt}\TR{-7pt}%G +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}%H +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}%I +\or\BL{2pt}\TL{0pt}\BR{-3pt}\TR{1pt}%J +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}%K +\or\BL{0pt}\TL{-5pt}\BR{2pt}\TR{-19pt}%L +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}%M +\or\BL{0pt}\TL{-5pt}\BR{-2pt}\TR{-1pt}%N +\or\BL{-3pt}\TL{-2pt}\BR{-3pt}\TR{-11pt}%O +\or\BL{0pt}\TL{-5pt}\BR{-9pt}\TR{-3pt}%P +\or\BL{-3pt}\TL{-2pt}\BR{-3pt}\TR{-11pt}%Q +\or\BL{0pt}\TL{-5pt}\BR{4pt}\TR{-8pt}%R +\or\BL{-2pt}\TL{-2pt}\BR{-2pt}\TR{-7pt}%S +\or\BL{-3pt}\TL{0pt}\BR{-5pt}\TR{4pt}\BLrule{8pt}%T +\or\BL{-7pt}\TL{-11pt}\BR{-5pt}\TR{-7pt}\BLrule{0pt}%U +\or\BL{-14pt}\TL{-5pt}\BR{-14pt}\TR{-1pt}\BLrule{14pt}%V +\or\BL{-10pt}\TL{-9pt}\BR{-13pt}\TR{-3pt}\BLrule{7pt}%W +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}\BLrule{0pt}%X +\or\BL{-6pt}\TL{-4pt}\BR{-7pt}\TR{1pt}\BLrule{7pt}%Y +\or\BL{0pt}\TL{-5pt}\BR{3pt}\TR{-1pt}\BLrule{0pt}%Z +\fi\fi +%%%%%%% + \settowidth{\px}{\CNV\FmN{\@chapapp}} + \addtolength{\px}{\tl} %MOD change 2pt to \tl + \settoheight{\py}{\CNV\FmN{\@chapapp}} + \addtolength{\py}{1pt} + + \settowidth{\mylen}{\CNV\FmN{\@chapapp}\space\CNoV\thechapter} + \addtolength{\mylen}{\trr}% MOD change 1pt to \tr + \settowidth{\pxx}{\CNoV\thechapter} + \addtolength{\pxx}{-1pt} + + \settoheight{\pyy}{\CNoV\thechapter} + \addtolength{\pyy}{-2pt} + \setlength{\myhi}{\pyy} + \addtolength{\myhi}{-1\py} + \par + \parbox[b]{\textwidth}{% + \rule[\py]{\RW}{\myhi}% + \hskip -\RW% + \rule[\pyy]{\px}{\RW}% + \hskip -\px% + \raggedright% + \CNV\FmN{\@chapapp}\rule{\blrule}{\RW}\hskip\bl\CNoV\thechapter%MOD +% \CNV\FmN{\@chapapp}\space\CNoV\thechapter %ORIGINAL + \hskip\br% %MOD 1pt to \br + \mghrulefill{\RW}% + \rule{\RW}{\pyy}\par\nobreak% + \vskip -\baselineskip% + \vskip -\pyy% + \hskip \mylen% + \mghrulefill{\RW}\par\nobreak% + \vskip \pyy}% + \vskip 20\p@} + + + \renewcommand{\DOTI}[1]{% + \raggedright + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@} + + \renewcommand{\DOTIS}[1]{% + \raggedright + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@} + } + + +% + + +%%%%%% BJORNSTRUP DEF + +\DeclareOption{Bjornstrup}{% + \usecolortrue + % pzc (Zapf Chancelery) is nice. ppl (Palatino) is cool too. + \ChNumVar{\fontsize{76}{80}\usefont{OT1}{pzc}{m}{n}\selectfont} + \ChTitleVar{\raggedleft\Large\sffamily\bfseries} + + \setlength{\myhi}{10pt} % Space between grey box border and text + \setlength{\mylen}{\textwidth} + \addtolength{\mylen}{-2\myhi} + \renewcommand{\DOCH}{% + \settowidth{\py}{\CNoV\thechapter} + \addtolength{\py}{-10pt} % Amount of space by which the +% % number is shifted right + \fboxsep=0pt% + \colorbox[gray]{.85}{\rule{0pt}{40pt}\parbox[b]{\textwidth}{\hfill}}% + \kern-\py\raise20pt% + \hbox{\color[gray]{.5}\CNoV\thechapter}\\% + } + + \renewcommand{\DOTI}[1]{% + \nointerlineskip\raggedright% + \fboxsep=\myhi% + \vskip-1ex% + \colorbox[gray]{.85}{\parbox[t]{\mylen}{\CTV\FmTi{#1}}}\par\nobreak% + \vskip 40\p@% + } + + \renewcommand{\DOTIS}[1]{% + \fboxsep=0pt + \colorbox[gray]{.85}{\rule{0pt}{40pt}\parbox[b]{\textwidth}{\hfill}}\\% + \nointerlineskip\raggedright% + \fboxsep=\myhi% + \colorbox[gray]{.85}{\parbox[t]{\mylen}{\CTV\FmTi{#1}}}\par\nobreak% + \vskip 40\p@% + } +} + + +%%%%%%% GLENN DEF + + +\DeclareOption{Glenn}{% + \ChNameVar{\bfseries\Large\sf} + \ChNumVar{\Huge} + \ChTitleVar{\bfseries\Large\rm} + \ChRuleWidth{1pt} + \ChNameUpperCase + \ChTitleUpperCase + \renewcommand{\DOCH}{% + \settoheight{\myhi}{\CTV\FmTi{Test}} + \setlength{\py}{\baselineskip} + \addtolength{\py}{\RW} + \addtolength{\py}{\myhi} + \setlength{\pyy}{\py} + \addtolength{\pyy}{-1\RW} + + \raggedright + \CNV\FmN{\@chapapp}\space\CNoV\thechapter + \hskip 3pt\mghrulefill{\RW}\rule[-1\pyy]{2\RW}{\py}\par\nobreak} + + \renewcommand{\DOTI}[1]{% + \addtolength{\pyy}{-4pt} + \settoheight{\myhi}{\CTV\FmTi{#1}} + \addtolength{\myhi}{\py} + \addtolength{\myhi}{-1\RW} + \vskip -1\pyy + \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt + \raggedleft\CTV\FmTi{#1}\par\nobreak + \vskip 80\p@} + +\newlength{\backskip} + \renewcommand{\DOTIS}[1]{% +% \setlength{\py}{10pt} +% \setlength{\pyy}{\py} +% \addtolength{\pyy}{\RW} +% \setlength{\myhi}{\baselineskip} +% \addtolength{\myhi}{\pyy} +% \mghrulefill{\RW}\rule[-1\py]{2\RW}{\pyy}\par\nobreak +% \addtolength{}{} +%\vskip -1\baselineskip +% \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 2pt +% \raggedleft\CTV\FmTi{#1}\par\nobreak +% \vskip 60\p@} +%% Fix suggested by Tomas Lundberg + \setlength{\py}{25pt} % eller vad man vill + \setlength{\pyy}{\py} + \setlength{\backskip}{\py} + \addtolength{\backskip}{2pt} + \addtolength{\pyy}{\RW} + \setlength{\myhi}{\baselineskip} + \addtolength{\myhi}{\pyy} + \mghrulefill{\RW}\rule[-1\py]{2\RW}{\pyy}\par\nobreak + \vskip -1\backskip + \rule{2\RW}{\myhi}\mghrulefill{\RW}\hskip 3pt % + \raggedleft\CTV\FmTi{#1}\par\nobreak + \vskip 40\p@} + } + +%%%%%%% CONNY DEF + +\DeclareOption{Conny}{% + \ChNameUpperCase + \ChTitleUpperCase + \ChNameVar{\centering\Huge\rm\bfseries} + \ChNumVar{\Huge} + \ChTitleVar{\centering\Huge\rm} + \ChRuleWidth{2pt} + + \renewcommand{\DOCH}{% + \mghrulefill{3\RW}\par\nobreak + \vskip -0.5\baselineskip + \mghrulefill{\RW}\par\nobreak + \CNV\FmN{\@chapapp}\space \CNoV\thechapter + \par\nobreak + \vskip -0.5\baselineskip + } + \renewcommand{\DOTI}[1]{% + \mghrulefill{\RW}\par\nobreak + \CTV\FmTi{#1}\par\nobreak + \vskip 60\p@ + } + \renewcommand{\DOTIS}[1]{% + \mghrulefill{\RW}\par\nobreak + \CTV\FmTi{#1}\par\nobreak + \vskip 60\p@ + } + } + +%%%%%%% REJNE DEF + +\DeclareOption{Rejne}{% + + \ChNameUpperCase + \ChTitleUpperCase + \ChNameVar{\centering\Large\rm} + \ChNumVar{\Huge} + \ChTitleVar{\centering\Huge\rm} + \ChRuleWidth{1pt} + \renewcommand{\DOCH}{% + \settoheight{\py}{\CNoV\thechapter} + \parskip=0pt plus 1pt % Set parskip to default, just in case v1.31 + \addtolength{\py}{-1pt} + \CNV\FmN{\@chapapp}\par\nobreak + \vskip 20\p@ + \setlength{\myhi}{2\baselineskip} + \setlength{\px}{\myhi} + \addtolength{\px}{-1\RW} + \rule[-1\px]{\RW}{\myhi}\mghrulefill{\RW}\hskip + 10pt\raisebox{-0.5\py}{\CNoV\thechapter}\hskip 10pt\mghrulefill{\RW}\rule[-1\px]{\RW}{\myhi}\par\nobreak + \vskip -3\p@% Added -2pt vskip to correct for streched text v1.31 + } + \renewcommand{\DOTI}[1]{% + \setlength{\mylen}{\textwidth} + \parskip=0pt plus 1pt % Set parskip to default, just in case v1.31 + \addtolength{\mylen}{-2\RW} + {\vrule width\RW}\parbox{\mylen}{\CTV\FmTi{#1}}{\vrule width\RW}\par\nobreak% + \vskip -3pt\rule{\RW}{2\baselineskip}\mghrulefill{\RW}\rule{\RW}{2\baselineskip}% + \vskip 60\p@% Added -2pt in vskip to correct for streched text v1.31 + } + \renewcommand{\DOTIS}[1]{% + \setlength{\py}{\fboxrule} + \setlength{\fboxrule}{\RW} + \setlength{\mylen}{\textwidth} + \addtolength{\mylen}{-2\RW} + \fbox{\parbox{\mylen}{\vskip 2\baselineskip\CTV\FmTi{#1}\par\nobreak\vskip \baselineskip}} + \setlength{\fboxrule}{\py} + \vskip 60\p@ + } + } + + +%%%%%%% BJARNE DEF + +\DeclareOption{Bjarne}{% + \ChNameUpperCase + \ChTitleUpperCase + \ChNameVar{\raggedleft\normalsize\rm} + \ChNumVar{\raggedleft \bfseries\Large} + \ChTitleVar{\raggedleft \Large\rm} + \ChRuleWidth{1pt} + + +%% Note thechapter -> c@chapter fix appendix bug +%% Fixed misspelled 12 + + \newcounter{AlphaCnt} + \newcounter{AlphaDecCnt} + \newcommand{\AlphaNo}{% + \ifcase\number\theAlphaCnt + \ifnum\c@chapter=0 + ZERO\else{}\fi + \or ONE\or TWO\or THREE\or FOUR\or FIVE + \or SIX\or SEVEN\or EIGHT\or NINE\or TEN + \or ELEVEN\or TWELVE\or THIRTEEN\or FOURTEEN\or FIFTEEN + \or SIXTEEN\or SEVENTEEN\or EIGHTEEN\or NINETEEN\fi +} + + \newcommand{\AlphaDecNo}{% + \setcounter{AlphaDecCnt}{0} + \@whilenum\number\theAlphaCnt>0\do + {\addtocounter{AlphaCnt}{-10} + \addtocounter{AlphaDecCnt}{1}} + \ifnum\number\theAlphaCnt=0 + \else + \addtocounter{AlphaDecCnt}{-1} + \addtocounter{AlphaCnt}{10} + \fi + + + \ifcase\number\theAlphaDecCnt\or TEN\or TWENTY\or THIRTY\or + FORTY\or FIFTY\or SIXTY\or SEVENTY\or EIGHTY\or NINETY\fi + } + \newcommand{\TheAlphaChapter}{% + + \ifinapp + \thechapter + \else + \setcounter{AlphaCnt}{\c@chapter} + \ifnum\c@chapter<20 + \AlphaNo + \else + \AlphaDecNo\AlphaNo + \fi + \fi + } + \renewcommand{\DOCH}{% + \mghrulefill{\RW}\par\nobreak + \CNV\FmN{\@chapapp}\par\nobreak + \CNoV\TheAlphaChapter\par\nobreak + \vskip -1\baselineskip\vskip 5pt\mghrulefill{\RW}\par\nobreak + \vskip 20\p@ + } + \renewcommand{\DOTI}[1]{% + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@ + } + \renewcommand{\DOTIS}[1]{% + \CTV\FmTi{#1}\par\nobreak + \vskip 40\p@ + } +} + +\DeclareOption*{% + \PackageWarning{fancychapter}{unknown style option} + } + +\ProcessOptions* \relax + +\ifusecolor + \RequirePackage{color} +\fi +\def\@makechapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedright \normalfont + \ifnum \c@secnumdepth >\m@ne + \if@mainmatter%%%%% Fix for frontmatter, mainmatter, and backmatter 040920 + \DOCH + \fi + \fi + \interlinepenalty\@M + \if@mainmatter%%%%% Fix for frontmatter, mainmatter, and backmatter 060424 + \DOTI{#1}% + \else% + \DOTIS{#1}% + \fi + }} + + +%%% Begin: To avoid problem with scrbook.cls (fncychap version 1.32) + +%%OUT: +%\def\@schapter#1{\if@twocolumn +% \@topnewpage[\@makeschapterhead{#1}]% +% \else +% \@makeschapterhead{#1}% +% \@afterheading +% \fi} + +%%IN: +\def\@schapter#1{% +\if@twocolumn% + \@makeschapterhead{#1}% +\else% + \@makeschapterhead{#1}% + \@afterheading% +\fi} + +%%% End: To avoid problem with scrbook.cls (fncychap version 1.32) + +\def\@makeschapterhead#1{% + \vspace*{50\p@}% + {\parindent \z@ \raggedright + \normalfont + \interlinepenalty\@M + \DOTIS{#1} + \vskip 40\p@ + }} + +\endinput + + diff --git a/ThirdParty/Ert/python/docs/latex/framed.sty b/ThirdParty/Ert/python/docs/latex/framed.sty new file mode 100644 index 0000000000..b044e96593 --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/framed.sty @@ -0,0 +1,548 @@ +% framed.sty v 0.96 2011/10/22 +% Copyright (C) 1992-2011 by Donald Arseneau (asnd@triumf.ca) +% These macros may be freely transmitted, reproduced, or modified +% for any purpose provided that this notice is left intact. +% +%====================== Begin Instructions ======================= +% +% framed.sty +% ~~~~~~~~~~ +% Create framed, shaded, or differently highlighted regions that can +% break across pages. The environments defined are +% framed - ordinary frame box (\fbox) with edge at margin +% oframed - framed with open top/bottom at page breaks +% shaded - shaded background (\colorbox) bleeding into margin +% shaded* - shaded background (\colorbox) with edge at margin +% snugshade - shaded with tight fit around text (esp. in lists) +% snugshade* - like snugshade with shading edge at margin +% leftbar - thick vertical line in left margin +% +% to be used like +% \begin{framed} +% copious text +% \end{framed} +% +% But the more general purpose of this package is to facilitate the +% definition of new environments that take multi-line material, +% wrap it with some non-breakable formatting (some kind of box or +% decoration) and allow page breaks in the material. Such environments +% are defined to declare (or use) \FrameCommand for applying the boxy +% decoration, and \MakeFramed{settings} ... \endMakeFramed wrapped +% around the main text argument (environment body). +% +% The "framed" environment uses "\fbox", by default, as its "\FrameCommand" +% with the additional settings "\fboxrule=\FrameRule" and "\fboxsep=\FrameSep". +% You can change these lengths (using "\setlength") and you can change +% the definition of "\FrameCommand" to use much fancier boxes. +% +% In fact, the "shaded" environment just redefines \FrameCommand to be +% "\colorbox{shadecolor}" (and you have to define the color `"shadecolor"': +% "\definecolor{shadecolor}..."). +% +% Although the intention is for other packages to define the varieties +% of decoration, a command "\OpenFbox" is defined for frames with open +% tops or bottoms, and used for the "oframed" environment. This facility +% is based on a more complex and capable command "\CustomFBox" which can +% be used for a wider range of frame styles. One such style of a title-bar +% frame with continuation marks is provided as an example. It is used by +% the "titled-frame" environment. To make use of "titled-frame" in your +% document, or the "\TitleBarFrame" command in your own environment +% definitions, you must define the colors TFFrameColor (for the frame) +% and a contrasting TFTitleColor (for the title text). +% +% A page break is allowed, and even encouraged, before the framed +% environment. If you want to attach some text (a box title) to the +% frame, then the text should be inserted by \FrameCommand so it cannot +% be separated from the body. +% +% The contents of the framed regions are restricted: +% Floats, footnotes, marginpars and head-line entries will be lost. +% (Some of these may be handled in a later version.) +% This package will not work with the page breaking of multicol.sty, +% or other systems that perform column-balancing. +% +% The MakeFramed environment does the work. Its `settings' argument +% should contain any adjustments to the text width (via a setting of +% "\hsize"). Here, the parameter "\width" gives the measured extra width +% added by the frame, so a common setting is "\advance\hsize-\width" +% which reduces the width of the text just enough that the outer edge +% of the frame aligns with the margins. The `settings' should also +% include a `restore' command -- "\@parboxrestore" or "\FrameRestore" +% or something similar; for instance, the snugshade environment uses +% settings to eliminate list indents and vertical space, but uses +% "\hspace" in "\FrameCommand" to reproduce the list margin ouside the +% shading. +% +% There are actually four variants of "\FrameCommand" to allow different +% formatting for each part of an environment broken over pages. Unbroken +% text is adorned by "\FrameCommand", whereas split text first uses +% "\FirstFrameCommand", possibly followed by "\MidFrameCommand", and +% finishing with "\LastFrameCommand". The default definitions for +% these three just invokes "\FrameCommand", so that all portions are +% framed the same way. See the oframe environment for use of distinct +% First/Mid/Last frames. +% +% Expert commands: +% \MakeFramed, \endMakeFramed: the "MakeFramed" environment +% \FrameCommand: command to draw the frame around its argument +% \FirstFrameCommand: the frame for the first part of a split environment +% \LastFrameCommand: for the last portion +% \MidFrameCommand: for any intermediate segments +% \FrameRestore: restore some text settings, but fewer than \@parboxrestore +% \FrameRule: length register; \fboxrule for default "framed". +% \FrameSep: length register; \fboxsep for default "framed". +% \FrameHeightAdjust: macro; height of frame above baseline at top of page +% \OuterFrameSep: vertical space before and after the framed env. Defaults to "\topsep" +% +% This is still a `pre-production' version because I can think of many +% features/improvements that should be made. Also, a detailed manual needs +% to be written. Nevertheless, starting with version 0.5 it should be bug-free. +% +% ToDo: +% Test more varieties of list +% Improve and correct documentation +% Propagation of \marks +% Handle footnotes (how??) floats (?) and marginpars. +% Stretchability modification. +% Make inner contents height/depth influence placement. +%======================== End Instructions ======================== + +\ProvidesPackage{framed}[2011/10/22 v 0.96: + framed or shaded text with page breaks] + +\newenvironment{framed}% using default \FrameCommand + {\MakeFramed {\advance\hsize-\width \FrameRestore}}% + {\endMakeFramed} + +\newenvironment{shaded}{% + \def\FrameCommand{\fboxsep=\FrameSep \colorbox{shadecolor}}% + \MakeFramed {\FrameRestore}}% + {\endMakeFramed} + +\newenvironment{shaded*}{% + \def\FrameCommand{\fboxsep=\FrameSep \colorbox{shadecolor}}% + \MakeFramed {\advance\hsize-\width \FrameRestore}}% + {\endMakeFramed} + +\newenvironment{leftbar}{% + \def\FrameCommand{\vrule width 3pt \hspace{10pt}}% + \MakeFramed {\advance\hsize-\width \FrameRestore}}% + {\endMakeFramed} + +% snugshde: Shaded environment that +% -- uses the default \fboxsep instead of \FrameSep +% -- leaves the text indent unchanged (shading bleeds out) +% -- eliminates possible internal \topsep glue (\@setminipage) +% -- shrinks inside the margins for lists +% An \item label will tend to hang outside the shading, thanks to +% the small \fboxsep. + +\newenvironment{snugshade}{% + \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep + \colorbox{shadecolor}{##1}\hskip-\fboxsep + % There is no \@totalrightmargin, so: + \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% + \MakeFramed {\advance\hsize-\width + \@totalleftmargin\z@ \linewidth\hsize + \@setminipage}% + }{\par\unskip\@minipagefalse\endMakeFramed} + +\newenvironment{snugshade*}{% + \def\FrameCommand##1{\hskip\@totalleftmargin + \colorbox{shadecolor}{##1}% + % There is no \@totalrightmargin, so: + \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% + \MakeFramed {\advance\hsize-\width + \@totalleftmargin\z@ \linewidth\hsize + \advance\labelsep\fboxsep + \@setminipage}% + }{\par\unskip\@minipagefalse\endMakeFramed} + +\newenvironment{oframed}{% open (top or bottom) framed + \def\FrameCommand{\OpenFBox\FrameRule\FrameRule}% + \def\FirstFrameCommand{\OpenFBox\FrameRule\z@}% + \def\MidFrameCommand{\OpenFBox\z@\z@}% + \def\LastFrameCommand{\OpenFBox\z@\FrameRule}% + \MakeFramed {\advance\hsize-\width \FrameRestore}% + }{\endMakeFramed} + +% A simplified entry to \CustomFBox with two customized parameters: +% the thicknesses of the top and bottom rules. Perhaps we want to +% use less \fboxsep on the open edges? + +\def\OpenFBox#1#2{\fboxsep\FrameSep + \CustomFBox{}{}{#1}{#2}\FrameRule\FrameRule} + +% \CustomFBox is like an amalgamation of \fbox and \@frameb@x, +% so it can be used by an alternate to \fbox or \fcolorbox, but +% it has more parameters for various customizations. +% Parameter #1 is inserted (in vmode) right after the top rule +% (useful for a title or assignments), and #2 is similar, but +% inserted right above the bottom rule. +% The thicknesses of the top, bottom, left, and right rules are +% given as parameters #3,#4,#5,#6 respectively. They should be +% \fboxrule or \z@ (or some other thickness). +% The text argument is #7. +% An instance of this can be used for the frame of \fcolorbox by +% locally defining \fbox before \fcolorbox; e.g., +% \def\fbox{\CustomFBox{}{}\z@\z@\fboxrule\fboxrule}\fcolorbox +% +% Do we need to use different \fboxsep on different sides too? +% +\long\def\CustomFBox#1#2#3#4#5#6#7{% + \leavevmode\begingroup + \setbox\@tempboxa\hbox{% + \color@begingroup + \kern\fboxsep{#7}\kern\fboxsep + \color@endgroup}% + \hbox{% + % Here we calculate and shift for the depth. Done in + % a group because one of the arguments might be \@tempdima + % (we could use \dimexpr instead without grouping). + \begingroup + \@tempdima#4\relax + \advance\@tempdima\fboxsep + \advance\@tempdima\dp\@tempboxa + \expandafter\endgroup\expandafter + \lower\the\@tempdima\hbox{% + \vbox{% + \hrule\@height#3\relax + #1% + \hbox{% + \vrule\@width#5\relax + \vbox{% + \vskip\fboxsep % maybe these should be parameters too + \copy\@tempboxa + \vskip\fboxsep}% + \vrule\@width#6\relax}% + #2% + \hrule\@height#4\relax}% + }% + }% + \endgroup +} + + +% A particular type of titled frame with continuation marks. +% Parameter #1 is the title, repeated on each page. +\newenvironment{titled-frame}[1]{% + \def\FrameCommand{\fboxsep8pt\fboxrule2pt + \TitleBarFrame{\textbf{#1}}}% + \def\FirstFrameCommand{\fboxsep8pt\fboxrule2pt + \TitleBarFrame[$\blacktriangleright$]{\textbf{#1}}}% + \def\MidFrameCommand{\fboxsep8pt\fboxrule2pt + \TitleBarFrame[$\blacktriangleright$]{\textbf{#1\ (cont)}}}% + \def\LastFrameCommand{\fboxsep8pt\fboxrule2pt + \TitleBarFrame{\textbf{#1\ (cont)}}}% + \MakeFramed{\advance\hsize-20pt \FrameRestore}}% +% note: 8 + 2 + 8 + 2 = 20. Don't use \width because the frame title +% could interfere with the width measurement. + {\endMakeFramed} + +% \TitleBarFrame[marker]{title}{contents} +% Frame with a label at top, optional continuation marker at bottom right. +% Frame color is TFFrameColor and title color is a contrasting TFTitleColor; +% both need to be defined before use. The frame itself use \fboxrule and +% \fboxsep. If the title is omitted entirely, the title bar is omitted +% (use a blank space to force a blank title bar). +% +\newcommand\TitleBarFrame[3][]{\begingroup + \ifx\delimiter#1\delimiter + \let\TF@conlab\@empty + \else + \def\TF@conlab{% continuation label + \nointerlineskip + \smash{\rlap{\kern\wd\@tempboxa\kern\fboxrule\kern\fboxsep #1}}}% + \fi + \let\TF@savecolor\current@color + \textcolor{TFFrameColor}{% + \CustomFBox + {\TF@Title{#2}}{\TF@conlab}% + \fboxrule\fboxrule\fboxrule\fboxrule + {\let\current@color\TF@savecolor\set@color #3}% + }\endgroup +} + +% The title bar for \TitleBarFrame +\newcommand\TF@Title[1]{% + \ifx\delimiter#1\delimiter\else + \kern-0.04pt\relax + \begingroup + \setbox\@tempboxa\vbox{% + \kern0.8ex + \hbox{\kern\fboxsep\textcolor{TFTitleColor}{#1}\vphantom{Tj)}}% + \kern0.8ex}% + \hrule\@height\ht\@tempboxa + \kern-\ht\@tempboxa + \box\@tempboxa + \endgroup + \nointerlineskip + \kern-0.04pt\relax + \fi +} + +\chardef\FrameRestore=\catcode`\| % for debug +\catcode`\|=\catcode`\% % (debug: insert space after backslash) + +\newlength\OuterFrameSep \OuterFrameSep=\maxdimen \relax + +\def\MakeFramed#1{\par + % apply default \OuterFrameSep = \topsep + \ifdim\OuterFrameSep=\maxdimen \OuterFrameSep\topsep \fi + % measure added width and height; call result \width and \height + \fb@sizeofframe\FrameCommand + \let\width\fb@frw \let\height\fb@frh + % insert pre-penalties and skips + \begingroup + \skip@\lastskip + \if@nobreak\else + \penalty9999 % updates \page parameters + \ifdim\pagefilstretch=\z@ \ifdim\pagefillstretch=\z@ + % not infinitely stretchable, so encourage a page break here + \edef\@tempa{\the\skip@}% + \ifx\@tempa\zero@glue \penalty-30 + \else \vskip-\skip@ \penalty-30 \vskip\skip@ + \fi\fi\fi + \penalty\z@ + % Give a stretchy breakpoint that will always be taken in preference + % to the \penalty 9999 used to update page parameters. The cube root + % of 10000/100 indicates a multiplier of 0.21545, but the maximum + % calculated badness is really 8192, not 10000, so the multiplier + % is 0.2301. + \advance\skip@ \z@ plus-.5\baselineskip + \advance\skip@ \z@ plus-.231\height + \advance\skip@ \z@ plus-.231\skip@ + \advance\skip@ \z@ plus-.231\OuterFrameSep + \vskip-\skip@ \penalty 1800 \vskip\skip@ + \fi + \addvspace{\OuterFrameSep}% + \endgroup + % clear out pending page break + \penalty\@M \vskip 2\baselineskip \vskip\height + \penalty9999 \vskip -2\baselineskip \vskip-\height + \penalty9999 % updates \pagetotal +|\message{After clearout, \pagetotal=\the\pagetotal, \pagegoal=\the\pagegoal. }% + \fb@adjheight + \setbox\@tempboxa\vbox\bgroup + #1% Modifications to \hsize (can use \width and \height) + \textwidth\hsize \columnwidth\hsize +} + +\def\endMakeFramed{\par + \kern\z@ + \hrule\@width\hsize\@height\z@ % possibly bad + \penalty-100 % (\hrule moves depth into height) + \egroup +%%% {\showoutput\showbox\@tempboxa}% + \begingroup + \fb@put@frame\FrameCommand\FirstFrameCommand + \endgroup + \@minipagefalse % In case it was set and not cleared +} + +% \fb@put@frame takes the contents of \@tempboxa and puts all, or a piece, +% of it on the page with a frame (\FrameCommand, \FirstFrameCommand, +% \MidFrameCommand, or \LastFrameCommand). It recurses until all of +% \@tempboxa has been used up. (\@tempboxa must have zero depth.) +% #1 = attempted framing command, if no split +% #2 = framing command if split +% First iteration: Try to fit with \FrameCommand. If it does not fit, +% split for \FirstFrameCommand. +% Later iteration: Try to fit with \LastFrameCommand. If it does not +% fit, split for \MidFrameCommand. +\def\fb@put@frame#1#2{\relax + \ifdim\pagegoal=\maxdimen \pagegoal\vsize \fi +| \message{=============== Entering putframe ====================^^J +| \pagegoal=\the\pagegoal, \pagetotal=\the\pagetotal. }% + \ifinner + \fb@putboxa#1% + \fb@afterframe + \else + \dimen@\pagegoal \advance\dimen@-\pagetotal % natural space left on page + \ifdim\dimen@<2\baselineskip % Too little room on page +| \message{Page has only \the\dimen@\space room left; eject. }% + \eject \fb@adjheight \fb@put@frame#1#2% + \else % there's appreciable room left on the page + \fb@sizeofframe#1% +| \message{\string\pagetotal=\the\pagetotal, +| \string\pagegoal=\the\pagegoal, +| \string\pagestretch=\the\pagestretch, +| \string\pageshrink=\the\pageshrink, +| \string\fb@frh=\the\fb@frh. \space} +| \message{^^JBox of size \the\ht\@tempboxa\space}% + \begingroup % temporarily set \dimen@ to be... + \advance\dimen@.8\pageshrink % maximum space available on page + \advance\dimen@-\fb@frh\relax % max space available for frame's contents +%%% LOOKS SUBTRACTED AND ADDED, SO DOUBLE ACCOUNTING! + \expandafter\endgroup + % expand \ifdim, then restore \dimen@ to real room left on page + \ifdim\dimen@>\ht\@tempboxa % whole box does fit +| \message{fits in \the\dimen@. }% + % ToDo: Change this to use vsplit anyway to capture the marks + % MERGE THIS WITH THE else CLAUSE!!! + \fb@putboxa#1% + \fb@afterframe + \else % box must be split +| \message{must be split to fit in \the\dimen@. }% + % update frame measurement to use \FirstFrameCommand or \MidFrameCommand + \fb@sizeofframe#2% + \setbox\@tempboxa\vbox{% simulate frame and flexiblity of the page: + \vskip \fb@frh \@plus\pagestretch \@minus.8\pageshrink + \kern137sp\kern-137sp\penalty-30 + \unvbox\@tempboxa}% + \edef\fb@resto@set{\boxmaxdepth\the\boxmaxdepth + \splittopskip\the\splittopskip}% + \boxmaxdepth\z@ \splittopskip\z@ +| \message{^^JPadded box of size \the\ht\@tempboxa\space split to \the\dimen@}% + % Split box here + \setbox\tw@\vsplit\@tempboxa to\dimen@ +| \toks99\expandafter{\splitfirstmark}% +| \toks98\expandafter{\splitbotmark}% +| \message{Marks are: \the\toks99, \the\toks98. }% + \setbox\tw@\vbox{\unvbox\tw@}% natural-sized +| \message{Natural height of split box is \the\ht\tw@, leaving +| \the\ht\@tempboxa\space remainder. }% + % If the split-to size > (\vsize-\topskip), then set box to full size. + \begingroup + \advance\dimen@\topskip + \expandafter\endgroup + \ifdim\dimen@>\pagegoal +| \message{Frame is big -- Use up the full column. }% + \dimen@ii\pagegoal + \advance\dimen@ii -\topskip + \advance\dimen@ii \FrameHeightAdjust\relax + \else % suspect this is implemented incorrectly: + % If the split-to size > feasible room_on_page, rebox it smaller. + \advance\dimen@.8\pageshrink + \ifdim\ht\tw@>\dimen@ +| \message{Box too tall; rebox it to \the\dimen@. }% + \dimen@ii\dimen@ + \else % use natural size + \dimen@ii\ht\tw@ + \fi + \fi + % Re-box contents to desired size \dimen@ii + \advance\dimen@ii -\fb@frh + \setbox\tw@\vbox to\dimen@ii \bgroup + % remove simulated frame and page flexibility: + \vskip -\fb@frh \@plus-\pagestretch \@minus-.8\pageshrink + \unvbox\tw@ \unpenalty\unpenalty + \ifdim\lastkern=-137sp % whole box went to next page +| \message{box split at beginning! }% + % need work here??? + \egroup \fb@resto@set \eject % (\vskip for frame size was discarded) + \fb@adjheight + \fb@put@frame#1#2% INSERTED ??? + \else % Got material split off at the head + \egroup \fb@resto@set + \ifvoid\@tempboxa % it all fit after all +| \message{box split at end! }% + \setbox\@tempboxa\box\tw@ + \fb@putboxa#1% + \fb@afterframe + \else % it really did split +| \message{box split as expected. Its reboxed height is \the\ht\tw@. }% + \ifdim\wd\tw@>\z@ + \wd\tw@\wd\@tempboxa + \centerline{#2{\box\tw@}}% ??? \centerline bad idea + \else +| \message{Zero width means likely blank. Don't frame it (guess)}% + \box\tw@ + \fi + \hrule \@height\z@ \@width\hsize + \eject + \fb@adjheight + \fb@put@frame\LastFrameCommand\MidFrameCommand + \fi\fi\fi\fi\fi +} + +\def\fb@putboxa#1{% + \ifvoid\@tempboxa + \PackageWarning{framed}{Boxa is void -- discard it. }% + \else +| \message{Frame and place boxa. }% +| %{\showoutput\showbox\@tempboxa}% + \centerline{#1{\box\@tempboxa}}% + \fi +} + +\def\fb@afterframe{% + \nointerlineskip \null %{\showoutput \showlists} + \penalty-30 \vskip\OuterFrameSep \relax +} + +% measure width and height added by frame (#1 = frame command) +% call results \fb@frw and \fb@frh +% todo: a mechanism to handle wide frame titles +\newdimen\fb@frw +\newdimen\fb@frh +\def\fb@sizeofframe#1{\begingroup + \setbox\z@\vbox{\vskip-5in \hbox{\hskip-5in + #1{\hbox{\vrule \@height 4.7in \@depth.3in \@width 5in}}}% + \vskip\z@skip}% +| \message{Measuring frame addition for \string#1 in \@currenvir\space +| gives ht \the\ht\z@\space and wd \the\wd\z@. }% +| %{\showoutput\showbox\z@}% + \global\fb@frw\wd\z@ \global\fb@frh\ht\z@ + \endgroup +} + +\def\fb@adjheight{% + \vbox to\FrameHeightAdjust{}% get proper baseline skip from above. + \penalty\@M \nointerlineskip + \vskip-\FrameHeightAdjust + \penalty\@M} % useful for tops of pages + +\edef\zero@glue{\the\z@skip} + +\catcode`\|=\FrameRestore + +% Provide configuration commands: +\providecommand\FrameCommand{% + \setlength\fboxrule{\FrameRule}\setlength\fboxsep{\FrameSep}% + \fbox} +\@ifundefined{FrameRule}{\newdimen\FrameRule \FrameRule=\fboxrule}{} +\@ifundefined{FrameSep} {\newdimen\FrameSep \FrameSep =3\fboxsep}{} +\providecommand\FirstFrameCommand{\FrameCommand} +\providecommand\MidFrameCommand{\FrameCommand} +\providecommand\LastFrameCommand{\FrameCommand} + +% Height of frame above first baseline when frame starts a page: +\providecommand\FrameHeightAdjust{6pt} + +% \FrameRestore has parts of \@parboxrestore, performing a similar but +% less complete restoration of the default layout. See how it is used in +% the "settings" argument of \MakeFrame. Though not a parameter, \hsize +% should be set to the desired total line width available inside the +% frame before invoking \FrameRestore. +\def\FrameRestore{% + \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + % \message{FrameRestore: + % \@totalleftmargin=\the \@totalleftmargin, + % \rightmargin=\the\rightmargin, + % \@listdepth=\the\@listdepth. }% + % Test if we are in a list (or list-like paragraph) + \ifnum \ifdim\@totalleftmargin>\z@ 1\fi + \ifdim\rightmargin>\z@ 1\fi + \ifnum\@listdepth>\z@ 1\fi 0>\z@ + % \message{In a list: \linewidth=\the\linewidth, \@totalleftmargin=\the\@totalleftmargin, + % \parshape=\the\parshape, \columnwidth=\the\columnwidth, \hsize=\the\hsize, + % \labelwidth=\the\labelwidth. }% + \@setminipage % snug fit around the item. I would like this to be non-global. + % Now try to propageate changes of width from \hsize to list parameters. + % This is deficient, but a more advanced way to indicate modification to text + % dimensions is not (yet) provided; in particular, no separate left/right + % adjustment. + \advance\linewidth-\columnwidth \advance\linewidth\hsize + \parshape\@ne \@totalleftmargin \linewidth + \else % Not in list + \linewidth=\hsize + %\message{No list, set \string\linewidth=\the\hsize. }% + \fi + \sloppy +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/ThirdParty/Ert/python/docs/latex/needspace.sty b/ThirdParty/Ert/python/docs/latex/needspace.sty new file mode 100644 index 0000000000..113d87216f --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/needspace.sty @@ -0,0 +1,35 @@ + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{needspace}[2010/09/12 v1.3d reserve vertical space] + +\newcommand{\needspace}[1]{% + \begingroup + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@ + \penalty -100\vskip\z@\@plus -\dimen@ + \vskip\dimen@ + \penalty 9999% + \vskip -\dimen@ + \vskip\z@skip % hide the previous |\vskip| from |\addvspace| + \endgroup +} + +\newcommand{\Needspace}{\@ifstar{\@sneedsp@}{\@needsp@}} + +\newcommand{\@sneedsp@}[1]{\par \penalty-100\begingroup + \setlength{\dimen@}{#1}% + \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal + \ifdim \dimen@>\dimen@ii + \break + \fi\endgroup} + +\newcommand{\@needsp@}[1]{\par \penalty-100\begingroup + \setlength{\dimen@}{#1}% + \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal + \ifdim \dimen@>\dimen@ii + \ifdim \dimen@ii>\z@ + \vfil + \fi + \break + \fi\endgroup} + diff --git a/ThirdParty/Ert/python/docs/latex/tabulary.sty b/ThirdParty/Ert/python/docs/latex/tabulary.sty new file mode 100644 index 0000000000..5660cdfbbe --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/tabulary.sty @@ -0,0 +1,451 @@ +%% +%% This is file `tabulary.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% tabulary.dtx (with options: `package') +%% DRAFT VERSION +%% +%% File `tabulary.dtx'. +%% Copyright (C) 1995 1996 2003 2008 David Carlisle +%% This file may be distributed under the terms of the LPPL. +%% See 00readme.txt for details. +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{tabulary} + [2014/06/11 v0.10 tabulary package (DPC)] +\RequirePackage{array} +\catcode`\Z=14 +\DeclareOption{debugshow}{\catcode`\Z=9\relax} +\ProcessOptions +\def\arraybackslash{\let\\=\@arraycr} +\def\@finalstrut#1{% + \unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1} +\newcount\TY@count +\def\tabulary{% + \let\TY@final\tabular + \let\endTY@final\endtabular + \TY@tabular} +\def\TY@tabular#1{% + \edef\TY@{\@currenvir}% + {\ifnum0=`}\fi + \@ovxx\TY@linewidth + \@ovyy\TY@tablewidth + \count@\z@ + \@tempswatrue + \@whilesw\if@tempswa\fi{% + \advance\count@\@ne + \expandafter\ifx\csname TY@F\the\count@\endcsname\relax + \@tempswafalse + \else + \expandafter\let\csname TY@SF\the\count@\expandafter\endcsname + \csname TY@F\the\count@\endcsname + \global\expandafter\let\csname TY@F\the\count@\endcsname\relax + \expandafter\let\csname TY@S\the\count@\expandafter\endcsname + \csname TY@\the\count@\endcsname + \fi}% + \global\TY@count\@ne + \TY@width\xdef{0pt}% + \global\TY@tablewidth\z@ + \global\TY@linewidth#1\relax +Z\message{^^J^^JTable^^J% +Z Target Width: \the\TY@linewidth^^J% +Z \string\tabcolsep: \the\tabcolsep\space +Z \string\arrayrulewidth: \the\arrayrulewidth\space +Z \string\doublerulesep: \the\doublerulesep^^J% +Z \string\tymin: \the\tymin\space +Z \string\tymax: \the\tymax^^J}% + \let\@classz\TY@classz + \let\verb\TX@verb + \toks@{}\TY@get@body} +\let\TY@@mkpream\@mkpream +\def\TY@mkpream{% + \def\@addamp{% + \if@firstamp \@firstampfalse \else + \global\advance\TY@count\@ne + \edef\@preamble{\@preamble &}\fi + \TY@width\xdef{0pt}}% + \def\@acol{% + \TY@subwidth\col@sep + \@addtopreamble{\hskip\col@sep}}% + \let\@arrayrule\TY@arrayrule + \let\@classvi\TY@classvi + \def\@classv{\save@decl + \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@ + \sbox\z@{\d@llarbegin\@nextchar\d@llarend}% + \TY@subwidth{\wd\z@}% + \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}% + \prepnext@tok}% + \global\let\@mkpream\TY@@mkpream + \TY@@mkpream} +\def\TY@arrayrule{% + \TY@subwidth\arrayrulewidth + \@addtopreamble \vline} +\def\TY@classvi{\ifcase \@lastchclass + \@acol \or + \TY@subwidth\doublerulesep + \@addtopreamble{\hskip \doublerulesep}\or + \@acol \or + \@classvii + \fi} +\def\TY@tab{% + \setbox\z@\hbox\bgroup + \let\[$\let\]$% + \let\equation$\let\endequation$% + \col@sep\tabcolsep + \let\d@llarbegin\begingroup\let\d@llarend\endgroup + \let\@mkpream\TY@mkpream + \def\multicolumn##1##2##3{\multispan##1\relax}% + \CT@start\TY@tabarray} +\def\TY@tabarray{\@ifnextchar[{\TY@array}{\@array[t]}} +\def\TY@array[#1]{\@array[t]} +\def\TY@width#1{% + \expandafter#1\csname TY@\the\TY@count\endcsname} +\def\TY@subwidth#1{% + \TY@width\dimen@ + \advance\dimen@-#1\relax + \TY@width\xdef{\the\dimen@}% + \global\advance\TY@linewidth-#1\relax} +\def\endtabulary{% + \gdef\@halignto{}% + \expandafter\TY@tab\the\toks@ + \crcr\omit + {\xdef\TY@save@row{}% + \loop + \advance\TY@count\m@ne + \ifnum\TY@count>\z@ + \xdef\TY@save@row{\TY@save@row&\omit}% + \repeat}\TY@save@row + \endarray\global\setbox1=\lastbox\setbox0=\vbox{\unvbox1 + \unskip\global\setbox1=\lastbox}\egroup + \dimen@\TY@linewidth + \divide\dimen@\TY@count + \ifdim\dimen@<\tymin + \TY@warn{tymin too large (\the\tymin), resetting to \the\dimen@}% + \tymin\dimen@ + \fi + \setbox\tw@=\hbox{\unhbox\@ne + \loop +\@tempdima=\lastskip +\ifdim\@tempdima>\z@ +Z \message{ecs=\the\@tempdima^^J}% + \global\advance\TY@linewidth-\@tempdima +\fi + \unskip + \setbox\tw@=\lastbox + \ifhbox\tw@ +Z \message{Col \the\TY@count: Initial=\the\wd\tw@\space}% + \ifdim\wd\tw@>\tymax + \wd\tw@\tymax +Z \message{> max\space}% +Z \else +Z \message{ \@spaces\space}% + \fi + \TY@width\dimen@ +Z \message{\the\dimen@\space}% + \advance\dimen@\wd\tw@ +Z \message{Final=\the\dimen@\space}% + \TY@width\xdef{\the\dimen@}% + \ifdim\dimen@<\tymin +Z \message{< tymin}% + \global\advance\TY@linewidth-\dimen@ + \expandafter\xdef\csname TY@F\the\TY@count\endcsname + {\the\dimen@}% + \else + \expandafter\ifx\csname TY@F\the\TY@count\endcsname\z@ +Z \message{***}% + \global\advance\TY@linewidth-\dimen@ + \expandafter\xdef\csname TY@F\the\TY@count\endcsname + {\the\dimen@}% + \else +Z \message{> tymin}% + \global\advance\TY@tablewidth\dimen@ + \global\expandafter\let\csname TY@F\the\TY@count\endcsname + \maxdimen + \fi\fi + \advance\TY@count\m@ne + \repeat}% + \TY@checkmin + \TY@checkmin + \TY@checkmin + \TY@checkmin + \TY@count\z@ + \let\TY@box\TY@box@v + {\expandafter\TY@final\the\toks@\endTY@final}% + \count@\z@ + \@tempswatrue + \@whilesw\if@tempswa\fi{% + \advance\count@\@ne + \expandafter\ifx\csname TY@SF\the\count@\endcsname\relax + \@tempswafalse + \else + \global\expandafter\let\csname TY@F\the\count@\expandafter\endcsname + \csname TY@SF\the\count@\endcsname + \global\expandafter\let\csname TY@\the\count@\expandafter\endcsname + \csname TY@S\the\count@\endcsname + \fi}% + \TY@linewidth\@ovxx + \TY@tablewidth\@ovyy + \ifnum0=`{\fi}} +\def\TY@checkmin{% + \let\TY@checkmin\relax +\ifdim\TY@tablewidth>\z@ + \Gscale@div\TY@ratio\TY@linewidth\TY@tablewidth + \ifdim\TY@tablewidth <\TY@linewidth + \def\TY@ratio{1}% + \fi +\else + \TY@warn{No suitable columns!}% + \def\TY@ratio{1}% +\fi +\count@\z@ +Z \message{^^JLine Width: \the\TY@linewidth, +Z Natural Width: \the\TY@tablewidth, +Z Ratio: \TY@ratio^^J}% +\@tempdima\z@ +\loop +\ifnum\count@<\TY@count +\advance\count@\@ne + \ifdim\csname TY@F\the\count@\endcsname>\tymin + \dimen@\csname TY@\the\count@\endcsname + \dimen@\TY@ratio\dimen@ + \ifdim\dimen@<\tymin +Z \message{Column \the\count@\space ->}% + \global\expandafter\let\csname TY@F\the\count@\endcsname\tymin + \global\advance\TY@linewidth-\tymin + \global\advance\TY@tablewidth-\csname TY@\the\count@\endcsname + \let\TY@checkmin\TY@@checkmin + \else + \expandafter\xdef\csname TY@F\the\count@\endcsname{\the\dimen@}% + \advance\@tempdima\csname TY@F\the\count@\endcsname + \fi + \fi +Z \dimen@\csname TY@F\the\count@\endcsname\message{\the\dimen@, }% +\repeat +Z \message{^^JTotal:\the\@tempdima^^J}% +} +\let\TY@@checkmin\TY@checkmin +\newdimen\TY@linewidth +\def\tyformat{\everypar{{\nobreak\hskip\z@skip}}} +\newdimen\tymin +\tymin=10pt +\newdimen\tymax +\tymax=2\textwidth +\def\@testpach{\@chclass + \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else + \ifnum \@lastchclass=7 5 \else + \ifnum \@lastchclass=8 \tw@ \else + \ifnum \@lastchclass=9 \thr@@ + \else \z@ + \ifnum \@lastchclass = 10 \else + \edef\@nextchar{\expandafter\string\@nextchar}% + \@chnum + \if \@nextchar c\z@ \else + \if \@nextchar l\@ne \else + \if \@nextchar r\tw@ \else + \if \@nextchar C7 \else + \if \@nextchar L8 \else + \if \@nextchar R9 \else + \if \@nextchar J10 \else + \z@ \@chclass + \if\@nextchar |\@ne \else + \if \@nextchar !6 \else + \if \@nextchar @7 \else + \if \@nextchar <8 \else + \if \@nextchar >9 \else + 10 + \@chnum + \if \@nextchar m\thr@@\else + \if \@nextchar p4 \else + \if \@nextchar b5 \else + \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi\fi \fi \fi\fi \fi + \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi} +\def\TY@classz{% + \@classx + \@tempcnta\count@ + \ifx\TY@box\TY@box@v + \global\advance\TY@count\@ne + \fi + \let\centering c% + \let\raggedright\noindent + \let\raggedleft\indent + \let\arraybackslash\relax + \prepnext@tok + \ifnum\@chnum<4 + \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ + \fi + \ifnum\@chnum=6 + \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ + \fi + \@addtopreamble{% + \ifcase\@chnum + \hfil \d@llarbegin\insert@column\d@llarend \hfil \or + \kern\z@ + \d@llarbegin \insert@column \d@llarend \hfil \or + \hfil\kern\z@ \d@llarbegin \insert@column \d@llarend \or + $\vcenter\@startpbox{\@nextchar}\insert@column \@endpbox $\or + \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or + \vbox \@startpbox{\@nextchar}\insert@column \@endpbox \or + \d@llarbegin \insert@column \d@llarend \or% dubious "s" case + \TY@box\centering\or + \TY@box\raggedright\or + \TY@box\raggedleft\or + \TY@box\relax + \fi}\prepnext@tok} +\def\TY@box#1{% + \ifx\centering#1% + \hfil \d@llarbegin\insert@column\d@llarend \hfil \else + \ifx\raggedright#1% + \kern\z@%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + \d@llarbegin \insert@column \d@llarend \hfil \else + \ifx\raggedleft#1% + \hfil\kern\z@ \d@llarbegin \insert@column \d@llarend \else + \ifx\relax#1% + \d@llarbegin \insert@column \d@llarend + \fi \fi \fi \fi} +\def\TY@box@v#1{% + \vtop \@startpbox{\csname TY@F\the\TY@count\endcsname}% + #1\arraybackslash\tyformat + \insert@column\@endpbox} +\newdimen\TY@tablewidth +\def\Gscale@div#1#2#3{% + \setlength\dimen@{#3}% + \ifdim\dimen@=\z@ + \PackageError{graphics}{Division by 0}\@eha + \dimen@#2% + \fi + \edef\@tempd{\the\dimen@}% + \setlength\dimen@{#2}% + \count@65536\relax + \ifdim\dimen@<\z@ + \dimen@-\dimen@ + \count@-\count@ + \fi + \loop + \ifdim\dimen@<8192\p@ + \dimen@\tw@\dimen@ + \divide\count@\tw@ + \repeat + \dimen@ii=\@tempd\relax + \divide\dimen@ii\count@ + \divide\dimen@\dimen@ii + \edef#1{\strip@pt\dimen@}} +\long\def\TY@get@body#1\end + {\toks@\expandafter{\the\toks@#1}\TY@find@end} +\def\TY@find@end#1{% + \def\@tempa{#1}% + \ifx\@tempa\TY@\def\@tempa{\end{#1}}\expandafter\@tempa + \else\toks@\expandafter + {\the\toks@\end{#1}}\expandafter\TY@get@body\fi} +\def\TY@warn{% + \PackageWarning{tabulary}} +\catcode`\Z=11 +\AtBeginDocument{ +\@ifpackageloaded{colortbl}{% +\expandafter\def\expandafter\@mkpream\expandafter#\expandafter1% + \expandafter{% + \expandafter\let\expandafter\CT@setup\expandafter\relax + \expandafter\let\expandafter\CT@color\expandafter\relax + \expandafter\let\expandafter\CT@do@color\expandafter\relax + \expandafter\let\expandafter\color\expandafter\relax + \expandafter\let\expandafter\CT@column@color\expandafter\relax + \expandafter\let\expandafter\CT@row@color\expandafter\relax + \expandafter\let\expandafter\CT@cell@color\expandafter\relax + \@mkpream{#1}} +\let\TY@@mkpream\@mkpream +\def\TY@classz{% + \@classx + \@tempcnta\count@ + \ifx\TY@box\TY@box@v + \global\advance\TY@count\@ne + \fi + \let\centering c% + \let\raggedright\noindent + \let\raggedleft\indent + \let\arraybackslash\relax + \prepnext@tok +\expandafter\CT@extract\the\toks\@tempcnta\columncolor!\@nil + \ifnum\@chnum<4 + \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ + \fi + \ifnum\@chnum=6 + \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ + \fi + \@addtopreamble{% + \setbox\z@\hbox\bgroup\bgroup + \ifcase\@chnum + \hskip\stretch{.5}\kern\z@ + \d@llarbegin\insert@column\d@llarend\hskip\stretch{.5}\or + \kern\z@%<<<<<<<<<<<<<<<<<<<<<<<<<<< + \d@llarbegin \insert@column \d@llarend \hfill \or + \hfill\kern\z@ \d@llarbegin \insert@column \d@llarend \or + $\vcenter\@startpbox{\@nextchar}\insert@column \@endpbox $\or + \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or + \vbox \@startpbox{\@nextchar}\insert@column \@endpbox \or + \d@llarbegin \insert@column \d@llarend \or% dubious s case + \TY@box\centering\or + \TY@box\raggedright\or + \TY@box\raggedleft\or + \TY@box\relax + \fi + \egroup\egroup +\begingroup + \CT@setup + \CT@column@color + \CT@row@color + \CT@cell@color + \CT@do@color +\endgroup + \@tempdima\ht\z@ + \advance\@tempdima\minrowclearance + \vrule\@height\@tempdima\@width\z@ +\unhbox\z@ +}\prepnext@tok}% + \def\TY@arrayrule{% + \TY@subwidth\arrayrulewidth + \@addtopreamble{{\CT@arc@\vline}}}% + \def\TY@classvi{\ifcase \@lastchclass + \@acol \or + \TY@subwidth\doublerulesep + \ifx\CT@drsc@\relax + \@addtopreamble{\hskip\doublerulesep}% + \else + \@addtopreamble{{\CT@drsc@\vrule\@width\doublerulesep}}% + \fi\or + \@acol \or + \@classvii + \fi}% +}{% +\let\CT@start\relax +} +} +{\uccode`\*=`\ % +\uppercase{\gdef\TX@verb{% + \leavevmode\null\TX@vwarn + {\ifnum0=`}\fi\ttfamily\let\\\ignorespaces + \@ifstar{\let~*\TX@vb}{\TX@vb}}}} +\def\TX@vb#1{\def\@tempa##1#1{\toks@{##1}\edef\@tempa{\the\toks@}% + \expandafter\TX@v\meaning\@tempa\\ \\\ifnum0=`{\fi}}\@tempa!} +\def\TX@v#1!{\afterassignment\TX@vfirst\let\@tempa= } +\begingroup +\catcode`\*=\catcode`\# +\catcode`\#=12 +\gdef\TX@vfirst{% + \if\@tempa#% + \def\@tempb{\TX@v@#}% + \else + \let\@tempb\TX@v@ + \if\@tempa\space~\else\@tempa\fi + \fi + \@tempb} +\gdef\TX@v@*1 *2{% + \TX@v@hash*1##\relax\if*2\\\else~\expandafter\TX@v@\fi*2} +\gdef\TX@v@hash*1##*2{*1\ifx*2\relax\else#\expandafter\TX@v@hash\fi*2} +\endgroup +\def\TX@vwarn{% + \@warning{\noexpand\verb may be unreliable inside tabularx/y}% + \global\let\TX@vwarn\@empty} +\endinput +%% +%% End of file `tabulary.sty'. diff --git a/ThirdParty/Ert/python/docs/latex/titlesec.sty b/ThirdParty/Ert/python/docs/latex/titlesec.sty new file mode 100644 index 0000000000..ab4d0177cc --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/titlesec.sty @@ -0,0 +1,1349 @@ +% +--------------------------------------------------+ +% | Typeset titlesec.tex to get the documentation. | +% +--------------------------------------------------+ +% +% Copyright (c) 1998-2016 by Javier Bezos. +% All Rights Reserved. +% +% This file is part of the titlesec distribution release 2.10.1 +% ----------------------------------------------------------- +% +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2003/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% The Current Maintainer of this work is Javier Bezos. +% +% Notes +% ~~~~~ +% +% The following tags are used: +% ttl@ : the generic tag used through the style +% ttlh@ : a shape definition +% ttlf@ : a macro containing the title format +% ttls@ : id. the title space +% ttlp@ : page key related macros +% ttll@ : level number +% +% The ttlf@ and ttls@ contains data in the form {..}{..}. +% Perhaps in future releases they should be converted +% to a prop-like list, similar to that proposed by the +% latex team. +% +% Admittedly, the current implementation seems too +% complicated, but that's necessary in order to provide +% certain compatibility with the sections as defined by the +% used class. Other packages opt for providing the sections +% as defined by standard classes ignoring the class; for +% instance sectsty which does a simple task in a simple and +% nice way. However, that was not my goal. +% +% Release +% ~~~~~~~ + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{titlesec}[2016/03/15 v2.10.1 Sectioning titles] + +% Initialization +% ~~~~~~~~~~~~~~ + +\newif\ifttl@ps +\ttl@psfalse + +% The \ttl@label switch is used when printing the label in titles. +% A numberless variant makes it to true. +% There is a \ttl@toclabel as well, which is true iff the +% title is numbered; used in toc entries (except default part +% and chapter) and marks (only in titlesec pagestyles). + +\newif\ifttl@label +\newif\ifttl@toclabel + +\newbox\ttl@box + +% A provision for the report style: + +\@ifundefined{if@mainmatter} + {\let\if@mainmatter\iftrue}{} + +\@ifundefined{if@openright} + {\let\if@openright\iftrue}{} + +% and the ams styles as well + +\@ifundefined{@chapapp} + {\let\@chapapp\chaptername}{} + +\def\ttl@trylist{\ttl@try{}} + +\def\ttl@getkeys#1#2{% + \if\expandafter @\@gobble#1@\@empty + \edef\ttl@b{\expandafter\@gobble\string#1}% + \let\ttl@a\ttl@b + \else + \makeatletter + \edef\ttl@d{% + \noexpand\input{ttlkeys.def}% + \catcode`\noexpand\@=\the\catcode`\@}% + \ttl@d + \ttl@getkeys{#1}{#2}% + \fi} + +% A more meaningful error for \@notdefinable + +\expandafter\AtEndOfPackage\expandafter{\expandafter + \gdef\expandafter\@notdefinable\expandafter{\@notdefinable}} + +\def\@notdefinable{% + \PackageError{titlesec}% + {Incompatible package}% + {Titlesec cannot continue defining its own macros + because\MessageBreak + \@backslashchar\reserved@a\space is already used by other package, + the class\MessageBreak + or the document.}} + +% +-----------------+ +% | C L A S S E S | +% +-----------------+ + +\def\ttl@useclass#1#2{% + \@ifstar + {\ttl@labelfalse#1{#2}[]}% + {\ttl@labeltrue\@dblarg{#1{#2}}}} + +\def\ttl@straightclass{\ttl@useclass\ttl@straight@i} +\def\ttl@partclass{\ttl@useclass\ttl@part@i} +\def\ttl@topclass{\ttl@useclass\ttl@top@i} +\def\ttl@pageclass{\ttl@useclass\ttl@page@i} + +% Here \scantokens is used to make sure the unescaped name +% has `letters' and no `others'. Mainly for hyperref, so there +% should be no problems. + +\newcommand\titleclass[1]{% + \edef\ttl@a{\expandafter\@gobble\string#1}% + \ifx\scantokens\@undefined\else + \scantokens\expandafter{\expandafter + \def\expandafter\ttl@a\expandafter{\ttl@a}}% + \fi + \@ifnextchar[{\@tempswatrue\ttl@class@i{#1}}% + {\@tempswafalse\ttl@class@ii{#1}}} + +\def\ttl@class@i#1[#2]{% + \@namedef{ttll@\ttl@a}{#2}% + \expandafter\providecommand\csname\ttl@a title\endcsname{}%%%% + \@ifundefined{ttl@toplevel}{}% + {\expandafter\let\csname ttlss@\ttl@a\expandafter\endcsname + \csname ttlss@\ttl@toplevel\endcsname}% + \edef\ttl@toplevel{\ttl@a}% + \ttl@class@ii{#1}} + +\def\ttl@class@ii#1#2{% + \@ifundefined{ttl@#2class}% + {\PackageError{titlesec}{Unknown sectioning class}% + {Valid names are top, page and straight}}% + {\expandafter\let\csname ttl@compat\ttl@a\endcsname\relax + \@ifundefined{\ttl@a mark}% + {\@namedef{\ttl@a mark}{\@gobble}}% + {}% + \edef#1{% + \expandafter\noexpand\csname ttl@#2class\endcsname{\ttl@a}}}% + \if@tempswa + \expandafter\@gobble + \else + \expandafter\@firstofone + \fi + {\@ifnextchar[% + {\ttl@class@iii}% + {\@ifundefined{ttll@\ttl@a}% + {\PackageError{titlesec}{Unknown sectioning level}% + {\string\titleclass\space with no optional arguments\MessageBreak + only changes the class of an *existing* level}}}}} + +\def\ttl@class@iii[#1]{% + \edef\ttl@b{\expandafter\@gobble\string#1}% + \expandafter\let\csname ttlss@\ttl@a\expandafter\endcsname + \csname ttlss@\ttl@b\endcsname + \expandafter\edef\csname ttlss@\ttl@b\endcsname{\ttl@a}% + \let\ttl@a\ttl@toplevel + \count@\csname ttll@\ttl@toplevel\endcsname + \ttl@class@iv} + +\def\ttl@class@iv{% + \@ifundefined{ttlss@\ttl@a}{}% + {\advance\count@\@ne + \edef\ttl@a{\csname ttlss@\ttl@a\endcsname}% + \expandafter\edef\csname ttll@\ttl@a\endcsname{\the\count@}% + \ttl@class@iv}} + +% Typesetting Classes: General tools +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% The following command handles the *n spacing +% Some tricks are necessary to multiply a +% skip by a non integer number + +\newskip\beforetitleunit +\beforetitleunit=1ex\@plus.3ex\@minus.06ex +\newskip\aftertitleunit +\aftertitleunit=1ex\@plus.1ex + +\newdimen\ttl@plus +\newdimen\ttl@minus + +\def\ttl@assign#1{% + \@ifstar + {\ttl@assign@i{#1}}% + {\ttl@assign@d{#1}}} + +\def\ttl@assign@i#1#2\relax#3{% + \ttl@plus\z@ + \ttl@minus\z@ + \afterassignment\ttl@assign@ii + \dimen@\the#3, % <- space + #1 = #2\dimen@ + plus #2\ttl@plus + minus #2\ttl@minus} + +\def\ttl@assign@ii#1 {% <- space + \if#1,\else\afterassignment\ttl@assign@ii\fi + \csname ttl@\string#1\endcsname} + +\def\ttl@assign@d#1#2\relax#3{\setlength#1{#2}} + +% To be used with \v/vspace to make them calc-savvy + +\def\ttl@calc#1#2{% + {\setlength\@tempskipa{#2}% + #1\@tempskipa}} + +\def\ttl@calcneg#1#2{% + {\setlength\@tempskipa{#2}% + #1{-\@tempskipa}}} + +% Gets from ttls@ and passes the spacing parameters: + +\def\ttl@startargs#1#2{% Get the first arguments, with the spacing + \@ifundefined{ttlp@#2}% + {\let\ttl@key@page\@empty}% + {\ttlp@fetch{#2}}% + \begingroup + \def\ttl@b{ttls@#2}% + \edef\ttl@key@numberless{\ifttl@label//\else/*\fi}% + \def\ttl@a##1{\csname ttl@key@##1\endcsname}% Used as elt in try + \ttl@trylist + \xdef\ttl@b{\ttl@c}% + \endgroup + \ifx\ttl@b\@empty + \PackageError{titlesec}{Format/spacing not found}% + {I was unable to find the format corresponding to #2.\MessageBreak + Maybe you haven't set it with \string\titleformat\space and + \string\titlespacing} + \fi + \expandafter#1\ttl@b{#2}} + +% Used in ttl@select + +\def\ttl@savefn#1[#2]#3{% + \ifcase#1% + \footnotemark[#2]% + \gdef\ttl@fn{\footnotetext[#2]{#3}}% + \else + \footnotemark + \gdef\ttl@fn{\footnotetext{#3}}% + \fi} + +\def\ttl@nest@error{% + \PackageError{titlesec}{Nested titles}{Titles must not be nested}} + +\def\ttl@hmode@error{% + \PackageError{titlesec}{Entered in horizontal mode} + {The argument cannot contain horizontal material\MessageBreak + such as text, \string\noindent, \string\makebox, etc.}} + +% \ttl@select not only selects the right version to be +% used. It also take steps to ensure that a mark +% is not lost inside a box by saving it into \ttl@mk, +% which in turn is used by the sect and chap commands. + +\newif\ifttl@explicit + +\def\ttl@gmk#1{\gdef\ttl@mk{#1}} + +\def\ttl@select#1#2#3#4{% + \ttl@Hy@saveanchor + \global\let\ttl@mk\@empty % global because of rigidchapters + \global\let\ttl@fn\@empty + \begingroup + \if@inlabel\else % Keep item's \everypar + \everypar{\setbox\z@\lastbox\strut}% + \fi + \let\ttl@straight@i\ttl@nest@error + \let\ttl@top@i \ttl@nest@error + \let\ttl@part@i \ttl@nest@error + \let\ttl@page@i \ttl@nest@error + \let\ttl@newpage\newpage + \def\newpage{\ttl@savewrite\ttl@newpage}% + \def\markboth##1##2{\protect\ttl@gmk{\protect\markboth{##1}{##2}}}% + \def\markright##1{\protect\ttl@gmk{\protect\markright{##1}}}% + \def\@mkboth##1##2{\protect\ttl@gmk{\protect\@mkboth{##1}{##2}}}% + \def\footnote{\@ifnextchar[% + {\ttl@savefn\z@}{\ttl@savefn\@ne[]}}% + \edef\ttl@key@numberless{\ifttl@label//\else/*\fi}% + \def\ttl@b{ttlf@#1}% + \def\ttl@a##1{\csname ttl@key@##1\endcsname}% Used as elt in try + \ttl@trylist + \ifttl@explicit + \def\ttl@passexplicit{\ttl@case{#4}}% + \ttl@c{#4}{#2}{#3}{}% ttl@c is returned by ttl@try with ttlf@... + \else + \let\ttl@passexplicit\ttl@case + \ttl@c{#2}{#3}{#4}% ttl@c is returned by ttl@try with ttlf@... + \fi + \endgroup} + +\let\ttl@savewrite\@empty + +\def\ttl@finmarks{% + \ttl@savewrite + \ttl@mk % Contains a possible mark, returned by \ttl@select + \ttl@fn} % And a footnote + +\def\ttl@try#1{% + \edef\ttl@c{#1}% #1 is a list in the form \ttl@a{key}\ttl@a{key} + \@ifundefined{\ttl@b\ttl@c}{}{% + \edef\ttl@c{\expandafter\noexpand\csname\ttl@b\ttl@c\endcsname}% + \def\ttl@a##1{\csname ttl@extra@##1\endcsname}% + #1% + \let\ttl@try\@gobble}} % locally modified to `break' testings + +% \ttl@write writes marks and toc. tocdepth is taken care of when +% the toc is typesetted and not here. Used always through +% ttl@savewrite, which is reset to \@empty to avoid duplicated +% calls. + +\def\ttl@write#1#2{% + \ttl@blinemarks + \csname#1mark\endcsname{#2}% + \def\ttl@a{\protect\numberline{\@nameuse{the#1}}}% + \@nameuse{ttl@toc#1}% eg, \ttl@tocpart modifies \ttl@a + \ttl@addcontentsline{#1}{#2}% Depends on toctitles, uses \ttl@a + \ttl@elinemarks + \global\ttl@toclabelfalse + \global\let\ttl@savewrite\@empty} + +\newif\ifttl@premark % to be used in ttlps.def +\ttl@premarkfalse + +\def\ttl@premark#1#2{% + \protected@xdef\ttl@prevmarks{\ttl@marks}% + \ttl@blinemarks + \csname#1mark\endcsname{#2}% + \ttl@elinemarks + \gdef\ttl@prevmarks{\ttl@marks}} + +% Must be preceded by a default \ttl@savewrite, which is used +% in starred variants--\@empty in top and straight classes. +% In straight class, it is preceded by the setting of +% prev marks to provide a "fixed" top mark. Otherwise, +% the default prev mark (= curr mark) is used (restored +% after ttl@labelling in straight). This is the command +% to be hacked if you want to change the behaviour of +% starred variants. + +\def\ttl@labelling#1#2{% + \let\ttl@Hy@saveanchor\@empty + \ifttl@label % 1st - if star + \def\ttl@savewrite{\ttl@write{#1}{#2}}% + \@nameuse{ttl@#1label}% eg, sets if mainmatter in chapter. + \ifttl@label % 2nd - eg, if not main matter + \ifnum\@nameuse{ttll@#1}>\c@secnumdepth\relax + \ttl@labelfalse % 3rd - if too deep + \else + \ttl@Hy@refstepcounter{#1}% + \@nameuse{ttl@#1out}% + \fi + \fi + \fi + \let\ifttl@toclabel\ifttl@label + \ifx\ttl@savewrite\@empty\else % If marks + \ifttl@ps + \ifttl@premark + \global\ttl@premarkfalse + \else % if no \pretitlemark + \ttl@premark{#1}{#2}% + \fi + \fi + \ifttl@label\else\ttl@Hy@steplink{#1}\fi + \fi} + +% Executed by ttl@labelling if the name of section is chapter: + +\def\ttl@chapterlabel{\if@mainmatter\else\ttl@labelfalse\fi} + +% Executed by ttl@labelling if chapter has a number. Note +% you can define messages for other sectioning levels (eg, +% \ttl@sectionout). + +\def\ttl@chapterout{\typeout{\chaptertitlename\space\thechapter.}} + +% Straight class +% ~~~~~~~~~~~~~ +% Default for nobottomtitles. Changed by nobottomtitles* + +\def\ttl@addstretch{\advance\@tempskipa-\pagestretch} + +% 1:name 2:level 3:indent 4:before 5:after 6:afind [7]:cap 8:title +% The second argument of ttl@sect is the level, which +% is empty if the star version is used. In this case +% neither the toc nor the marks are written. + +\def\ttl@straight@i#1[#2]#3{% + \def\@currentlabelname{#2}% for nameref + \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}% + \let\ttl@savewrite\@empty + \def\ttl@savetitle{#3}% + \gdef\thetitle{\csname the#1\endcsname}% + \if@noskipsec \leavevmode \fi + \par + \ttl@labelling{#1}{#2}% + \ttl@startargs\ttl@straight@ii{#1}{#3}} + +% 1:left 2:right 3:before 4:after 5:afterindent 6:name 7:title + +\def\ttl@straight@ii#1#2#3#4#5#6#7{% + \ttl@assign\@tempskipa#3\relax\beforetitleunit + \@ifundefined{ttl@ps@#6}{}% + {\PackageWarning{titlesec}{Page style in straight class ignored}}% + \if@nobreak + \ttl@titlespace{\@tempskipa}% + \else + \@ifundefined{#6break}% + {\addpenalty{\@secpenalty}}% + {\csname#6break\endcsname}% + \addvspace{\@tempskipa}% + \ifdim\bottomtitlespace<\z@ + \else + \begingroup + \@tempskipb\pagegoal + \@tempskipa\pagegoal + \ttl@addstretch % \relax if nobottomtitle* + \advance\@tempskipa-\bottomtitlespace\relax % not a register + \pagegoal\@tempskipa + \def\@textbottom{\vskip\z@\@plus.0001fil}% + \penalty9999 + \pagegoal\@tempskipb + \endgroup + \fi + \fi + \@afterindenttrue + \ifcase#5 \@afterindentfalse\fi + \ttl@assign\@tempskipb#4\relax\aftertitleunit + \ttl@select{#6}{#1}{#2}{#7}% + \ttl@finmarks + \@ifundefined{ttlp@#6}{}{\ttlp@write{#6}}% + \if@noskipsec + \global\@nobreakfalse + \everypar{% + \if@noskipsec + \global\@noskipsecfalse + \clubpenalty\@M + \hskip-\parindent + \begingroup + \@svsechd\unskip{\hspace{\@tempskipb}}% + \endgroup + \else + \clubpenalty\@clubpenalty\everypar{}% + \fi}% + \else + \par\nobreak + \vspace{\@tempskipb}% + \@afterheading + \fi + \ignorespaces} + +% Part class +% ~~~~~~~~~~ + +\providecommand\partmark[1]{\markboth{}{}} + +\def\ttl@part@i#1[#2]#3{% + \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}% + \ifx\ttl@notocparts\@undefined + \def\ttl@savewrite{\ttl@write{#1}{#3}}% Not #2! + \else + \let\ttl@savewrite\@empty + \fi + \def\ttl@savetitle{#3}% + \ttl@labelling{#1}{#2}% + \ttl@startargs\ttl@part@ii{#1}{#3}} + +\def\ttl@part@ii#1#2#3#4#5#6#7{% + \ttl@assign\@tempskipa#3\relax\beforetitleunit + \vspace*{\@tempskipa}% + \@ifundefined{ttl@ps@#6}{}% + {\PackageWarning{titlesec}{Page style in part class ignored}}% + \global\@afterindenttrue + \ifcase#5 \global\@afterindentfalse \fi + \ttl@assign\@tempskipb#4\relax\aftertitleunit + \ttl@select{#6}{#1}{#2}{#7}% + \ttl@finmarks + \@ifundefined{ttlp@#6}{}{\ttlp@write{#6}}% + \par\nobreak + \vspace{\@tempskipb}% + \@afterheading} + +% Page class +% ~~~~~~~~~~ + +\def\ttl@page@i#1[#2]#3{% + \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}% + \ifx\ttl@notocparts\@undefined + \def\ttl@savewrite{\ttl@write{#1}{#3}}% Not #2! + \else + \let\ttl@savewrite\@empty + \fi + \def\ttl@savetitle{#3}% + \ttl@labelling{#1}{#2}% + \ttl@startargs\ttl@page@ii{#1}{#3}} + +\def\ttl@page@ii#1#2#3#4#5#6#7{% + \ttl@assign\@tempskipa#3\relax\beforetitleunit + \if@openright + \cleardoublepage + \else + \clearpage + \fi + \@ifundefined{ttl@ps@#6}% + {\thispagestyle{plain}}% + {\thispagestyle{\@nameuse{ttl@ps@#6}}}% + \if@twocolumn + \onecolumn + \@tempswatrue + \else + \@tempswafalse + \fi + \vspace*{\@tempskipa}% + \@afterindenttrue + \ifcase#5 \@afterindentfalse\fi + \ttl@assign\@tempskipb#4\relax\aftertitleunit + \ttl@select{#6}{#1}{#2}{#7}% + \ttl@finmarks + \@ifundefined{ttlp@#6}{}{\ttlp@write{#6}}% + \vspace{\@tempskipb}% + \newpage + \if@twoside + \if@openright + \null + \@ifundefined{ttl@ps@#6}% + {\thispagestyle{empty}}% + {\thispagestyle{\@nameuse{ttl@ps@#6}}}% + \newpage + \fi + \fi + \if@tempswa + \twocolumn + \fi + \ignorespaces} + +% Top class and some makechapterhead stuff +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% +% \ttl@mkchap is the new make(s)chapterhead. + +\def\ttl@mkchap#1#2#3#4#5#6#7{% + \gdef\ttl@savemark{\csname#6mark\endcsname{#7}}% + \let\ttl@savewrite\@empty + \let\ttl@Hy@saveanchor\@empty + \@ifundefined{ttl@ps@#6}{}% + {\thispagestyle{\@nameuse{ttl@ps@#6}}}% + \let\ifttl@toclabel\ifttl@label + \ttl@mkchap@i{#1}{#2}{#3}{#4}{#5}{#6}{#7}} + +% But \ttl@mkchap@i is used by both makechapterhead and +% the top class. + +\def\ttl@mkchap@i#1#2#3#4#5#6#7{% + \ttl@assign\@tempskipa#3\relax\beforetitleunit + \vspace*{\@tempskipa}% + \global\@afterindenttrue + \ifcase#5 \global\@afterindentfalse\fi + \ttl@assign\@tempskipb#4\relax\aftertitleunit + \ttl@topmode{\@tempskipb}{% + \ttl@select{#6}{#1}{#2}{#7}}% + \ttl@finmarks % Outside the box! + \@ifundefined{ttlp@#6}{}{\ttlp@write{#6}}} + +\def\ttl@top@i#1[#2]#3{% + \gdef\ttl@savemark{\csname#1mark\endcsname{#3}}% + \let\ttl@savewrite\@empty + \def\ttl@savetitle{#3}% + \ttl@labelling{#1}{#2}% + \ttl@startargs\ttl@top@ii{#1}{#3}} + +\def\ttl@top@ii#1#2#3#4#5#6#7{% + \@ifundefined{#6break}% + {\if@openright + \cleardoublepage + \else + \clearpage + \fi}% + {\csname#6break\endcsname}% + \@ifundefined{ttl@ps@#6}% + {\thispagestyle{plain}}% + {\thispagestyle{\@nameuse{ttl@ps@#6}}}% + \global\@topnum\z@ + \@ifundefined{#6tolists}% + {\addtocontents{lof}{\protect\ttl@tocsep}% + \addtocontents{lot}{\protect\ttl@tocsep}} + {\@nameuse{#6tolists}}% + \if@twocolumn + \@topnewpage[\ttl@mkchap@i{#1}{#2}{#3}{#4}{#5}{#6}{#7}]% + \else + \ttl@mkchap@i{#1}{#2}{#3}{#4}{#5}{#6}{#7}% + \@afterheading + \fi + \ignorespaces} + + +% \def\ttl@noskipsectrue{% +% \if@noskipsec +% \PackageError{titlesec}{Invalid shape for top class}% +% {The selected shape only makes sense when merged into\MessageBreak +% a paragraph. That is impossible in the top class}% +% \else + +\newcommand\chaptertitlename{\@chapapp} +\def\ttl@tocsep{\addvspace{10\p@}} + +% +-----------------+ +% | S H A P E S | +% +-----------------+ +% +% % Reformatting Titles: Interface +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +% The surrounding space is stored in a macro +% named \ttls@

whose content is +% {left}{right}{before}{after}{afterindent}. +% But if there is the page key, the name is +% \ttls@
/ + +\newcommand\titlespacing{% + \@ifstar{\ttl@spacing@i{\z@}}{\ttl@spacing@i{\@ne}}} + +\def\ttl@spacing@i#1#2#3#4#5{% + \ttl@getkeys{#2}{titlesec}% + \@ifnextchar[{% + \ttl@spacing@ii{#1}{#3}{#4}{#5}% + }{% + \ttl@spacing@ii{#1}{#3}{#4}{#5}[\z@]}} + +\def\ttl@spacing@ii#1#2#3#4[#5]{% + \expandafter\def\csname ttls@\ttl@a\endcsname + {{#2}{#5}{#3}{#4}{#1}}} + +% The section name is built in \ttl@a. +% The format is stored in a macro named \ttlf@
, +% or \ttlf@
/ if there is the page spec, +% or \ttlf@.../* if numberless is true +% whose content is +% \ttl@{format}{label}{sep}{before}{after} + +\newtoks\ttl@toksa + +\newcommand\titleformat{% + \@ifstar{\ttl@format@s}% + {\ttl@format@i}} + +\def\ttl@format@s#1#2{% + \edef\ttl@a{\expandafter\@gobble\string#1}% + \@ifundefined{ttlf@\ttl@a}% + {\PackageError{titlesec}{Not allowed in `easy' settings} + {The sectiong command you are trying to redefine\MessageBreak + is not handled by the starred variant (eg, \string\part)}}{} + \expandafter\expandafter\expandafter + \ttl@format@si\csname ttlf@\ttl@a \endcsname + {#2}} + +\def\ttl@format@si#1#2#3#4#5#6#7{% + \@namedef{ttlf@\ttl@a}{#1{#7}{#3}{#4}{#5}{#6}}} + +\def\ttl@format@i#1{% + \@ifnextchar[{\ttl@format@ii{#1}}{\ttl@format@ii{#1}[hang]}} + +\def\ttl@format@ii#1[#2]#3#4#5#6{% + \ttl@getkeys{#1}{titlesec}% + \ttl@toksa{{#3}{#4}{#5}{#6}}% Save arguments + \@ifnextchar[{% + \ttl@format@iii{#2}% + }{% + \ttl@format@iii{#2}[]}} + +% First, we get the shape -- if not defined it loads +% the corresponding file. + +\def\ttl@format@iii#1[#2]{% + \@ifundefined{ttlh@#1}{% + \begingroup + \makeatletter + \InputIfFileExists{#1.tss}{}{% + \PackageError{titlesec}{Unknown shape}% + {Shapes are defined in files with extension tss\MessageBreak + Either you have misspelled the shape\MessageBreak + or there is no a #1.tss file}}% + \endgroup}{}% + \@temptokena{#2}% + \ifttl@explicit + \edef\ttl@b{% + \def\expandafter\noexpand\csname ttlf@\ttl@a\endcsname####1% + {\expandafter\noexpand\csname ttlh@#1\endcsname + \the\ttl@toksa{\the\@temptokena}}}% + \else + \edef\ttl@b{% + \def\expandafter\noexpand\csname ttlf@\ttl@a\endcsname + {\expandafter\noexpand\csname ttlh@#1\endcsname + \the\ttl@toksa{\the\@temptokena}}}% + \fi + \ttl@b + \csname ttl@compat\ttl@a\endcsname} + +% Styles +% ~~~~~~ + +% 1:global 2:label 3:sep 4:style 5:after 6:left 7:right 8:title +% \ttl@ and \ttlh@ take the following eight +% arguments: +% {format}{label}{sep}{before}{after}{left}{right}{title} +% where before and after refer to the format. +% With the option explicit, #4 contains the title and #8 is +% empty. + +\def\ttlh@display#1#2#3#4#5#6#7#8{% + \gdef\ttl@makeline##1{\ttl@calc\hspace{#6}##1\ttl@calc\hspace{#7}}% + \setlength\leftskip{#6}% + \setlength\rightskip{#7}% + \interlinepenalty\@M + \ttl@changecentercr + \ttl@beginlongest + #1\ifhmode\ttl@hmode@error\fi + \ttl@glcmds + \parindent\z@ + \ifttl@label + {#2\strut\@@par}\nobreak\ttl@calc\vspace{#3}% + \fi + #4{#8}% + \kern\z@\strut\@@par + \nobreak\ttl@midlongest#5\@@par + \ttl@endlongest} + +\def\ttlh@hang#1#2#3#4#5#6#7#8{% + \gdef\ttl@makeline##1{\ttl@calc\hspace{#6}##1\ttl@calc\hspace{#7}}% + \setlength\leftskip{#6}% + \setlength\rightskip{#7}% + \interlinepenalty\@M + \ttl@changecentercr + \ttl@beginlongest + #1{\ifhmode\ttl@hmode@error\fi + \ttl@glcmds + \parindent\z@ + \begingroup + \ifttl@label + \sbox\z@{#2\strut\ttl@calc\hspace{#3}}% + \hangindent\wd\z@ + \noindent\box\z@ + \fi + #4{#8}% + \kern\z@\strut\@@par + \endgroup + \nobreak\ttl@midlongest#5\@@par}% + \ttl@endlongest} + +\def\ttlh@runin#1#2#3#4#5#6#7#8{% + \global\@noskipsectrue + \gdef\ttl@makeline##1{##1}% + \ttl@changecentercr + #1{\ifhmode\ttl@hmode@error\fi + \global\sbox\ttl@box{% + \ttl@calc\hspace{#6}% + \ifttl@label{\strut#2}\ttl@calc\hspace{#3}\fi + #4{#8}#5\unskip}}% + \gdef\@svsechd{\unhbox\ttl@box}} + +% +-----------------+ +% | T O O L S | +% +-----------------+ +% +% calcwidth +% ~~~~~~~~~ +% Implemented after code from soul (but much modified...) + +\newdimen\titlewidth +\newdimen\titlewidthlast +\newdimen\titlewidthfirst + +\let\ttl@glcmds\relax +\let\ttl@beginlongest\@empty +\let\ttl@midlongest\@empty +\let\ttl@endlongest\@empty +\let\iftitlemeasuring\@secondoftwo + +\def\ttl@xbeginlongest#1\ttl@endlongest{% + \titlewidth\z@ + \titlewidthlast\z@ + \let\iftitlemeasuring\@firstoftwo + \setbox\ttl@box\vbox{% + \def\ttl@glcmds{% + \def\\{\@ifstar{\@ifnextchar[{\ttl@bs}{\newline}}% + {\@ifnextchar[{\ttl@bs}{\newline}}}% + \def\ttl@bs[####1]{\newline}% + \let\@centercr\\% + \def\ttl@midlongest####1\@@par{}% Very dirty... + \advance\rightskip 1\leftskip plus 1fil + \leftskip=\z@}% + #1}% + \let\iftitlemeasuring\@secondoftwo + \ttl@boxprocess + #1} + +\def\ttl@boxprocess{% + \setbox\ttl@box=\vbox{% + \unvcopy\ttl@box + \unskip\unpenalty + \global\setbox\@ne=\lastbox}% + \ifvoid\@ne + \else + \setbox\tw@=\hbox{\hskip-\leftskip\unhbox\@ne\hskip-\rightskip}% + \titlewidthfirst\wd\tw@ + \ifdim\titlewidth<\titlewidthfirst + \titlewidth\titlewidthfirst + \fi + \ifdim\titlewidthlast=\z@ + \titlewidthlast\titlewidthfirst + \fi + \expandafter\ttl@boxprocess + \fi} + +% Rules +% ~~~~~ + +\providecommand\titleline{% + \@ifstar{\ttl@line@i{\hb@xt@\titlewidth}}% + {\ttl@line@i{}}} + +\def\ttl@line@i#1{% + \@ifnextchar[{\ttl@line{#1}}{\ttl@line{#1}[s]}} + +\def\ttl@line#1[#2]#3{% + \vskip\topskip + \hrule \@height \z@ + \nobreak + \vskip-\topskip + \begingroup + \parindent\z@ + \everypar{}% + \leftskip\z@ + \rightskip\z@ % #1 is either \hb@xt@\titlewidth or empty: + \@makebox[\hsize][#2]{\ttl@makeline{#1{#3}}}% + \par + \endgroup + \hrule height \z@ + \nobreak} + +\providecommand\titlerule{\@ifstar{\ttl@row}{\ttl@rule}} + +\let\ttl@leaders\xleaders % For titletoc compatibility + +\def\ttl@row{\@ifnextchar[{\ttl@row@i}{\ttl@row@i[\wd\z@]}} +\def\ttl@row@i[#1]#2{% + \ifvmode\expandafter\titleline\fi + {\sbox\z@{#2}% + \ttl@calcneg\hspace{#1}% + \hskip\wd\z@ + \ttl@leaders\hb@xt@#1{\hss\box\z@}% + \hfill\kern\z@}} + +\def\ttl@rule{\@ifnextchar[{\ttl@rule@i}{\ttl@rule@i[.4\p@]}} +\def\ttl@rule@i[#1]{% + \ifvmode\expandafter\titleline\fi + {\leaders\hrule height #1\hfill\kern\z@}} + +% Par shapes and space +% ~~~~~~~~~~~~~~~~~~~~ + +\providecommand\filright{% + \gdef\ttl@filleft##1{\hskip##1}% + \gdef\ttl@filright##1{\hfill}% + \let\\\@centercr + \advance\rightskip\z@ \@plus 1fil\relax} +\providecommand\filleft{% + \gdef\ttl@filleft##1{\hfill}% + \gdef\ttl@filright##1{\hskip##1}% + \let\\\@centercr + \advance\leftskip\z@ \@plus 1fil + \parfillskip\z@} +\providecommand\filcenter{\filleft\filright + \gdef\ttl@filleft##1{\hfill}} +\providecommand\fillast{% + \gdef\ttl@filleft##1{\hfill}% + \gdef\ttl@filright##1{\hfill}% + \let\\\@centercr + \filleft\advance\rightskip\z@ \@plus -1fil + \parfillskip\z@ \@plus 2fil\relax} +\newcommand\filinner{% + \if@twoside + \ifodd\count\z@\filleft\else\filright\fi + \else + \filleft + \fi} +\newcommand\filouter{% + \if@twoside + \ifodd\count\z@\filright\else\filleft\fi + \else + \filright + \fi} + +\newcommand\wordsep{\fontdimen\tw@\font \@plus + \fontdimen\thr@@\font \@minus \fontdimen4\font} + +% +-----------------+ +% | O P T I O N S | +% +-----------------+ + + +\DeclareOption{pagestyles}{\let\sectiontitle\@empty} +\DeclareOption{extramarks}{\let\ttl@fetchmark\@empty} +\DeclareOption{floatps}{% + \ifx\sectiontitle\@empty + \let\ttl@replace\space + \else + \PackageWarning{titlesec}{Ignoring `floatps' without + `pagestyles'. This option is now deprecated.}% + \fi} +\DeclareOption{psfloats}{% + \ifx\sectiontitle\@empty + \let\ttl@replace\@empty + \else + \PackageWarning{titlesec}{Ignoring `psfloats' without + `pagestyles'}% + \fi} + +\DeclareOption{loadonly}{\let\ttl@extract\@empty} + +\DeclareOption{outermarks}{% + \def\ttl@titlemarks{\outertitlemarks}} +\DeclareOption{topmarks}{ + \def\ttl@titlemarks{\toptitlemarks}} +\DeclareOption{botmarks}{% + \def\ttl@titlemarks{\bottitlemarks}} +\DeclareOption{innermarks}{% + \def\ttl@titlemarks{\innertitlemarks}} + +\DeclareOption{footmarks}{} % Backward compat + +\DeclareOption{explicit}{\ttl@explicittrue} + +\DeclareOption{clearempty}{% + \def\cleardoublepage{% + \clearpage{\ps@empty\if@twoside\ifodd\c@page\else + \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi}}} + +\DeclareOption{rigidchapters}{% + \def\ttl@topmode#1#2{\vbox to #1{#2\vfil}}% + \def\ttl@chapafter{.26\textheight}} +\DeclareOption{rubberchapters}{% + \def\ttl@topmode#1#2{{#2}\ttl@calc\vspace{#1}}% + \def\ttl@chapafter{40\p@}} + +\DeclareOption{bottomtitles}{% + \def\bottomtitlespace{-1\p@}} +\DeclareOption{nobottomtitles}{% + \def\bottomtitlespace{.2\textheight}} +\DeclareOption{nobottomtitles*}{% + \let\ttl@addstretch\relax + \def\bottomtitlespace{.2\textheight}} + +\DeclareOption{calcwidth}{% + \let\ttl@beginlongest\ttl@xbeginlongest} + +\DeclareOption{aftersep}{% + \let\ttl@titlespace\@gobble} +\DeclareOption{largestsep}{% + \let\ttl@titlespace\addvspace} + +\DeclareOption{oldparttoc}{% + \def\ttl@tocpart{\def\ttl@a{\thepart\hspace{1em}}}} +\DeclareOption{newparttoc}{% + \let\ttl@tocpart\relax} +\DeclareOption{notocpart*}{% + \let\ttl@notocparts\@empty} + +\DeclareOption{rm}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\rmfamily}} +\DeclareOption{sf}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\sffamily}} +\DeclareOption{tt}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\ttfamily}} +\DeclareOption{md}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\mdseries}} +\DeclareOption{bf}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\bfseries}} +\DeclareOption{up}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\upshape}} +\DeclareOption{it}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\itshape}} +\DeclareOption{sl}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\slshape}} +\DeclareOption{sc}{% + \protected@xdef\ttl@fonts{\ttl@fonts\protect\scshape}} + +\DeclareOption{big}{% + \gdef\ttl@sizes#1{\ifcase#1\relax\Huge\or\Large\or\large + \or\normalsize\or\or\or\huge\fi}} +\DeclareOption{medium}{% + \gdef\ttl@sizes#1{\ifcase#1\relax\huge\or\Large\or\large + \or\normalsize\or\or\or\LARGE\fi}} +\DeclareOption{small}{% + \gdef\ttl@sizes#1{\ifcase#1\relax\LARGE\or\large + \or\normalsize\or\normalsize\or\or\or\Large\fi}} +\DeclareOption{tiny}{% + \gdef\ttl@sizes#1{\ifcase#1\relax\large\or\normalsize\or + \normalsize\or\normalsize\or\or\or\normalsize\fi}} + +\DeclareOption{raggedleft}{% + \gdef\ttl@fil{\filleft}} +\DeclareOption{center}{% + \gdef\ttl@fil{\filcenter}} +\DeclareOption{raggedright}{% + \gdef\ttl@fil{\filright}} + +\DeclareOption{uppercase}{% + \gdef\ttl@case{\MakeUppercase}} + +\DeclareOption{compact}{% + \gdef\ttl@space{1}% + \gdef\ttl@chapafter{30\p@}} + +% Deprecated. To be remmoved in a major upgrade (3.0) +\DeclareOption{indentfirst}{% + \gdef\@afterindentfalse{\let\if@afterindent\iftrue}% + \@afterindenttrue + \def\titlespacing{% + \@ifstar{\ttl@spacing@i{\@ne}}{\ttl@spacing@i{\@ne}}}} +\DeclareOption{nonindentfirst}{% + \def\titlespacing{% + \@ifstar{\ttl@spacing@i{\z@}}{\ttl@spacing@i{\z@}}}} + +% New names +\DeclareOption{indentafter}{% + \gdef\@afterindentfalse{\let\if@afterindent\iftrue}% + \@afterindenttrue + \def\titlespacing{% + \@ifstar{\ttl@spacing@i{\@ne}}{\ttl@spacing@i{\@ne}}}} +\DeclareOption{noindentafter}{% + \def\titlespacing{% + \@ifstar{\ttl@spacing@i{\z@}}{\ttl@spacing@i{\z@}}}} + +% newlinetospace +\let\ttl@blinemarks\relax +\let\ttl@elinemarks\relax + +\DeclareRobustCommand\ttl@linetosp{% + \@ifstar{\ttl@linetosp@i}{\ttl@linetosp@i}}% + +\def\ttl@linetosp@i{% + \ifdim\lastskip>\z@\else\space\fi + \ignorespaces} + +\DeclareOption{newlinetospace}{% + \def\ttl@blinemarks{% + \let\ttl@e\\% + \def\\{\ttl@linetosp}}% + \def\ttl@elinemarks{\let\\\ttl@e}}% + +% toctitles +\def\ttl@addcontentsline#1#2{% + \addcontentsline{toc}{#1}{\ifttl@toclabel\ttl@a\fi#2}% + \nobreak} + +\DeclareOption{toctitles}{% + \def\ttl@addcontentsline#1#2{% + \addcontentsline{toc}{#1}{\ifttl@toclabel\ttl@a\fi\ttl@savetitle}% + \nobreak}} + +% pageatnewline + +\def\ttl@changecentercr{% + \let\ttl@centercr\@centercr + \def\@centercr{\@ifstar{\ttl@centercr*}{\ttl@centercr*}}} + +\DeclareOption{pageatnewline}{\let\ttl@changecentercr\relax} + +\def\ttl@fonts{} + +\ExecuteOptions{rubberchapters,bottomtitles,aftersep,oldparttoc,% + innermarks} + +\ProcessOptions + +% +-----------------+ +% | H Y P E R R E F | +% +-----------------+ +% +% These two commands are provided by hyperref. But if they +% are not defined at \begin{document} hyperref has not been +% loaded or it is an old version. + +\AtBeginDocument{% + \ifx\ttl@Hy@steplink\@undefined + \let\ttl@Hy@steplink\@gobble + \let\ttl@Hy@refstepcounter\refstepcounter + \fi} + +% +-----------------+ +% | PAGE STYLES | +% +-----------------+ +% +% This is generic: + +\newcommand\assignpagestyle[2]{% + \@namedef{ttl@ps@\expandafter\@gobble\string#1}{#2}} + +% Old pagestyles +% ~~~~~~~~~~~~~~ + +\providecommand\newpagestyle{% + \let\ttl@compatps\@empty % marks the ``old interface'' + \makeatletter + \edef\ttl@d{% + \noexpand\input{ttlps.def}% + \catcode`\noexpand\@=\the\catcode`\@}% + \ttl@d + \newpagestyle} + +\providecommand\renewpagestyle{% + \let\ttl@compatps\@empty % marks the ``old interface'' + \makeatletter + \edef\ttl@d{% + \noexpand\input{ttlps.def}% + \catcode`\noexpand\@=\the\catcode`\@}% + \ttl@d + \renewpagestyle} + +\providecommand\widenhead{% + \let\ttl@compatps\@empty % marks the ``old interface'' + \makeatletter + \edef\ttl@d{% + \noexpand\input{ttlps.def}% + \catcode`\noexpand\@=\the\catcode`\@}% + \ttl@d + \widenhead} + +% New pagestyles +% ~~~~~~~~~~~~~~ + +\@ifundefined{sectiontitle}{}{\input{ttlps.def}} + +% +-----------------+ +% | C O M P A T | +% +-----------------+ +% Easy setup, i.e., that of package options, is +% taken care of, if necessary. + +\renewcommand\secdef[2]{% + \@ifstar + {\ttl@labelfalse + #2} + {\ttl@labeltrue + \ifx#1\@chapter + \if@mainmatter\else\ttl@labelfalse\fi + \ifnum\ttll@chapter>\c@secnumdepth\ttl@labelfalse\fi + \else\ifx#1\@part + \ifnum\ttll@part>\c@secnumdepth\ttl@labelfalse\fi + \fi\fi + \let\ifttl@toclabel\ifttl@label + \@dblarg{#1}}} + +\@ifundefined{ttl@extract}{}{\endinput} + +\newcommand\titlelabel[1]{% + \def\@seccntformat##1{#1}} + +\expandafter\ifx\csname chapter\endcsname\relax + + \def\ttl@compatpart{\titleclass{\part}{part}\relax} + +\else + + \def\ttl@compatchapter{% + \def\@makechapterhead{% + \ttl@labeltrue + \if@mainmatter\else\ttl@labelfalse\fi + \ifnum\ttll@chapter>\c@secnumdepth\ttl@labelfalse\fi + \ttl@startargs\ttl@mkchap{chapter}}% + \def\@makeschapterhead{% + \ttl@labelfalse + \if@mainmatter\else\ttl@labelfalse\fi + \ifnum\ttll@chapter>\c@secnumdepth\ttl@labelfalse\fi + \ttl@startargs\ttl@mkchap{chapter}}} + + \def\ttl@compatpart{\titleclass{\part}{page}\relax} + +\fi + +\def\ttl@@extract#1\@startsection#2#3#4#5#6#7#8{% + \@tempskipa=#5 + \@tempskipb=#6 + \ifdim\@tempskipa<\z@ + \toks@{\titlespacing*#8{#4}}% + \@tempskipa-\@tempskipa + \else + \toks@{\titlespacing#8{#4}}% + \fi + \@ifundefined{ttl@space}{}{% + \ttl@assign\@tempskipa*\ttl@space\relax\beforetitleunit}% + \ifdim\@tempskipb<\z@ + \if@tempswa + \titleformat#8[runin]% + {\ttl@fonts\ttl@sizes{#3}}{\@seccntformat{#2}}% + {\z@}\ttl@passexplicit + \else + \titleformat#8[runin]% + {#7}{\@seccntformat{#2}}% + {\z@}\ttl@passexplicit + \fi + \@tempskipb-\@tempskipb + \else + \if@tempswa + \titleformat#8% + {\ttl@fil\ttl@fonts\ttl@sizes{#3}}{\@seccntformat{#2}}% + {\z@}\ttl@passexplicit + \else + \titleformat#8% + {#7}{\@seccntformat{#2}}% + {\z@}\ttl@passexplicit + \fi + \@ifundefined{ttl@space}{}{% + \ttl@assign\@tempskipb*\ttl@space\relax\aftertitleunit}% + \fi + \edef\ttl@a{\the\toks@{\the\@tempskipa}{\the\@tempskipb}} + \ttl@a} + +\def\ttl@extract#1{% + \expandafter\in@\expandafter\@startsection\expandafter{#1}% + \ifin@ + \expandafter\ttl@@extract#1#1% + \else + \PackageWarningNoLine{titlesec}% + {Non standard sectioning command detected\MessageBreak + Using default spacing and no format} + \titlespacing*#1{\z@}{*3}{*2}% + \fi} + +\@tempswafalse + +\ifx\ttl@fonts\@empty + \def\ttl@fonts{\bfseries} +\else + \@tempswatrue +\fi + +\expandafter\ifx\csname ttl@sizes\endcsname\relax + \gdef\ttl@sizes#1{\ifcase#1\relax\Huge\or\Large\or\large + \or\normalsize\or\or\or\huge\fi} +\else + \@tempswatrue +\fi + +\expandafter\ifx\csname ttl@fil\endcsname\relax + \let\ttl@fil\@empty +\else + \@tempswatrue +\fi + +\expandafter\ifx\csname ttl@case\endcsname\relax + \let\ttl@case\@firstofone +\else + \@tempswatrue +\fi + +\if@tempswa + + \expandafter\ifx\csname chapter\endcsname\relax\else + \titleformat\chapter[display]% + {\@ifundefined{ttl@fil}{\raggedright}{\ttl@fil}\ttl@fonts\ttl@sizes6} + {\@chapapp\space\thechapter}{.8\baselineskip}{\ttl@sizes\z@\ttl@passexplicit} + \fi + +\fi + +\ttl@extract\section +\ttl@extract\subsection +\ttl@extract\subsubsection +\ttl@extract\paragraph +\ttl@extract\subparagraph + +\let\ttl@extract\@undefined +\let\ttl@@extract\@undefined + +\def\ttl@toplevel{part} + +\expandafter\ifx\csname chapter\endcsname\relax + + \@namedef{ttll@part}{0} + \titleclass{\section}{straight}[\part] + + \titlespacing*{\part} + {\z@} + {4ex} + {3ex} + +\else + + \let\ttl@save@mkchap\@makechapterhead + \let\ttl@save@mkschap\@makeschapterhead + + \def\@makechapterhead#1{% + \gdef\ttl@savemark{\chaptermark{#1}}% + \ttl@save@mkchap{#1}% + \@ifundefined{ttl@ps@chapter}{}% + {\thispagestyle{\@nameuse{ttl@ps@chapter}}}} + + \def\@makeschapterhead#1{% + \gdef\ttl@savemark{\chaptermark{#1}}% + \ttl@save@mkschap{#1}% + \@ifundefined{ttl@ps@chapter}{}% + {\thispagestyle{\@nameuse{ttl@ps@chapter}}}} + + \@namedef{ttll@part}{-1} + \@namedef{ttlss@part}{chapter} + \@namedef{ttll@chapter}{0} + \titleclass{\section}{straight}[\chapter] + +% The following is unoperant, unless when \chapter / \part +% format is redefined + + \titlespacing*{\part} + {\z@} + {\z@\@plus1fil} + {\z@\@plus1fil} + + \titlespacing*\chapter + {\z@}% + {50\p@}% + {\ttl@chapafter}% + +\fi + +\titleclass{\subsection} {straight}[\section] +\titleclass{\subsubsection}{straight}[\subsection] +\titleclass{\paragraph} {straight}[\subsubsection] +\titleclass{\subparagraph} {straight}[\paragraph] + +\endinput diff --git a/ThirdParty/Ert/python/docs/latex/upquote.sty b/ThirdParty/Ert/python/docs/latex/upquote.sty new file mode 100644 index 0000000000..6b9d754f2a --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/upquote.sty @@ -0,0 +1,40 @@ +%% +%% This is file `upquote.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% upquote.dtx (with options: `package') +%% +%% Copyright (C) 2000 by Michael A. Covington +%% Copyright (C) 2003 by Frank Mittelbach +%% Copyright (C) 2012 by Markus Kuhn (current maintainer) +%% +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{upquote} + [2012/04/19 v1.3 upright-quote and grave-accent glyphs in verbatim] +\newcommand\upquote@cmtt{cmtt} +\newcommand\upquote@OTone{OT1} +\ifx\encodingdefault\upquote@OTone + \ifx\ttdefault\upquote@cmtt\else\RequirePackage{textcomp}\fi +\else + \RequirePackage{textcomp} +\fi +\begingroup +\catcode`'=\active +\catcode``=\active +\g@addto@macro\@noligs + {\let'\textquotesingle + \let`\textasciigrave + \ifx\encodingdefault\upquote@OTone + \ifx\ttdefault\upquote@cmtt + \def'{\char13 }% + \def`{\char18 }% + \fi\fi} +\endgroup +\endinput +%% +%% End of file `upquote.sty'. diff --git a/ThirdParty/Ert/python/docs/latex/wrapfig.sty b/ThirdParty/Ert/python/docs/latex/wrapfig.sty new file mode 100644 index 0000000000..ea85e1b0d4 --- /dev/null +++ b/ThirdParty/Ert/python/docs/latex/wrapfig.sty @@ -0,0 +1,598 @@ +% W R A P F I G . S T Y ver 3.6 (Jan 31, 2003) +% +% Copyright (C) 1991-2003 by Donald Arseneau +% This software is released under the terms of the LaTeX Project +% public license. +% +% Environments "wrapfigure" and "wraptable" place a figure or table +% at the side of the page and wrap text around it. +% +% \begin{wrapfigure}[12]{r}[34pt]{5cm}
\end{wrapfigure} +% -- - ---- --- +% [number of narrow lines] {placement} [overhang] {width of figure} +% +% Placement is one of r, l, i, o, R, L, I, O, for right, left, +% inside, outside, (here / FLOAT). +% The figure sticks into the margin by `overhang', if given, or by the +% length \wrapoverhang, which is normally zero. +% The number of wrapped text lines is normally calculated from the height +% of the figure, but may be specified manually ("12" above). +% +% Environments similar to "wrapfigure" and "wraptable" may be easily added, +% or invoked by "\begin{wrapfloat}{float_name}" +% +% More detailed instructions are given below, following the definitions. +% Please direct any problem reports to asnd@triumf.ca + +%%%%% ----- Begin definitions ----- %%%%% + +\@ifundefined{c@WF@wrappedlines}{}{\endinput} + +\newdimen\wrapoverhang \wrapoverhang\z@ +\newdimen\WF@size +\newcount\c@WF@wrappedlines % used globally +\newbox\WF@box +\newtoks\WF@everypar +\newif\ifWF@float +\let\@@parshape\parshape +\let\WF@@everypar\everypar + +\def\wrapfloat#1{\def\@captype{#1}\@ifnextchar[\WF@wr{\WF@wr[]}} + +\def\wrapfigure{\wrapfloat{figure}} +\def\wraptable{\wrapfloat{table}} + +\def\WF@wr[#1]#2{% first two args: #1=num lines, #2=placement + \xdef\WF@wfname{wrap\@captype\space}% + \ifvoid\WF@box\else \WFclear \WF@collision \fi + \xdef\WF@place{\string`\@car#2r\@nil}% + \ifnum\lccode\WF@place=\WF@place \global\WF@floatfalse + \else \global\WF@floattrue \fi + \ifx\parshape\WF@fudgeparshape \ifWF@float\else\WF@collision\fi \else + \ifx\par\@@par \ifnum\@@parshape>\z@\WF@conflict\fi \else \WF@conflict\fi + \fi \gdef\WF@wli{#1}% + \@ifnextchar[\WF@rapt{\WF@rapt[\wrapoverhang]}} + +\def\WF@rapt[#1]#2{% final two args: #1 = overhang, #2 = width, + \gdef\WF@ovh{#1}% hold overhang for later, when \width is known + \global\setbox\WF@box\vtop\bgroup \setlength\hsize{#2}% + \ifdim\hsize>\z@ \@parboxrestore \else + \setbox\z@\hbox\bgroup \let\wf@@caption\caption \let\caption\wf@caption + \ignorespaces \fi} + +\def\wf@caption{\relax + \ifdim\hsize>\z@ \let\caption\wf@@caption \else + \unskip \egroup \hsize\wd\z@ \@parboxrestore \box\z@ \fi \caption} + +\def\endwrapfloat{% + \ifdim\hsize>\z@ \par\hrule\@width\hsize\@height\z@ % force width + \else \unskip \egroup \box\z@ \fi % or end hbox + \egroup % end the \vtop; width is known so now is "later" + \WF@floatstyhook % support float.sty + \def\width{\wd\WF@box}\setlength\wrapoverhang{\WF@ovh}% + \xdef\WF@ovh{\the\wrapoverhang}% save until wrapping + \ifdim\ht\WF@box>\topskip \ht\WF@box\z@ \fi % too much height, set flag. + \ifdim\ht\WF@box<.5\p@ % too tall (starts with \vbox) or too short + \global\setbox\WF@box\vtop{\vskip-1.4ex\unvbox\WF@box}\fi + \global\WF@size\dp\WF@box % box is guaranteed to have little height. + \global\advance\WF@size1.5\baselineskip \global\advance\WF@size\tw@\intextsep + \aftergroup\WF@startfloating % even when not really floating! + \ifWF@float\else \ifhmode + {\unskip \parfillskip\z@skip \par \vskip-\parskip}\aftergroup\noindent + \fi\fi \global\@ignoretrue} + +\let\endwrapfigure\endwrapfloat +\let\endwraptable\endwrapfloat + +% Subvert \everypar to float fig and do wrapping. Also for non-float. +\def\WF@startfloating{% + \WF@everypar\expandafter{\the\everypar}\let\everypar\WF@everypar + \WF@@everypar{\ifvoid\WF@box\else\WF@floathand\fi \the\everypar + \WF@wraphand +}} + +\def\WF@floathand{% +\ifx\parshape\WF@fudgeparshape \WF@fltmes\else + \ifx\par\@@par\ifnum\@@parshape=\z@\ifdim\hangindent=\z@ + \setbox\z@\lastbox \begingroup + \@@par \WF@@everypar{}\WF@putfigmaybe + \endgroup % start wrapping + \ifvoid\z@\else\box\z@\fi % replace indentation + \else\WF@fltmes\fi\else\WF@fltmes\fi\else\WF@fltmes\fi\fi} + +% Put fig here if it fits or if it can't float +\def\WF@putfigmaybe{% +\ifinner + \vskip-\parskip \global\WF@floatfalse + \let\pagetotal\maxdimen % kludge flag for "not top of page" +\else % outer page + \@tempdima\pagedepth % save page depth + {\advance\parskip\@tempdima\vskip-\parskip}% back up to baseline + \penalty\interlinepenalty % update pg. parameters + \@tempdimb\pagegoal \advance\@tempdimb-\pagetotal % room left on page + \ifdim\@tempdimb<\z@ % \WF@info{Page overfull already;}% + \global\WF@floatfalse + \ifdim-\@tempdimb>\pageshrink \else \pagebreak \fi + \else + \ifdim\WF@size>\@tempdimb +% \WF@info{Size \the\WF@size\space does not fit in \the\@tempdimb}% + \ifWF@float \dimen@.5\baselineskip \else \dimen@ 2\baselineskip\fi + \ifdim\pagestretch>\dimen@ \dimen@\pagestretch \fi + \ifdim\pagefilstretch>\z@ \dimen@\@tempdimb \fi + \ifdim\pagefillstretch>\z@ \dimen@\@tempdimb \fi + \advance\dimen@.5\baselineskip + \ifdim\dimen@>\@tempdimb % \WF@info{Page nearly full; can stretch}% + \global\WF@floatfalse \pagebreak + \fi + \else % \WF@info{Fits in \the\@tempdimb;}% + \global\WF@floatfalse + \fi\fi + \vskip\@tempdima\relax % (return erased page depth) +\fi +\noindent +\ifWF@float + \WF@fltmes +\else % putting here; + \WF@info{Put \WF@wfname here:}% + {\ifodd\if@twoside\c@page\else\@ne\fi % assign l/r to i/o placement + \lccode`i`l\lccode`o`r\else \lccode`i`r\lccode`o`l\fi + \xdef\WF@place{\the\lccode\lccode\WF@place}}% twice to get only l or r + \hbox to\z@{% llap or rlap depending on {l} or {r}; calc effective width + \@tempdima\wd\WF@box \@tempdimb\WF@ovh + \advance\@tempdima-\@tempdimb \advance\@tempdima\columnsep + \@tempdimb\hsize \advance\@tempdimb-\@tempdima + \xdef\WF@adjlw{\the\@tempdima}% + \ifnum `l=\WF@place % fig on left + \hss % figure overlaps space to the left + \def\@tempa{\kern\columnsep}% position to left of the gap + \else % fig on right + \@tempdima\z@ % no left indentation + \kern\@tempdimb \kern\columnsep + \def\@tempa{\hss}% figure overlaps space to the right + \fi + \ifdim\@tempdimb<\hsize + \xdef\WF@wrapil{\the\@tempdima \the\@tempdimb}% indentation and length + \xdef\WF@adjtlm{\the\@tempdima}% + \else + \xdef\WF@wrapil{\z@ \the\hsize}% + \xdef\WF@adjlw{\z@}\xdef\WF@adjtlm{\z@}% + \fi + \ifdim\pagetotal=\z@ % \WF@info{Put \WF@wfname at top of p.\thepage}% + \global\advance\WF@size-\intextsep + \else % \WF@info{Putting \WF@wfname in middle of page}% + \setbox\WF@box\hbox{\lower\intextsep\box\WF@box}% + \fi \dp\WF@box\z@ \box\WF@box \@tempa + }% end \hbox to 0pt + \aftergroup\WF@startwrapping % after the \endgroup which immediately follows +\fi} + +\def\WF@startwrapping{% + \ifx\WF@wli\@empty + {\advance\WF@size1.1\baselineskip + \divide\WF@size\baselineskip \global\c@WF@wrappedlines\WF@size}% + \else + \setcounter{WF@wrappedlines}{\WF@wli}\global\advance\c@WF@wrappedlines\@ne + \fi + \ifnum\c@WF@wrappedlines>\@ne + \let\parshape\WF@fudgeparshape \let\WF@pspars\@empty \let\WF@@par\par + \def\@setpar##1{\def\WF@@par{##1}}\def\par{\@par}\let\@par\WF@mypar + \xdef\WF@restoretol{\tolerance\the\tolerance}\tolerance9999 + \advance\linewidth-\WF@adjlw \advance\@totalleftmargin\WF@adjtlm + \fi} + +\def\WF@wraphand{% +\ifnum\c@WF@wrappedlines<\tw@ \WF@finale +\else \begingroup % Create \parshape command: + \@tempcnta\@ne \let\WF@wrapil\relax \gdef\WF@ps{}% + \@whilenum \@tempcnta<\c@WF@wrappedlines\do{% repeated indentation, length + \xdef\WF@ps{\WF@ps\WF@wrapil}\advance\@tempcnta\@ne + }\endgroup + \ifx\WF@pspars\@empty + \@@parshape\c@WF@wrappedlines \WF@ps \WF@noil + \else % use external `parshape' values to modify my parshape + \WF@modps +\fi\fi} + +\def\WF@mypar{\relax + \WF@@par % what the rest of LaTeX expects \par to be (usually \@@par) + \ifnum\@@parshape=\z@ \let\WF@pspars\@empty \fi % reset `parshape' + \global\advance\c@WF@wrappedlines-\prevgraf \prevgraf\z@ + \ifnum\c@WF@wrappedlines<\tw@ \WF@finale \fi} + +\def\WF@modps{\begingroup + \afterassignment\@tempdimb \@tempdima\WF@pspars % a=ind, b=wid + \advance\@tempdima-\WF@adjtlm \advance\@tempdimb\WF@adjlw +% \afterassignment\dimen@\advance\@tempdima\WF@wrapil +% \advance\@tempdimb\dimen@ \advance\@tempdimb-\hsize + \let\WF@wrapil\WF@pspars%{\the\@tempdima \the\@tempdimb}% + \edef\@tempb{\@@parshape\c@WF@wrappedlines \WF@ps \the\@tempdima \the\@tempdimb}% + \expandafter\endgroup\@tempb} + +\let\@@setpar\@setpar +\def\WF@noil{\z@ \hsize} +\let\WF@pspars\@empty + +\def\WF@fudgeparshape{\relax \ifnum\c@WF@wrappedlines<\tw@ \WF@finale + \else \afterassignment\WF@fudgeparshapee \fam \fi} +\def\WF@fudgeparshapee{\ifnum\fam=\@ne \expandafter \WF@parshapeee \else + \WF@conflict \@@parshape\fam \fi} +\def\WF@parshapeee#1#2{\begingroup\delimitershortfall#1% + \nulldelimiterspace#2%\advance\nulldelimiterspace\WF@adjlw + \edef\@tempa{\def\noexpand\WF@pspars{% + \the\delimitershortfall \the\nulldelimiterspace}}% + \expandafter\endgroup\@tempa \WF@wraphand} + +\def\WF@finale{\ifx\parshape\WF@fudgeparshape + \WF@restoretol \let\@setpar\@@setpar \let\par\WF@@par + \advance\linewidth\WF@adjlw \advance\@totalleftmargin-\WF@adjtlm + \WF@info{Finish wrapping text}% + \ifx\par\@@par \def\@par{\let\par\@@par\par}\else \let\@par\WF@@par \fi + \let\parshape\@@parshape + \parshape\ifx\WF@pspars\@empty \z@ \else \@ne \WF@pspars\fi \fi + \ifvoid\WF@box \ifx\everypar\WF@everypar + \let\everypar\WF@@everypar \everypar\expandafter{\the\WF@everypar}% + \fi\fi} + +\newcommand{\WFclear}{\par + \ifvoid\WF@box\else \vskip\bigskipamount \box\WF@box + \let\everypar\WF@@everypar \everypar\expandafter{\the\WF@everypar}% + \fi \global\c@WF@wrappedlines\z@ \WF@finale} + +\begingroup + \toks0={\let\everypar\WF@@everypar \everypar\expandafter{\the\WF@everypar}% + \let\parshape\@@parshape \let\@setpar\@@setpar } + \toks1=\expandafter{\@arrayparboxrestore} + \toks2=\expandafter{\clearpage} + \edef\@tempa{\def\noexpand\@arrayparboxrestore{\the\toks0 \the\toks1}% + \def\noexpand\clearpage{\noexpand\protect\noexpand\WFclear \the\toks2}} + \expandafter +\endgroup\@tempa + +\@ifundefined{@capwidth}{\let\@capwidth\hsize}{}% Pamper RevTeX's Stupidity + +\def\WF@conflict{\WF@warning + {\WF@wfname used inside a conflicting environment}} +\def\WF@collision{\WF@warning{Collision between wrapping environments}} +\def\WF@fltmes{\ifWF@float \WF@info{\WF@wfname floats}% + \else \WF@warning{Stationary \WF@wfname forced to float}\fi} + +\let\WF@warning\@warning +\let\WF@info\@gobble + +% Support float.sty: float styles and \newfloat. Make \newfloat{foo} +% define the `wrapfoo' environment. Support \newfloat from memoir.cls +% and \newfloatlist from ccaption.sty. +% +\let\WF@floatstyhook\relax + +\@ifundefined{newfloat}{}{% There is a \newfloat command +% + \@ifundefined{restylefloat}{ + % \newfloat comes from somewhere besides float.sty + \@ifclassloaded{memoir}{ + \toks@=\expandafter\expandafter\expandafter + {\csname\string\newfloat\endcsname [{#1}]{#2}{#3}{#4}% + \newenvironment{wrap#2}{\wrapfloat{#2}}{\endwrapfloat}% + } + \edef\@tempa{\def\expandafter\noexpand\csname\string\newfloat\endcsname + [##1]##2##3##4{\the\toks@}} + \@tempa + }% end memoir support + {}% Other origins of \newfloat here?? + }{ + % float.sty handler. Ooops: Two versions for different versions + % Changing \float@restyle (or \restylefloat) changes \newfloat too. + \@ifundefined{float@restyle}{% older float.sty + \toks@=\expandafter{\restylefloat{#1}% (env may or may not be defined) + \@namedef{wrap#1}{\def\@captype{#1}\@nameuse{fst@#1}% + \def\WF@floatstyhook{\let\@currbox\WF@box \columnwidth\wd\WF@box + \global\setbox\WF@box\float@makebox}% + \@ifnextchar[\WF@wr{\WF@wr[]}}% + \expandafter\let\csname endwrap#1\endcsname \endwrapfigure + }\edef\@tempa{\def\noexpand\restylefloat##1{\the\toks@}} + }{% newer float.sty: use \float@restyle, and \float@makebox takes width arg + \toks@=\expandafter{\float@restyle{#1}% (env may or may not be defined) + \@namedef{wrap#1}{\def\@captype{#1}\@nameuse{fst@#1}% + \def\WF@floatstyhook{\let\@currbox\WF@box + \global\setbox\WF@box\float@makebox{\wd\WF@box}}% + \@ifnextchar[\WF@wr{\WF@wr[]}}% + \expandafter\let\csname endwrap#1\endcsname \endwrapfigure + }\edef\@tempa{\def\noexpand\float@restyle##1{\the\toks@}} + } + \@tempa % perform redefinitions + % + }% End float.sty handler +}% End redefinitions of \newfloat + +% Support ccaption.sty +\@ifundefined{\string\newfloatlist}{}{ + \toks@=\expandafter\expandafter\expandafter + {\csname\string\newfloatlist\endcsname [{#1}]{#2}{#3}{#4}{#5}% + \@namedef{wrap#2}{\wrapfloat{#2}}% + \expandafter\let\csname endwrap#2\endcsname \endwrapfloat + } + \edef\@tempa{\def\expandafter\noexpand\csname\string\newfloatlist\endcsname + [##1]##2##3##4##5{\the\toks@}} + \@tempa +} + +% Process package options. + +\@ifundefined{DeclareOption}{\endinput}{} + +\def\WF@warning{\PackageWarning{wrapfig}} +\ProvidesPackage{wrapfig}[2003/01/31 \space v 3.6] +\DeclareOption{verbose}{\def\WF@info{\PackageInfo{wrapfig}}} +\ProcessOptions +\AtEndDocument{\WFclear} + +\endinput + +%%%%% ----- End definitions ----- %%%%% + +%%%%% ----- Begin Instructions ----- %%%%% + + +W R A P F I G . S T Y \ \ ver 3.6 \ \ (Jan 31, 2003) + +Copyright (C) 1991-2003 by Donald Arseneau (asnd@triumf.ca) + +Wrapfig.sty provides the environments "wrapfigure" and "wraptable" for +typesetting a narrow float at the edge of the text, and making the text +wrap around it. The "wrapfigure" and "wraptable" environments interact +properly with the "\caption" command to produce proper numbering, but +they are not regular floats like "figure" and "table", so (beware!) they +may be printed out of sequence with the regular floats. There are four +parameters for "\begin{wrapfigure}", two optional and two required, plus +the text of the figure, with a caption perhaps: + + \begin{wrapfigure}[12]{r}[34pt]{5cm}
\end{wrapfigure} + == = ==== === + [number of narrow lines] {placement} [overhang] {width} + +Some idiosyncrasies: + + - You must not specify a wrapfigure in any type of list environment or + or immediately before or immediately after one. It is OK to follow + a list if there is a blank line ("\par") in between. + + - If you put a wrapfigure in a parbox or a minipage, or any other type + of grouping, the text wrapping should end before the group does. + + - It does work in two-column format, but are your figures that small? + + - It may be out of sequence with regular floats. + + - The hlines that may be printed above and below floats are ignored; + you must insert them manually if desired. + + - "\linewidth" is now adjusted within the wrapped text, but since it + can only be set for whole paragraphs at a time, it will persist with + the wrong value after the wrapping, until the paragraph is finished. + +New wrapping environments may be added when new float types are defined +(using memoir.cls, float.sty, or ccaption.sty). Any wrapping environment, +"wrapfigure", "wraptable", or something else may be invoked using the +"wrapfloat" environment, as in "\begin{wrapfloat}{figure}{O}{5cm}". + +To use float.sty properly, load package "float" before "wrapfig", +and declare any new float types after loading both. Likewise for +ccaption.sty and "\newfloatlist" and memoir.cls and its "\newfloat". + +\section{Placement and Floating} + +Parameter "#2" (required) is the figure placement code, but the valid +codes are different from regular figures. They come in pairs: an +uppercase version which allows the figure to float, and a lowercase +version that puts the figure ``exactly here''. + + r R - the right side of the text + l L - the left side of the text + i I - the inside edge--near the binding (if "[twoside]" document) + o O - the outside edge--far from the binding + +You should specify one code only, not a list. The figure or table must +be on one side or the other; it cannot be in the middle with text on +both sides. The "i" and "o" options refer to the inside and outside of +the whole page, not individual columns. + +The ability to float is somewhat restricted, and you will get best results +by giving exact manual placement, but floating is more convenient while +revising the document. Any changes to the formatting can ruin your manual +positioning so you should adjust the placement just before printing a +final copy. Here are some tips for good placement: + + - The environment should be placed so as to not run over a page break. + + - The environment must not be placed in special places like lists. + + - For esthetic reasons, only plain text should wrap around the figure. + Section titles and big equations look bad; lists are bad if the figure + is on the left. (All these function properly, they just don't look + very good.) Small equations look fine. + + - It is convenient to begin the environment between paragraphs, but if + you want placement in the middle of a paragraph, you must put the + environment between two words where there is a natural line break. + +When floating, \LaTeX\ tries to apply these rules. More specifically, +a floated wrapping environment will only begin... + + - at the beginning of a paragraph, + + - when there is enough room on the page, or it is possible to go on + the next page, + + - if the `paragraph' is not in a section title or a list, + + - if the paragraph is not wrapping around another figure, + + - in the main text (not in a minipage etc.) + +It is possible that a non-floating wrapfigure will be forced to float +when an earlier one is still being processed. A warning will be written +in that case. You can have more information about the floating process +written to the log file by specifying "\usepackage[verbose]{wrapfig}". + +If there is a lot of flexibility on a page, a floating wrapfigure may +be placed badly; you must turn to manual placement. A rare problem is +that floats and footnotes specified within the wrapping text can also +cause poor placement and bad formatting. + + +\section {Sizing and optional overhang} + +Parameter "#4" (the second required parameter) is the width of the figure +or table. Given the way that \LaTeX\ puts just about everything into boxes +with the current line-width, the width parameter will take precedence over +whatever natural width the figure has. In particular, the caption is always +typeset with the specified width. If the figure is wider than the space +allotted, you will get an ``overfull box'' warning. + +However, if you specify a width of *zero* ("0pt"), the actual width of +the figure will determine the wrapping width. A following "\caption" +should have the same width as the figure, but it might fail badly; it +is safer to specify a width when you use a caption. + +\LaTeX\ will wrap surrounding text around the figure, leaving a gap of +"\intextsep" at the top and bottom, and "\columsep" at the side, by +producing a series of shortened text lines beside the figure. The +indentation (shortening) of the text is the figure width plus "\columnsep" +minus overhang (if any; see below). + +\LaTeX\ calculates the number of short lines needed based on the height +of the figure and the length "\intextsep". You can override this guess +by giving the first optional argument (parameter "#1") specifying the +number of shortened lines (counting each displayed equation as 3 lines). +This is particularly useful when the surrounding text contains extra +vertical spacing that is not accounted for automatically. + +The second optional parameter ("#3") tells how much the figure should +hang out into the margin. The default overhang is given by the length +"\wrapoverhang", which is "0pt" normally but can be changed using +"\setlength". For example, to have all wrapfigures use the space +reserved for marginal notes, + + \setlength{\wrapoverhang}{\marginparwidth} + \addtolength{\wrapoverhang}{\marginparsep} + +When you do specify the overhang explicitly for a particular figure, you +can use a special unit called "\width" meaning the width of the figure. +For example, "[0.5\width]" makes the center of the figure sit on the +edge of the text, and "[\width]" puts the figure entirely in the margin +(and the adjacent text is indented by just "\columnsep"). This "\width" +is the actual width of the wrapfigure, which may be greater than the +declared width. + + +\section{Some Random Implementation Notes} + +Unfortunately, \LaTeX's system of setting "\everypar" and "\par" is +unable to coexist peacefully with a wrapping environment, so I was +forced to subvert the "\@setpar" mechanism and "\everypar". ("\everypar" +is already subverted once by NFSS.) + +When checking the room left on the page, remember that if there is less +than "\baselineskip" the new paragraph will begin on the next page, even +if there is no page stretch. If non-floating, I force a bad page break +rather than have the figure hang into the bottom margin. + +Here are notes on various variables and some macros; what info they +store and how they are used. + + \WF@wli - number-of-wrapped-lines parameter, saved for start of wrapping. + Set globally by "\WF@wr" (set empty if no optional parameter given). + The floating mechanism ignores this and uses the real size. + + \WF@ovh - margin overhang set globally by "\WF@rapt", saved until placing + figure (but not reset). Actually, the setting is very tricky so that + the expected values are used when a figure floats. First, the expression + is saved without evaluation by "\WF@rapt" ("\begin{wrapfigure}") because + "\width" is still unknown. Soon after that, "\endwrapfigure" executes + "\WF@ovh" to evaluate the overhang and save the result (so that changes + to "\wrapoverhang" while this figure is floating won't affect this + figure). Finally, it is used by "\WF@putfigmaybe" when printing the fig. + + \WF@place - a macro that is used as a number, giving the placement code. + It might start out as "`I" and later be converted to "114" (r). + + \WF@box - tested for void at "\begin{wrapfigure}", to avoid collisions, + by "\everypar" to do floating, and by "\WF@finale" before resetting + "\everypar". Voided globally when used by "\WF@putfigmaybe" (or by + "\WF@wr" if an old figure must be dumped prematurely). + + \par - test if it is "\@@par" by "\begin{wrapfigure}" and "\WF@floathand" + to float past special environments. It is set to "\@par" ("\WF@mypar") + by "\WF@startwrapping", and restored by an end-group (bad!) or by + "\WF@finale" (good). It is protected from change by redefining + "\@setpar". + + \parshape - let to "\WF@fudgeparshape" by "\WF@startwrapping", so lists + will continue wrapping; "\@@parshape" preserves the real "\parshape" + command, and it is restored by "\WF@finale" or "\@parboxrestore". + "\WF@floathand" and "\WF@wr" test if old wrapping is still in progress + with "\ifx\parshape\WF@fudgeparshape". The value of "\@@parshape" is + also tested to float past lists and other wrapping environments. + + \hangindent - tested to float past section titles etc. + + \c@WF@wrappedlines - the number of shortened lines + 1; set globally by + "\WF@startwrapping" and decremented by "\par" ("\WF@mypar"). It is > 1 + only when wrapping is incomplete. "\WF@wraphand", "\WF@fudgeparshape", + and "\WF@mypar" test the number for calling "\WF@finale". It may get + stuck at some high value if "\par" is restored by an end-group, (and + wrapping is terminated prematurely) so it is unwise to use this as a + test for wrapping-complete. + + \pagetotal - one of many parameters used to compute floating. When + putting a wrapfigure in a parbox, I assign "\let\pagetotal\maxdimen" + (locally!) to signal not-top-of-page and no floating. + + \WF@pspars - the "\parshape" parameters as LaTeX sets them for lists + ("\WF@fudgeparshape"); when wrapping I test it and use it to modify my + own real params for the paragraph. They are also used when "\parshape" + is restored after wrapping. + + \WF@finale - is performed by "\par" when wrapping should end. However, + that might happen inside a group (a list especially), so the subverted + versions of "\par", "\parshape" etc. will be reinstated when the group + ends. Thus, they must themselves test "\c@WF@wrappedlines" < 2 to see + when wrapping is over, and if so, they should just do "\WF@finale" again. + +These are the tests to see if a floating wrapfigure will fit at a particular +spot. These tests are performed at the beginning of every paragraph after +the figure, except in lists etc. ("\pagegoal" - "\pagetotal" is the room +left on the page.) + + > + room_left := \pagegoal - \pagetotal + if room_left < 0 then page overfull already: put figure (on next page) + else + if figure_size > room_left then does not fit + if max(min_stretch, \pagestretch) + extra > room_left + then page can stretch until full: put figure (at top of next page) + fi + else figure fits: put figure + fi fi + < + +Even if a wrapfigure is not floating, it will go through the same logic +to generate a "\pagebreak", and maybe an underfull page, when the current +page can stretch until full. The "min_stretch" depends on whether it is +floating or not: ".5\baselineskip" (floating) "2\baselineskip" (not). The +"extra" is ".5\baselineskip" in either case. These values can be adjusted. + +There are some other `magic numbers' for floating that aren't really so +special, but you must change them together if you change them at all. +To make floating wrapfigures float less and fit on pages more frequently, +but not change the number of wrapped lines, decrease the "1.5" in +"\global\advance\WF@size1.5\baselineskip" and increase the "1.1" in +"\advance\WF@size1.1\baselineskip" by the same amount (and vice versa). +To make more (or fewer) wrapped lines for the same size figure, without +changing the floating, change "1.1" in "\advance\WF@size1.1\baselineskip" +unilaterally. + +%%%%% ----- End Instructions ----- %%%%% + +Test file integrity: ASCII 32-57, 58-126: !"#$%&'()*+,-./0123456789 +:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ diff --git a/ThirdParty/Ert/python/ecl/__init__.py b/ThirdParty/Ert/python/ecl/__init__.py index 50cb5823bd..f60dd2b8c6 100644 --- a/ThirdParty/Ert/python/ecl/__init__.py +++ b/ThirdParty/Ert/python/ecl/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file '__init__.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/ecl_type.py b/ThirdParty/Ert/python/ecl/ecl_type.py index 330d636a9a..69537a9a6b 100644 --- a/ThirdParty/Ert/python/ecl/ecl_type.py +++ b/ThirdParty/Ert/python/ecl/ecl_type.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'ecl_type.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/ecl_util.py b/ThirdParty/Ert/python/ecl/ecl_util.py index 3835d3e5ae..e6edce0351 100644 --- a/ThirdParty/Ert/python/ecl/ecl_util.py +++ b/ThirdParty/Ert/python/ecl/ecl_util.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_util.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/__init__.py b/ThirdParty/Ert/python/ecl/eclfile/__init__.py index c98633910f..a183ea32b6 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/__init__.py +++ b/ThirdParty/Ert/python/ecl/eclfile/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_3d_file.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_3d_file.py index 0d462a7636..90156ac322 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_3d_file.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_3d_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_3dkw.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_3dkw.py index f19d01f171..6db3647849 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_3dkw.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_3dkw.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'ecl_3dkw.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_file.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_file.py index 75ac344456..ca96e6cdc3 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_file.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_file.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py index ccb29032fa..1c6f02345d 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_init_file.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_init_file.py index 51ae032143..e15df9dab3 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_init_file.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_init_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'ecl_init_file.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py index d5cd61dcad..6a47ddecc5 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_kw.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_restart_file.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_restart_file.py index bdd2e33e8f..d09f179d65 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_restart_file.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_restart_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'ecl_restart_file.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/eclfile/fortio.py b/ThirdParty/Ert/python/ecl/eclfile/fortio.py index e454a9b8b0..d32e501990 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/fortio.py +++ b/ThirdParty/Ert/python/ecl/eclfile/fortio.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'fortio.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/gravimetry/__init__.py b/ThirdParty/Ert/python/ecl/gravimetry/__init__.py index f218261dda..16881ceaba 100644 --- a/ThirdParty/Ert/python/ecl/gravimetry/__init__.py +++ b/ThirdParty/Ert/python/ecl/gravimetry/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav.py b/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav.py index f8d75a3822..41171d94fe 100644 --- a/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav.py +++ b/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_grav.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav_calc.py b/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav_calc.py index c00a1e714b..58dd878724 100644 --- a/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav_calc.py +++ b/ThirdParty/Ert/python/ecl/gravimetry/ecl_grav_calc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/gravimetry/ecl_subsidence.py b/ThirdParty/Ert/python/ecl/gravimetry/ecl_subsidence.py index 890e4e5ccc..a9073c4d80 100644 --- a/ThirdParty/Ert/python/ecl/gravimetry/ecl_subsidence.py +++ b/ThirdParty/Ert/python/ecl/gravimetry/ecl_subsidence.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_subsidence.py' is part of ERT - Ensemble based # Reservoir Tool. @@ -49,6 +49,7 @@ class EclSubsidence(BaseCClass): _add_survey_PRESSURE = EclPrototype("void* ecl_subsidence_add_survey_PRESSURE( ecl_subsidence , char* , ecl_file_view )") _eval = EclPrototype("double ecl_subsidence_eval( ecl_subsidence , char* , char* , ecl_region , double , double , double, double, double)") _eval_geertsma = EclPrototype("double ecl_subsidence_eval_geertsma( ecl_subsidence , char* , char* , ecl_region , double , double , double, double, double, double)") + _eval_geertsma_rporv = EclPrototype("double ecl_subsidence_eval_geertsma_rporv( ecl_subsidence , char* , char* , ecl_region , double , double , double, double, double, double)") _has_survey = EclPrototype("bool ecl_subsidence_has_survey( ecl_subsidence , char*)") def __init__( self, grid, init_file ): @@ -103,6 +104,17 @@ class EclSubsidence(BaseCClass): return self._eval_geertsma(base_survey, monitor_survey, region, pos[0], pos[1], pos[2], youngs_modulus, poisson_ratio, seabed) + def eval_geertsma_rporv(self, base_survey, monitor_survey, pos, youngs_modulus, poisson_ratio, seabed, region=None): + if not base_survey in self: + raise KeyError("No such survey: %s" % base_survey) + + if monitor_survey is not None: + if not monitor_survey in self: + raise KeyError("No such survey: %s" % monitor_survey) + + return self._eval_geertsma_rporv(base_survey, monitor_survey, region, pos[0], pos[1], pos[2], youngs_modulus, poisson_ratio, seabed) + + def eval(self, base_survey, monitor_survey, pos, compressibility, poisson_ratio, region=None): """ Calculates the subsidence change between two surveys. diff --git a/ThirdParty/Ert/python/ecl/grid/__init__.py b/ThirdParty/Ert/python/ecl/grid/__init__.py index 69d110e0bf..b262c5b381 100644 --- a/ThirdParty/Ert/python/ecl/grid/__init__.py +++ b/ThirdParty/Ert/python/ecl/grid/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/cell.py b/ThirdParty/Ert/python/ecl/grid/cell.py index 5824d6fc47..ee6949624e 100644 --- a/ThirdParty/Ert/python/ecl/grid/cell.py +++ b/ThirdParty/Ert/python/ecl/grid/cell.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/ecl_grid.py b/ThirdParty/Ert/python/ecl/grid/ecl_grid.py index 9afc3acd30..e8b662b006 100644 --- a/ThirdParty/Ert/python/ecl/grid/ecl_grid.py +++ b/ThirdParty/Ert/python/ecl/grid/ecl_grid.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_grid.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/ecl_grid_generator.py b/ThirdParty/Ert/python/ecl/grid/ecl_grid_generator.py index 7bdf798bd3..66d4eec2a3 100644 --- a/ThirdParty/Ert/python/ecl/grid/ecl_grid_generator.py +++ b/ThirdParty/Ert/python/ecl/grid/ecl_grid_generator.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'ecl_grid_generator.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/ecl_region.py b/ThirdParty/Ert/python/ecl/grid/ecl_region.py index 295f0e59f9..db1a0bc092 100644 --- a/ThirdParty/Ert/python/ecl/grid/ecl_region.py +++ b/ThirdParty/Ert/python/ecl/grid/ecl_region.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_region.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault.py b/ThirdParty/Ert/python/ecl/grid/faults/fault.py index ac5ef42acb..986b6288ba 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_block.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_block.py index e5313170a7..0757b9e4eb 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_block.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_block.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault_block.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_block_collection.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_block_collection.py index 16166c3ea6..bc4ad438c6 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_block_collection.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_block_collection.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault_block_collection.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_block_layer.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_block_layer.py index cc84d65981..e51e889c19 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_block_layer.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_block_layer.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault_block_layer.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_collection.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_collection.py index 704c5fad87..755ff90d58 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_collection.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_collection.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault_collection.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_line.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_line.py index 10ef3da0e8..cbd9b7a67b 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_line.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_line.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'fault_line.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/fault_segments.py b/ThirdParty/Ert/python/ecl/grid/faults/fault_segments.py index 7949a44d0e..b7af6ea97f 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/fault_segments.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/fault_segments.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014. Statoil ASA, Norway. +# Copyright (C) 2014. Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/grid/faults/layer.py b/ThirdParty/Ert/python/ecl/grid/faults/layer.py index 855f8f6be0..dc8df60a29 100644 --- a/ThirdParty/Ert/python/ecl/grid/faults/layer.py +++ b/ThirdParty/Ert/python/ecl/grid/faults/layer.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'layer.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/rft/__init__.py b/ThirdParty/Ert/python/ecl/rft/__init__.py index d4efcd32c0..ac830d914b 100644 --- a/ThirdParty/Ert/python/ecl/rft/__init__.py +++ b/ThirdParty/Ert/python/ecl/rft/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/rft/ecl_rft.py b/ThirdParty/Ert/python/ecl/rft/ecl_rft.py index 38411dfd4b..493fa47727 100644 --- a/ThirdParty/Ert/python/ecl/rft/ecl_rft.py +++ b/ThirdParty/Ert/python/ecl/rft/ecl_rft.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_rft.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -53,8 +53,6 @@ class EclRFT(BaseCClass): _get_date = EclPrototype("time_t ecl_rft_node_get_date( ecl_rft )") _get_size = EclPrototype("int ecl_rft_node_get_size( ecl_rft )") _iget_cell = EclPrototype("void* ecl_rft_node_iget_cell( ecl_rft )") - _iget_cell_sorted = EclPrototype("void* ecl_rft_node_iget_cell_sorted( ecl_rft )") - _sort_cells = EclPrototype("void* ecl_rft_node_inplace_sort_cells( ecl_rft )") _iget_depth = EclPrototype("double ecl_rft_node_iget_depth( ecl_rft )") _iget_pressure = EclPrototype("double ecl_rft_node_iget_pressure(ecl_rft)") _iget_ijk = EclPrototype("void ecl_rft_node_iget_ijk( ecl_rft , int , int*, int*, int*)") @@ -165,6 +163,9 @@ class EclRFT(BaseCClass): The return value from the __getitem__() method is either an EclRFTCell instance or a EclPLTCell instance, depending on the type of this particular RFT object. + + For MSW wells the cells will come in sorted order along the wellpath, + for other well types the cells will come sorted in input order. """ self.assert_cell_index( index ) cell_ptr = self._iget_cell( index ) @@ -175,46 +176,6 @@ class EclRFT(BaseCClass): return self[index] - def iget_sorted( self , index ): - """ - Will return the cell nr @index in the list of sorted cells. - - See method sort() for further documentation. - """ - self.assert_cell_index( index ) - cell_ptr = self._iget_cell_sorted( index ) - return self.__cell_ref( cell_ptr ) - - - def sort(self): - """ - Will sort cells in RFT; currently only applies to MSW wells. - - By default the cells in the RFT come in the order they are - specified in the ECLIPSE input file; that is not necessarily - in a suitable order. In the case of MSW wells it is possible - to sort the connections after distance along the wellpath. To - access the cells in sort order you have two options: - - 1. Sort the cells using the sort() method, and then - subsequently access them sequentially: - - rft.sort() - for cell in rft: - print cell - - 2. Let the rft object stay unsorted, but access the cells - using the iget_sorted() method: - - for i in range(len(rft)): - cell = rft.iget_sorted( i ) - - Currently only MSW/PLTs are sorted, based on the CONLENST - keyword; for other wells the sort() method does nothing. - """ - self._sort_cells( ) - - # ijk are zero offset def ijkget( self , ijk ): """ diff --git a/ThirdParty/Ert/python/ecl/rft/ecl_rft_cell.py b/ThirdParty/Ert/python/ecl/rft/ecl_rft_cell.py index 13a80cc4b6..ae01fb1ff6 100644 --- a/ThirdParty/Ert/python/ecl/rft/ecl_rft_cell.py +++ b/ThirdParty/Ert/python/ecl/rft/ecl_rft_cell.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_rft_cell.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/rft/well_trajectory.py b/ThirdParty/Ert/python/ecl/rft/well_trajectory.py index abe0cadcd5..7df3a76c80 100644 --- a/ThirdParty/Ert/python/ecl/rft/well_trajectory.py +++ b/ThirdParty/Ert/python/ecl/rft/well_trajectory.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'well_trajectory.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/__init__.py b/ThirdParty/Ert/python/ecl/summary/__init__.py index 946fcf6e8d..064164accf 100644 --- a/ThirdParty/Ert/python/ecl/summary/__init__.py +++ b/ThirdParty/Ert/python/ecl/summary/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_cmp.py b/ThirdParty/Ert/python/ecl/summary/ecl_cmp.py index ce705d20e7..dfbcf626a2 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_cmp.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_cmp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'ecl_cmp.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_npv.py b/ThirdParty/Ert/python/ecl/summary/ecl_npv.py index 67363f2669..3f1fbe42ad 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_npv.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_npv.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'ecl_npv.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -136,7 +136,7 @@ class NPVPriceVector(object): class EclNPV(object): - sumKeyRE = re.compile("[[]([\w:,]+)[]]") + sumKeyRE = re.compile("[\[]([\w:,]+)[\]]") def __init__(self, baseCase): diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py b/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py index 893eb66162..676515bd1d 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py @@ -1,4 +1,4 @@ -# Copyright (C) 2016 Statoil ASA, Norway. +# Copyright (C) 2016 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum.py index 029334836a..f721ee9dee 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_sum.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -26,6 +26,8 @@ import numpy import datetime import os.path import ctypes +import pandas +import re # Observe that there is some convention conflict with the C code # regarding order of arguments: The C code generally takes the time @@ -90,7 +92,7 @@ class EclSum(BaseCClass): _fread_alloc = EclPrototype("void* ecl_sum_fread_alloc(char*, stringlist, char*, bool)", bind=False) _create_restart_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_restart_writer2(char*, char*, int, bool, bool, char*, time_t, bool, int, int, int)", bind = False) _create_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_writer(char*, bool, bool, char*, time_t, bool, int, int, int)", bind = False) - _resample = EclPrototype("ecl_sum_obj ecl_sum_alloc_resample( ecl_sum, char*, time_t_vector)") + _resample = EclPrototype("ecl_sum_obj ecl_sum_alloc_resample( ecl_sum, char*, time_t_vector, bool, bool)") _iiget = EclPrototype("double ecl_sum_iget(ecl_sum, int, int)") _free = EclPrototype("void ecl_sum_free(ecl_sum)") _data_length = EclPrototype("int ecl_sum_get_data_length(ecl_sum)") @@ -303,9 +305,8 @@ class EclSum(BaseCClass): raise TypeError('Parameter sim_days should be float, was %r' % sim_days) sim_seconds = sim_days * 24 * 60 * 60 - - return self._add_tstep(report_step, sim_seconds).setParent(parent=self) - + tstep = self._add_tstep(report_step, sim_seconds).setParent(parent=self) + return tstep @@ -500,7 +501,6 @@ class EclSum(BaseCClass): .... """ from ecl.summary import EclSumKeyWordVector - import pandas if column_keys is None: keywords = EclSumKeyWordVector(self, add_keywords = True) else: @@ -524,6 +524,61 @@ class EclSum(BaseCClass): frame = pandas.DataFrame(index = time_index, columns=list(keywords), data=data) return frame + @staticmethod + def _compile_headers_list(headers, dims): + var_list = [] + for key in headers: + lst = re.split(':', key) + kw = lst[0] + wgname = None + num = 0; + unit = "UNIT" + if len(lst) > 1: + nums = [] + if lst[1][0].isdigit(): + nums = re.split(',', lst[1]) + else: + wgname = lst[1] + if len(lst) == 3: + nums = re.split(",", lst[2]) + if len(nums) == 3: + i = int(nums[0])-1 + j = int(nums[1])-1 + k = int(nums[2])-1 + if dims is None: + raise ValueError("For key %s When using indexing i,j,k you must supply a valid value for the dims argument" % key) + num = i + j * dims[0] + k * dims[0]*dims[1] + 1 + elif len(nums) == 1: + num = int(nums[0]) + + var_list.append( [kw, wgname, num, unit] ) + return var_list + + @classmethod + def from_pandas(cls, case, frame, dims = None, headers = None): + start_time = frame.index[0] + var_list = [] + if headers is None: + header_list = EclSum._compile_headers_list( frame.columns.values, dims ) + else: + header_list = EclSum._compile_headers_list( headers, dims ) + if dims is None: + dims = [1,1,1]; + ecl_sum = EclSum.writer(case, + start_time.to_pydatetime(), + dims[0], dims[1], dims[2]) + for kw, wgname, num, unit in header_list: + var_list.append( ecl_sum.addVariable( kw , wgname = wgname , num = num, unit =unit).getKey1() ) + + for i, time in enumerate(frame.index): + days = (time - start_time).days + t_step = ecl_sum.addTStep( i+1 , days ) + + for var in var_list: + t_step[var] = frame.iloc[i][var] + + return ecl_sum + def get_key_index(self, key): """ @@ -1481,8 +1536,12 @@ are advised to fetch vector as a numpy vector and then scale that yourself: - def resample(self, new_case_name, time_points): - return self._resample(new_case_name, time_points) + def resample(self, new_case_name, time_points, lower_extrapolation=False, upper_extrapolation=False): + new_case = self._resample(new_case_name, time_points, lower_extrapolation, upper_extrapolation) + if new_case is None: + raise ValueError("Failed to create new resampled case:{}".format(new_case_name)) + + return new_case import ecl.summary.ecl_sum_keyword_vector diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_keyword_vector.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_keyword_vector.py index a3fc4c12a6..466106bfcc 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_keyword_vector.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_keyword_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ecl_sum_keyword_vector.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_tstep.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_tstep.py index 0b165e6e0a..1fa471619b 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_tstep.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_tstep.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_var_type.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_var_type.py index 039105f497..3d19a9eff3 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_var_type.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_var_type.py @@ -1,4 +1,4 @@ -# Copyright (C) 2016 Statoil ASA, Norway. +# Copyright (C) 2016 Equinor ASA, Norway. # # The file 'ecl_sum_var_type.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py index 8c7a614eef..3feff8d326 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # @@ -46,7 +46,7 @@ class EclSumVector(object): self.__dates = parent.get_dates(report_only) self.__days = parent.get_days(report_only) - self.__mpl_dates = parent.get_mpl_dates(report_only) + self.__numpy_dates = parent.numpy_dates self.__report_step = parent.get_report_step(report_only) self.__values = None @@ -99,8 +99,21 @@ class EclSumVector(object): def mpl_dates(self): """ All the dates as numpy vector of dates in matplotlib format. + This property will be replaced by numpy_dates, but is kept for + backwards-compatibility for the time-being. Usage will trigger + a depreciation warning. """ - return self.__mpl_dates + warnings.warn("The mpl_dates property has been deprecated - use numpy_dates instead", + DeprecationWarning) + + return self.parent.get_mpl_dates(self.report_only) + + @property + def numpy_dates(self): + """ + All the dates as numpy vector of dates in numpy format. + """ + return self.__numpy_dates @property def report_step(self): @@ -119,7 +132,7 @@ class EclSumVector(object): return EclSumNode(self.__report_step[index], self.__days[index], self.__dates[index], - self.__mpl_dates[index], + self.mpl_dates[index], self.__values[index]) diff --git a/ThirdParty/Ert/python/ecl/util/geometry/__init__.py b/ThirdParty/Ert/python/ecl/util/geometry/__init__.py index e4bc012dc9..d970567ebe 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/__init__.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file '__init__.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/geometry/cpolyline.py b/ThirdParty/Ert/python/ecl/util/geometry/cpolyline.py index 227413182b..550bd68bcb 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/cpolyline.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/cpolyline.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/geometry/cpolyline_collection.py b/ThirdParty/Ert/python/ecl/util/geometry/cpolyline_collection.py index 335f3092b6..814900cca1 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/cpolyline_collection.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/cpolyline_collection.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'cpolyline_collection.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/geometry/geo_pointset.py b/ThirdParty/Ert/python/ecl/util/geometry/geo_pointset.py index 6286de3eef..501af9e451 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/geo_pointset.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/geo_pointset.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/geometry/geo_region.py b/ThirdParty/Ert/python/ecl/util/geometry/geo_region.py index 9d4e290147..fab03e64c9 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/geo_region.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/geo_region.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/geometry/surface.py b/ThirdParty/Ert/python/ecl/util/geometry/surface.py index ba610cb9bc..8152b1cc08 100644 --- a/ThirdParty/Ert/python/ecl/util/geometry/surface.py +++ b/ThirdParty/Ert/python/ecl/util/geometry/surface.py @@ -1,4 +1,4 @@ -# Copyright (C) 2016 Statoil ASA, Norway. +# Copyright (C) 2016 Equinor ASA, Norway. # # The file 'surface' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/test/CMakeLists.txt b/ThirdParty/Ert/python/ecl/util/test/CMakeLists.txt index 4d87b9efca..50c2a9bd09 100644 --- a/ThirdParty/Ert/python/ecl/util/test/CMakeLists.txt +++ b/ThirdParty/Ert/python/ecl/util/test/CMakeLists.txt @@ -6,7 +6,6 @@ set(PYTHON_SOURCES test_run.py source_enumerator.py test_area.py - temp_area.py path_context.py lint_test_case.py import_test_case.py diff --git a/ThirdParty/Ert/python/ecl/util/test/__init__.py b/ThirdParty/Ert/python/ecl/util/test/__init__.py index 1cc89f8d32..ab79dd25d9 100644 --- a/ThirdParty/Ert/python/ecl/util/test/__init__.py +++ b/ThirdParty/Ert/python/ecl/util/test/__init__.py @@ -3,7 +3,6 @@ from .test_run import path_exists from .extended_testcase import ExtendedTestCase from .source_enumerator import SourceEnumerator from .test_area import TestArea , TestAreaContext -from .temp_area import TempArea , TempAreaContext from .ert_test_runner import ErtTestRunner from .path_context import PathContext from .lint_test_case import LintTestCase diff --git a/ThirdParty/Ert/python/ecl/util/test/ecl_mock/ecl_sum_mock.py b/ThirdParty/Ert/python/ecl/util/test/ecl_mock/ecl_sum_mock.py index 9fc8b7a8b1..3096791654 100644 --- a/ThirdParty/Ert/python/ecl/util/test/ecl_mock/ecl_sum_mock.py +++ b/ThirdParty/Ert/python/ecl/util/test/ecl_mock/ecl_sum_mock.py @@ -39,8 +39,10 @@ def createEclSum( case, days = time_offset + report_step * report_step_length + mini_step * mini_step_length t_step = ecl_sum.addTStep( report_step + 1 , sim_days = days ) + for var in var_list: key = var.getKey1( ) + if key in func_table: func = func_table[key] t_step[key] = func( days ) diff --git a/ThirdParty/Ert/python/ecl/util/test/ert_test_context.py b/ThirdParty/Ert/python/ecl/util/test/ert_test_context.py index dd89c5a720..931578ac79 100644 --- a/ThirdParty/Ert/python/ecl/util/test/ert_test_context.py +++ b/ThirdParty/Ert/python/ecl/util/test/ert_test_context.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'test_work_area.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/test/import_test_case.py b/ThirdParty/Ert/python/ecl/util/test/import_test_case.py index 13b940d49b..089107f2b7 100644 --- a/ThirdParty/Ert/python/ecl/util/test/import_test_case.py +++ b/ThirdParty/Ert/python/ecl/util/test/import_test_case.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/test/lint_test_case.py b/ThirdParty/Ert/python/ecl/util/test/lint_test_case.py index ff3bd729d6..3b27225384 100644 --- a/ThirdParty/Ert/python/ecl/util/test/lint_test_case.py +++ b/ThirdParty/Ert/python/ecl/util/test/lint_test_case.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/test/temp_area.py b/ThirdParty/Ert/python/ecl/util/test/temp_area.py deleted file mode 100644 index 4b7d2aa697..0000000000 --- a/ThirdParty/Ert/python/ecl/util/test/temp_area.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (C) 2016 Statoil ASA, Norway. -# -# The file 'temp_area.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 -# for more details. - -import os -import os.path -from ecl import EclPrototype -from . import TestArea - -class TempArea(TestArea): - """TempArea class is essentially similar to the TestArea class, with - the only difference that the cwd is *not* changed into the newly - created area. - """ - - _temp_area_alloc = EclPrototype("void* temp_area_alloc( char* )" , bind = False) - _temp_area_alloc_relative = EclPrototype("void* temp_area_alloc_relative( char* , char* )" , bind = False) - - def __init__(self, name, prefix = None , store_area=False): - if prefix: - if os.path.exists( prefix ): - c_ptr = self._temp_area_alloc_relative(prefix , name) - else: - raise IOError("The prefix path:%s must exist" % prefix) - else: - c_ptr = self._temp_area_alloc(name) - super(TempArea, self).__init__(name , c_ptr = c_ptr , store_area = store_area) - - - def __str__(self): - return self.getPath() - - - def get_cwd(self): - """ - Since the TempArea class does *not* change the cwd this method - just returns the ordinary os.getcwd(). - """ - return os.getcwd() - - - def getPath(self): - """ - Will return the full path to the temporary working area. - """ - return self._get_cwd( ) - - - -class TempAreaContext(object): - def __init__(self, name, prefix = None , store_area=False): - self.name = name - self.store_area = store_area - self.prefix = prefix - - def __enter__(self): - """ - @rtype: TempArea - """ - self.temp_area = TempArea(self.name, prefix = self.prefix , store_area = self.store_area ) - return self.temp_area - - - def __exit__(self, exc_type, exc_val, exc_tb): - del self.temp_area - return False - - - diff --git a/ThirdParty/Ert/python/ecl/util/test/test_area.py b/ThirdParty/Ert/python/ecl/util/test/test_area.py index 22089bd86c..929bae6ff2 100644 --- a/ThirdParty/Ert/python/ecl/util/test/test_area.py +++ b/ThirdParty/Ert/python/ecl/util/test/test_area.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'test_work_area.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -20,8 +20,7 @@ from ecl import EclPrototype class TestArea(BaseCClass): - _test_area_alloc = EclPrototype("void* test_work_area_alloc( char* )" , bind = False) - _test_area_alloc_relative = EclPrototype("void* test_work_area_alloc_relative( char* , char* )" , bind = False) + _test_area_alloc = EclPrototype("void* test_work_area_alloc__( char*, bool )" , bind = False) _free = EclPrototype("void test_work_area_free( test_area )") _install_file = EclPrototype("void test_work_area_install_file( test_area , char* )") _copy_directory = EclPrototype("void test_work_area_copy_directory( test_area , char* )") @@ -31,22 +30,13 @@ class TestArea(BaseCClass): _copy_parent_content = EclPrototype("void test_work_area_copy_parent_content( test_area , char* )") _get_cwd = EclPrototype("char* test_work_area_get_cwd( test_area )") _get_original_cwd = EclPrototype("char* test_work_area_get_original_cwd( test_area )") - _set_store = EclPrototype("void test_work_area_set_store( test_area , bool)") - _sync = EclPrototype("void test_work_area_sync( test_area )") - def __init__(self, test_name, prefix = None , store_area=False , c_ptr = None): + def __init__(self, test_name, store_area=False , c_ptr = None): if c_ptr is None: - if prefix: - if os.path.exists( prefix ): - c_ptr = self._test_area_alloc_relative(prefix , test_name) - else: - raise IOError("The prefix path:%s must exist" % prefix) - else: - c_ptr = self._test_area_alloc(test_name) + c_ptr = self._test_area_alloc(test_name, store_area) super(TestArea, self).__init__(c_ptr) - self.set_store( store_area ) def get_original_cwd(self): @@ -111,10 +101,6 @@ class TestArea(BaseCClass): self._free() - def set_store(self, store): - self._set_store(store) - - def getFullPath(self , path): if not os.path.exists( path ): raise IOError("Path not found:%s" % path) @@ -125,22 +111,17 @@ class TestArea(BaseCClass): return os.path.join( self.get_cwd() , path ) - def sync(self): - return self._sync( ) - - class TestAreaContext(object): - def __init__(self, test_name, prefix = None , store_area=False): + def __init__(self, test_name, store_area=False): self.test_name = test_name self.store_area = store_area - self.prefix = prefix def __enter__(self): """ @rtype: TestArea """ - self.test_area = TestArea(self.test_name, prefix = self.prefix , store_area = self.store_area ) + self.test_area = TestArea(self.test_name, store_area = self.store_area ) return self.test_area diff --git a/ThirdParty/Ert/python/ecl/util/test/test_run.py b/ThirdParty/Ert/python/ecl/util/test/test_run.py index 496353ba4d..b32a8f45c5 100644 --- a/ThirdParty/Ert/python/ecl/util/test/test_run.py +++ b/ThirdParty/Ert/python/ecl/util/test/test_run.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'test_run.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/__init__.py b/ThirdParty/Ert/python/ecl/util/util/__init__.py index aa5edf30b6..3960e7bfd2 100644 --- a/ThirdParty/Ert/python/ecl/util/util/__init__.py +++ b/ThirdParty/Ert/python/ecl/util/util/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file '__init__.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -71,7 +71,7 @@ from .cwd_context import CWDContext ### the process of changing camelCase function names to snake_case function ### names. ### -### See https://github.com/Statoil/libecl/issues/142 for a discussion and for +### See https://github.com/Equinor/libecl/issues/142 for a discussion and for ### usage. ### diff --git a/ThirdParty/Ert/python/ecl/util/util/arg_pack.py b/ThirdParty/Ert/python/ecl/util/util/arg_pack.py index 4b53e03b18..018cffcb48 100644 --- a/ThirdParty/Ert/python/ecl/util/util/arg_pack.py +++ b/ThirdParty/Ert/python/ecl/util/util/arg_pack.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'arg_pack.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/bool_vector.py b/ThirdParty/Ert/python/ecl/util/util/bool_vector.py index d688562682..cb68a2d013 100644 --- a/ThirdParty/Ert/python/ecl/util/util/bool_vector.py +++ b/ThirdParty/Ert/python/ecl/util/util/bool_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'vector_template.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/cthread_pool.py b/ThirdParty/Ert/python/ecl/util/util/cthread_pool.py index 39d8c3be91..30c923e8f3 100644 --- a/ThirdParty/Ert/python/ecl/util/util/cthread_pool.py +++ b/ThirdParty/Ert/python/ecl/util/util/cthread_pool.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'cthread_pool.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/ctime.py b/ThirdParty/Ert/python/ecl/util/util/ctime.py index 0c92ecd893..173f7c64ad 100644 --- a/ThirdParty/Ert/python/ecl/util/util/ctime.py +++ b/ThirdParty/Ert/python/ecl/util/util/ctime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'ctime.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/double_vector.py b/ThirdParty/Ert/python/ecl/util/util/double_vector.py index 9ba7100958..c9fa16d66f 100644 --- a/ThirdParty/Ert/python/ecl/util/util/double_vector.py +++ b/ThirdParty/Ert/python/ecl/util/util/double_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'double_vector.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/hash.py b/ThirdParty/Ert/python/ecl/util/util/hash.py index 3edc600763..62def2f3c3 100644 --- a/ThirdParty/Ert/python/ecl/util/util/hash.py +++ b/ThirdParty/Ert/python/ecl/util/util/hash.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'hash.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/int_vector.py b/ThirdParty/Ert/python/ecl/util/util/int_vector.py index f280603df8..34c6cd8415 100644 --- a/ThirdParty/Ert/python/ecl/util/util/int_vector.py +++ b/ThirdParty/Ert/python/ecl/util/util/int_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'int_vector.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/lookup_table.py b/ThirdParty/Ert/python/ecl/util/util/lookup_table.py index 4d01ba8732..3ebf71c5f5 100644 --- a/ThirdParty/Ert/python/ecl/util/util/lookup_table.py +++ b/ThirdParty/Ert/python/ecl/util/util/lookup_table.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'lookup_table.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/matrix.py b/ThirdParty/Ert/python/ecl/util/util/matrix.py deleted file mode 100644 index 160763987c..0000000000 --- a/ThirdParty/Ert/python/ecl/util/util/matrix.py +++ /dev/null @@ -1,230 +0,0 @@ - -# Copyright (C) 2011 Statoil ASA, Norway. -# -# The file 'matrix.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 -# for more details. - - -# The Matrix class implemented here wraps the C matrix implementation -# in matrix.c from the libutil library. The C matrix implementation -# has the very limited ambition of just barely satisfying the matrix -# needs of the EnKF algorithm, i.e. for general linear algebra -# applications you will probably be better served by a more complete -# matrix library. This applies even more so to this Python -# implementation; it is only here facilitate use of C libraries which -# expect a matrix instance as input (i.e. the LARS estimator). For -# general linear algebra in Python the numpy library is a natural -# choice. - - -from cwrap import BaseCClass,CFILE -from ecl import EclPrototype - - -class Matrix(BaseCClass): - _matrix_alloc = EclPrototype("void* matrix_alloc(int, int )" , bind = False) - _matrix_alloc_identity = EclPrototype("matrix_obj matrix_alloc_identity( int )" , bind = False) - _alloc_transpose = EclPrototype("matrix_obj matrix_alloc_transpose(matrix)") - _inplace_transpose = EclPrototype("void matrix_inplace_transpose(matrix)") - _copy = EclPrototype("matrix_obj matrix_alloc_copy(matrix)" ) - _sub_copy = EclPrototype("matrix_obj matrix_alloc_sub_copy(matrix, int , int , int , int)" ) - _free = EclPrototype("void matrix_free(matrix)") - _iget = EclPrototype("double matrix_iget( matrix , int , int )") - _iset = EclPrototype("void matrix_iset( matrix , int , int , double)") - _set_all = EclPrototype("void matrix_scalar_set( matrix , double)") - _scale_column = EclPrototype("void matrix_scale_column(matrix , int , double)") - _scale_row = EclPrototype("void matrix_scale_row(matrix , int , double)") - _copy_column = EclPrototype("void matrix_copy_column(matrix , matrix , int , int)" , bind = False) - _rows = EclPrototype("int matrix_get_rows(matrix)") - _columns = EclPrototype("int matrix_get_columns(matrix)") - _equal = EclPrototype("bool matrix_equal(matrix, matrix)") - _pretty_print = EclPrototype("void matrix_pretty_print(matrix, char*, char*)") - _fprint = EclPrototype("void matrix_fprintf(matrix, char*, FILE)") - _random_init = EclPrototype("void matrix_random_init(matrix, rng)") - _dump_csv = EclPrototype("void matrix_dump_csv(matrix, char*)") - - # Requires BLAS. If the library does not have the - # matrix_alloc_matmul() function the prototype will have _func = - # None, and NotImplementedError( ) will be raised int the - # __call__() method if we try to use this function. - try: - _alloc_matmul = EclPrototype("matrix_obj matrix_alloc_matmul(matrix, matrix)" , bind = False) - except AttributeError: - _alloc_matmul = None - - # Requires BLAS! - @classmethod - def matmul(cls, m1,m2): - """ - Will return a new matrix which is matrix product of m1 and m2. - """ - if m1.columns( ) == m2.rows( ): - return cls._alloc_matmul( m1, m2) - else: - raise ValueError("Matrix size mismatch") - - - def __init__(self, rows, columns, value=0): - c_ptr = self._matrix_alloc(rows, columns) - super(Matrix, self).__init__(c_ptr) - self.setAll(value) - - def copy(self): - return self._copy( ) - - @classmethod - def identity(cls, dim): - """Returns a dim x dim identity matrix.""" - if dim < 1: - raise ValueError('Identity matrix must have positive size, %d not allowed.' % dim) - return cls._matrix_alloc_identity(dim) - - def subCopy(self, row_offset, column_offset, rows, columns): - if row_offset < 0 or row_offset >= self.rows(): - raise ValueError("Invalid row offset") - - if column_offset < 0 or column_offset >= self.columns(): - raise ValueError("Invalid column offset") - - if row_offset + rows > self.rows(): - raise ValueError("Invalid rows") - - if column_offset + columns > self.columns(): - raise ValueError("Invalid columns") - - return self._sub_copy( row_offset , column_offset , rows , columns) - - - def __str__(self): - s = "" - for i in range(self.rows()): - s += "[" - for j in range(self.columns()): - d = self._iget(i, j) - s += "%6.3g " % d - s += "]\n" - return s - - def __getitem__(self, index_tuple): - if not 0 <= index_tuple[0] < self.rows(): - raise IndexError("Expected 0 <= %d < %d" % (index_tuple[0], self.rows())) - - if not 0 <= index_tuple[1] < self.columns(): - raise IndexError("Expected 0 <= %d < %d" % (index_tuple[1], self.columns())) - - return self._iget(index_tuple[0], index_tuple[1]) - - def __setitem__(self, index_tuple, value): - if not 0 <= index_tuple[0] < self.rows(): - raise IndexError("Expected 0 <= %d < %d" % (index_tuple[0], self.rows())) - - if not 0 <= index_tuple[1] < self.columns(): - raise IndexError("Expected 0 <= %d < %d" % (index_tuple[1], self.columns())) - - return self._iset(index_tuple[0], index_tuple[1], value) - - def dims(self): - return self._rows(), self._columns() - - def rows(self): - """ @rtype: int """ - return self._rows() - - def transpose(self , inplace = False): - """ - Will transpose the matrix. By default a transposed copy is returned. - """ - if inplace: - self._inplace_transpose( ) - return self - else: - return self._alloc_transpose( ) - - - def columns(self): - """ @rtype: int """ - return self._columns() - - def __eq__(self, other): - assert isinstance(other, Matrix) - return self._equal(other) - - def scaleColumn(self, column, factor): - if not 0 <= column < self.columns(): - raise IndexError("Expected column: [0,%d) got:%d" % (self.columns(), column)) - self._scale_column(column, factor) - - def scaleRow(self, row, factor): - if not 0 <= row < self.rows(): - raise IndexError("Expected row: [0,%d) got:%d" % (self.rows(), row)) - self._scale_row(row, factor) - - def setAll(self, value): - self._set_all(value) - - def copyColumn(self, target_column, src_column): - columns = self.columns() - if not 0 <= src_column < columns: - raise ValueError("src column:%d invalid" % src_column) - - if not 0 <= target_column < columns: - raise ValueError("target column:%d invalid" % target_column) - - if src_column != target_column: - # The underlying C function accepts column copy between matrices. - Matrix._copy_column(self, self, target_column, src_column) - - - def dumpCSV(self , filename): - self._dump_csv( filename ) - - - def prettyPrint(self, name, fmt="%6.3g"): - self._pretty_print(name, fmt) - - def fprint(self , fileH , fmt = "%g "): - """Will print ASCII representation of matrix. - - The fileH argument should point to an open Python - filehandle. If you supply a fmt string it is important that it - contains a separator, otherwise you might risk that elements - overlap in the output. For the matrix: - - [0 1 2] - m = [3 4 5] - [6 7 8] - - The code: - - with open("matrix.txt" , "w") as f: - m.fprintf( f ) - - The file 'matrix.txt' will look like: - - 0 1 2 - 3 4 5 - 6 7 8 - - """ - self._fprint( fmt , CFILE( fileH)) - - - def randomInit(self, rng): - self._random_init(rng) - - def free(self): - self._free() - - - diff --git a/ThirdParty/Ert/python/ecl/util/util/rng.py b/ThirdParty/Ert/python/ecl/util/util/rng.py index e03af1c3f2..ff46f30b0b 100644 --- a/ThirdParty/Ert/python/ecl/util/util/rng.py +++ b/ThirdParty/Ert/python/ecl/util/util/rng.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'rng.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/stringlist.py b/ThirdParty/Ert/python/ecl/util/util/stringlist.py index 19d4de759e..3c98a202de 100644 --- a/ThirdParty/Ert/python/ecl/util/util/stringlist.py +++ b/ThirdParty/Ert/python/ecl/util/util/stringlist.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'stringlist.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/time_vector.py b/ThirdParty/Ert/python/ecl/util/util/time_vector.py index cffcb411f8..d8e0425189 100644 --- a/ThirdParty/Ert/python/ecl/util/util/time_vector.py +++ b/ThirdParty/Ert/python/ecl/util/util/time_vector.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'vector_template.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/util_func.py b/ThirdParty/Ert/python/ecl/util/util/util_func.py index cb7cf236d6..40acc3385b 100644 --- a/ThirdParty/Ert/python/ecl/util/util/util_func.py +++ b/ThirdParty/Ert/python/ecl/util/util/util_func.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'util_func.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/util/util/vector_template.py b/ThirdParty/Ert/python/ecl/util/util/vector_template.py index ca4d1a506a..5693a64322 100644 --- a/ThirdParty/Ert/python/ecl/util/util/vector_template.py +++ b/ThirdParty/Ert/python/ecl/util/util/vector_template.py @@ -1,4 +1,4 @@ -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'vector_template.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ecl/well/well_info.py b/ThirdParty/Ert/python/ecl/well/well_info.py index 938341ace0..e8e3dcc6b5 100644 --- a/ThirdParty/Ert/python/ecl/well/well_info.py +++ b/ThirdParty/Ert/python/ecl/well/well_info.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/ert/test/__init__.py b/ThirdParty/Ert/python/ert/test/__init__.py index bacdd1adf8..743e58fc12 100644 --- a/ThirdParty/Ert/python/ert/test/__init__.py +++ b/ThirdParty/Ert/python/ert/test/__init__.py @@ -3,7 +3,6 @@ from ecl.util.test import path_exists from ecl.util.test import ExtendedTestCase from ecl.util.test import SourceEnumerator from ecl.util.test import TestArea , TestAreaContext -from ecl.util.test import TempArea , TempAreaContext from ecl.util.test import ErtTestRunner from ecl.util.test import PathContext from ecl.util.test import LintTestCase diff --git a/ThirdParty/Ert/python/tests/__init__.py b/ThirdParty/Ert/python/tests/__init__.py index 918cbb6acc..4fb12b1cca 100644 --- a/ThirdParty/Ert/python/tests/__init__.py +++ b/ThirdParty/Ert/python/tests/__init__.py @@ -23,12 +23,12 @@ def source_root(): # Decorator which is used to mark either an entire test class or individual -# test methods as requiring Statoil testdata. If Statoil testdata has not been +# test methods as requiring Equinor testdata. If Equinor testdata has not been # configured as part of the build process these tests will be skipped. # -# Ideally the statoil_test() implementation should just be a suitable wrapper of: +# Ideally the equinor_test() implementation should just be a suitable wrapper of: # -# skipUnless(EclTest.STATOIL_DATA, "Missing Statoil testdata") +# skipUnless(EclTest.EQUINOR_DATA, "Missing Equinor testdata") # # but that has been surprisingly difficult to achieve. The current # implemenation is based on the skip() function from the unittest/case.py @@ -42,32 +42,32 @@ def source_root(): # class, that is not required when decorating method: # # -# @statoil_test() -# class StatoilTest(EclTest): +# @equinor_test() +# class EquinorTest(EclTest): # # This test class will be skipped entirely if we do not have access to -# # Statoil testdata. +# # Equinor testdata. # # # class XTest(EclTest): # -# @statoil_test +# @equinor_test # def test_method(self): -def statoil_test(): +def equinor_test(): """ - Will mark a test method or an entire test class as dependent on Statoil testdata. + Will mark a test method or an entire test class as dependent on Equinor testdata. """ def decorator(test_item): if not isinstance(test_item, type): - if not EclTest.STATOIL_DATA: + if not EclTest.EQUINOR_DATA: @functools.wraps(test_item) def skip_wrapper(*args, **kwargs): - raise SkipTest("Missing Statoil testdata") + raise SkipTest("Missing Equinor testdata") test_item = skip_wrapper - if not EclTest.STATOIL_DATA: + if not EclTest.EQUINOR_DATA: test_item.__unittest_skip__ = True - test_item.__unittest_skip_why__ = "Missing Statoil testdata" + test_item.__unittest_skip_why__ = "Missing Equinor testdata" return test_item return decorator @@ -77,6 +77,6 @@ def statoil_test(): class EclTest(ExtendedTestCase): SOURCE_ROOT = source_root() TESTDATA_ROOT = os.path.join(SOURCE_ROOT, "test-data") - STATOIL_DATA = os.path.islink(os.path.join(TESTDATA_ROOT, "Statoil")) + EQUINOR_DATA = os.path.islink(os.path.join(TESTDATA_ROOT, "Equinor")) diff --git a/ThirdParty/Ert/python/tests/bin_tests/test_summary_resample.py b/ThirdParty/Ert/python/tests/bin_tests/test_summary_resample.py index c265382c00..d4e0db52b9 100644 --- a/ThirdParty/Ert/python/tests/bin_tests/test_summary_resample.py +++ b/ThirdParty/Ert/python/tests/bin_tests/test_summary_resample.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # @@ -60,6 +60,7 @@ class SummaryResampleTest(EclTest): with TestAreaContext(""): self.case.fwrite() + # Too few arguments with self.assertRaises(CallError): subprocess.check_call([self.script]) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt b/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt index 5196dd1016..eec263e163 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt +++ b/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt @@ -4,7 +4,7 @@ set(TEST_SOURCES test_ecl_ecl.py test_removed.py test_ecl_3dkw.py - test_ecl_file_statoil.py + test_ecl_file_equinor.py test_ecl_file.py test_ecl_init_file.py test_ecl_restart_file.py @@ -12,33 +12,33 @@ set(TEST_SOURCES test_ecl_sum.py test_ecl_sum_vector.py test_fault_blocks.py - test_fault_blocks_statoil.py + test_fault_blocks_equinor.py test_faults.py test_fortio.py - test_grdecl_statoil.py + test_grdecl_equinor.py test_grdecl.py test_grid.py test_grid_pandas.py test_cell.py - test_grid_statoil.py - test_grid_statoil_coarse.py - test_grid_statoil_dual.py - test_grid_statoil_large_case.py + test_grid_equinor.py + test_grid_equinor_coarse.py + test_grid_equinor_dual.py + test_grid_equinor_large_case.py test_grid_generator.py test_indexed_read.py - test_ecl_kw_statoil.py + test_ecl_kw_equinor.py test_ecl_kw.py test_kw_function.py test_layer.py test_npv.py test_region.py - test_region_statoil.py + test_region_equinor.py test_restart.py test_rft.py - test_rft_statoil.py + test_rft_equinor.py test_rft_cell.py - test_statoil_faults.py - test_sum_statoil.py + test_equinor_faults.py + test_sum_equinor.py test_ecl_util.py test_ecl_cmp.py test_sum.py @@ -83,24 +83,24 @@ if (INSTALL_ERT_LEGACY) endif() -addPythonTest(tests.ecl_tests.test_ecl_file_statoil.EclFileStatoilTest) -addPythonTest(tests.ecl_tests.test_grdecl_statoil.GRDECLStatoilTest) +addPythonTest(tests.ecl_tests.test_ecl_file_equinor.EclFileEquinorTest) +addPythonTest(tests.ecl_tests.test_grdecl_equinor.GRDECLEquinorTest) addPythonTest(tests.ecl_tests.test_grdecl.GRDECLTest) -addPythonTest(tests.ecl_tests.test_grid_statoil.GridTest) -addPythonTest(tests.ecl_tests.test_grid_statoil_coarse.GridCoarceTest) -addPythonTest(tests.ecl_tests.test_grid_statoil_dual.GridDualTest) -addPythonTest(tests.ecl_tests.test_grid_statoil_large_case.GridLargeCaseTest) -addPythonTest(tests.ecl_tests.test_ecl_kw_statoil.KWTest) +addPythonTest(tests.ecl_tests.test_grid_equinor.GridTest) +addPythonTest(tests.ecl_tests.test_grid_equinor_coarse.GridCoarceTest) +addPythonTest(tests.ecl_tests.test_grid_equinor_dual.GridDualTest) +addPythonTest(tests.ecl_tests.test_grid_equinor_large_case.GridLargeCaseTest) +addPythonTest(tests.ecl_tests.test_ecl_kw_equinor.KWTest) addPythonTest(tests.ecl_tests.test_ecl_init_file.InitFileTest) addPythonTest(tests.ecl_tests.test_ecl_restart_file.RestartFileTest) addPythonTest(tests.ecl_tests.test_restart.RestartTest ) -addPythonTest(tests.ecl_tests.test_region_statoil.RegionTest) -addPythonTest(tests.ecl_tests.test_rft_statoil.RFTTest) -addPythonTest(tests.ecl_tests.test_sum_statoil.SumTest) +addPythonTest(tests.ecl_tests.test_region_equinor.RegionTest) +addPythonTest(tests.ecl_tests.test_rft_equinor.RFTTest) +addPythonTest(tests.ecl_tests.test_sum_equinor.SumTest) addPythonTest(tests.ecl_tests.test_ecl_sum_vector.EclSumVectorTest) addPythonTest(tests.ecl_tests.test_ecl_sum.EclSumTest) -addPythonTest(tests.ecl_tests.test_statoil_faults.StatoilFaultTest) -addPythonTest(tests.ecl_tests.test_fault_blocks_statoil.FaultBlockTest) +addPythonTest(tests.ecl_tests.test_equinor_faults.EquinorFaultTest) +addPythonTest(tests.ecl_tests.test_fault_blocks_equinor.FaultBlockTest) addPythonTest(tests.ecl_tests.test_npv.NPVTest) addPythonTest(tests.ecl_tests.test_indexed_read.EclIndexedReadTest) addPythonTest(tests.ecl_tests.test_ecl_cmp.EclCmpTest) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_cell.py b/ThirdParty/Ert/python/tests/ecl_tests/test_cell.py index 5b8f41e52b..55120ce5c2 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_cell.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_cell.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_debug.py b/ThirdParty/Ert/python/tests/ecl_tests/test_debug.py index 49e4f997f1..ef930ed46b 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_debug.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_debug.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'test_debug.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_deprecation.py b/ThirdParty/Ert/python/tests/ecl_tests/test_deprecation.py index 869b6a4168..1096fc5272 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_deprecation.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_deprecation.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_deprecation.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -43,7 +43,6 @@ class Deprecation_2_0_Test(EclTest): with openFortIO("TEST" , mode = FortIO.WRITE_MODE) as f: kw.fwrite( f ) - t.sync() f = EclFile( "TEST" ) class Deprecation_1_9_Test(EclTest): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_3dkw.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_3dkw.py index e6a8fed20a..8c4f146743 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_3dkw.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_3dkw.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_kw.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_cmp.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_cmp.py index 39adb1fcb9..3d90837248 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_cmp.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_cmp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_ecl_cmp.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -17,13 +17,13 @@ from ecl.util.test import TestAreaContext from ecl.util.test.ecl_mock import createEclSum from ecl.summary import EclCmp -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class EclCmpTest(EclTest): def setUp(self): - self.root1 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE") - self.root2 = self.createTestPath("Statoil/ECLIPSE/Oseberg/F8MLT/F8MLT-F4") + self.root1 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE") + self.root2 = self.createTestPath("Equinor/ECLIPSE/Oseberg/F8MLT/F8MLT-F4") def test_not_existing(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py index c04ef9ef9a..8038ad5711 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_equinor.py similarity index 97% rename from ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_equinor.py index 8cffcbc259..1c9e8bf4da 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -22,14 +22,14 @@ from ecl import EclFileFlagEnum, EclFileEnum from ecl.eclfile import EclFile, FortIO, EclKW , openFortIO , openEclFile from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() -class EclFileStatoilTest(EclTest): +@equinor_test() +class EclFileEquinorTest(EclTest): def setUp(self): - self.test_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") - self.test_fmt_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.FUNRST") + self.test_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") + self.test_fmt_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.FUNRST") def assertFileType(self , filename , expected): file_type , step , fmt_file = EclFile.getFileType(filename) @@ -159,7 +159,7 @@ class EclFileStatoilTest(EclTest): def test_ix_case(self): - f = EclFile( self.createTestPath( "Statoil/ECLIPSE/ix/summary/Create_Region_Around_Well.SMSPEC")) + f = EclFile( self.createTestPath( "Equinor/ECLIPSE/ix/summary/Create_Region_Around_Well.SMSPEC")) # Keywords self.assertTrue( "KEYWORDS" in f ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_init_file.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_init_file.py index 9be2c65c72..c17a2fa6ea 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_init_file.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_init_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_ecl_init_file.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -15,18 +15,18 @@ # for more details. -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl import EclFileFlagEnum from ecl.eclfile import Ecl3DKW, EclKW, EclInitFile, EclFile, FortIO from ecl.grid import EclGrid -@statoil_test() +@equinor_test() class InitFileTest(EclTest): def setUp(self): - self.grid_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") - self.init_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.INIT") + self.grid_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") + self.init_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.INIT") def test_wrong_type(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py index 7528b85b66..f2c084a5d4 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_kw.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_equinor.py similarity index 91% rename from ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_equinor.py index 13b2d5d292..8593a64dcb 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_kw.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -20,7 +20,7 @@ from ecl import EclDataType, EclFileFlagEnum from ecl.eclfile import EclKW, EclFile, FortIO from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test def copy_long(): src = EclKW("NAME", 100, EclDataType.ECL_FLOAT) @@ -32,10 +32,10 @@ def copy_offset(): copy = src.sub_copy(200, 100) -@statoil_test() +@equinor_test() class KWTest(EclTest): def test_fortio_size( self ): - unrst_file_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") + unrst_file_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") unrst_file = EclFile(unrst_file_path) size = 0 for kw in unrst_file: @@ -48,7 +48,7 @@ class KWTest(EclTest): def test_sub_copy(self): - unrst_file_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") + unrst_file_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") unrst_file = EclFile(unrst_file_path) swat = unrst_file["SWAT"][0] @@ -89,7 +89,7 @@ class KWTest(EclTest): self.assertFalse(kw1.equal(kw2)) self.assertFalse(kw1.equal_numeric(kw2)) - unrst_file_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") + unrst_file_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") unrst_file = EclFile(unrst_file_path) kw1 = unrst_file["PRESSURE"][0] kw2 = kw1.deep_copy() diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_restart_file.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_restart_file.py index 690ac7ba52..cb3f437ee2 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_restart_file.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_restart_file.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_ecl_init_file.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -15,19 +15,19 @@ # for more details. import datetime -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl import EclFileFlagEnum from ecl.eclfile import Ecl3DKW , EclKW, EclRestartFile , EclFile, FortIO from ecl.grid import EclGrid -@statoil_test() +@equinor_test() class RestartFileTest(EclTest): def setUp(self): - self.grid_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") - self.unrst_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") - self.xrst_file0 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0000") - self.xrst_file10 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0010") - self.xrst_file20 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0020") + self.grid_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") + self.unrst_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") + self.xrst_file0 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0000") + self.xrst_file10 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0010") + self.xrst_file20 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0020") def test_load(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py index 80c69003b7..40c36bccda 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_ecl_sum.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -24,14 +24,14 @@ from cwrap import Prototype, load, open as copen from ecl.eclfile import EclFile, FortIO, openFortIO, openEclFile, EclKW from ecl.summary import EclSum, EclSumKeyWordVector from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class EclSumTest(EclTest): def setUp(self): - self.test_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") + self.test_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") self.ecl_sum = EclSum(self.test_file) @@ -71,7 +71,7 @@ class EclSumTest(EclTest): def test_truncated_smspec(self): with TestAreaContext("EclSum/truncated_smspec") as ta: ta.copy_file(self.test_file) - ta.copy_file(self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) + ta.copy_file(self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) file_size = os.path.getsize("ECLIPSE.SMSPEC") with open("ECLIPSE.SMSPEC","r+") as f: @@ -84,7 +84,7 @@ class EclSumTest(EclTest): def test_truncated_data(self): with TestAreaContext("EclSum/truncated_data") as ta: ta.copy_file(self.test_file) - ta.copy_file(self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) + ta.copy_file(self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) file_size = os.path.getsize("ECLIPSE.UNSMRY") @@ -98,7 +98,7 @@ class EclSumTest(EclTest): def test_missing_smspec_keyword(self): with TestAreaContext("EclSum/truncated_data") as ta: ta.copy_file(self.test_file) - ta.copy_file(self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) + ta.copy_file(self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) with openEclFile("ECLIPSE.SMSPEC") as f: kw_list = [] @@ -118,7 +118,7 @@ class EclSumTest(EclTest): def test_missing_unsmry_keyword(self): with TestAreaContext("EclSum/truncated_data") as ta: ta.copy_file(self.test_file) - ta.copy_file(self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) + ta.copy_file(self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNSMRY")) with openEclFile("ECLIPSE.UNSMRY") as f: kw_list = [] @@ -140,7 +140,7 @@ class EclSumTest(EclTest): def test_labscale(self): - case = self.createTestPath("Statoil/ECLIPSE/LabScale/HDMODEL") + case = self.createTestPath("Equinor/ECLIPSE/LabScale/HDMODEL") sum = EclSum(case, lazy_load=True) self.assertEqual(sum.getStartTime(), datetime.datetime(2013,1,1,0,0,0)) self.assertEqual(sum.getEndTime() , datetime.datetime(2013,1,1,19,30,0)) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py index 90e799eb1b..8a72dd0452 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'test_ecl_sum_vector.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -23,14 +23,14 @@ except ImportError: import warnings from ecl.summary import EclSumVector, EclSum -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class EclSumVectorTest(EclTest): def setUp(self): - self.test_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") + self.test_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") self.ecl_sum = EclSum(self.test_file) def test_reportOnly_warns(self): @@ -38,7 +38,7 @@ class EclSumVectorTest(EclTest): warnings.simplefilter("always") vector = EclSumVector(self.ecl_sum, "FOPT", True) - self.assertEqual(len(w), 2) + self.assertEqual(len(w), 1) assert issubclass(w[-1].category, DeprecationWarning) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py index fc5c03d7dc..522afd7c8f 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_statoil_faults.py b/ThirdParty/Ert/python/tests/ecl_tests/test_equinor_faults.py similarity index 94% rename from ThirdParty/Ert/python/tests/ecl_tests/test_statoil_faults.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_equinor_faults.py index 03c5b3210a..cdde627cb3 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_statoil_faults.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_equinor_faults.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_faults.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -26,13 +26,13 @@ from ecl import EclDataType from ecl.eclfile import EclKW from ecl.grid import EclGrid from ecl.grid.faults import FaultCollection, Fault, FaultLine, FaultSegment -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() -class StatoilFaultTest(EclTest): +@equinor_test() +class EquinorFaultTest(EclTest): def loadGrid(self): - grid_file = self.createTestPath("Statoil/ECLIPSE/Faults/grid.grdecl") + grid_file = self.createTestPath("Equinor/ECLIPSE/Faults/grid.grdecl") fileH = copen(grid_file, "r") specgrid = EclKW.read_grdecl(fileH, "SPECGRID", ecl_type=EclDataType.ECL_INT, strict=False) zcorn = EclKW.read_grdecl(fileH, "ZCORN") @@ -46,7 +46,7 @@ class StatoilFaultTest(EclTest): def test_load(self): grid = self.loadGrid() - faults_file = self.createTestPath("Statoil/ECLIPSE/Faults/faults.grdecl") + faults_file = self.createTestPath("Equinor/ECLIPSE/Faults/faults.grdecl") faults = FaultCollection( grid , faults_file ) for fault in faults: for layer in fault: diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks.py b/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks.py index 8e6ca732c4..7be4554098 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_fault_blocks.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_equinor.py similarity index 85% rename from ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_equinor.py index 4b72f27be6..1c5e760579 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_fault_blocks_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_fault_blocks.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -22,17 +22,17 @@ except ImportError: from ecl import EclDataType from ecl.eclfile import EclKW from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl.grid.faults import FaultBlock, FaultBlockLayer from cwrap import open as copen -@statoil_test() +@equinor_test() class FaultBlockTest(EclTest): def setUp(self): - self.grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Mariner/MARINER.EGRID")) - fileH = copen( self.createTestPath("Statoil/ECLIPSE/Mariner/faultblock.grdecl") ) + self.grid = EclGrid( self.createTestPath("Equinor/ECLIPSE/Mariner/MARINER.EGRID")) + fileH = copen( self.createTestPath("Equinor/ECLIPSE/Mariner/faultblock.grdecl") ) self.kw = EclKW.read_grdecl( fileH , "FAULTBLK" , ecl_type = EclDataType.ECL_INT ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_faults.py b/ThirdParty/Ert/python/tests/ecl_tests/test_faults.py index 5a65e9a0b1..240204d367 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_faults.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_faults.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_faults.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_fk_user_data.py b/ThirdParty/Ert/python/tests/ecl_tests/test_fk_user_data.py index d01c981463..3e484cac27 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_fk_user_data.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_fk_user_data.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'test_ecl_cell_containment.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_fortio.py b/ThirdParty/Ert/python/tests/ecl_tests/test_fortio.py index 54a4b9fabe..842ac049b7 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_fortio.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_fortio.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # @@ -77,8 +77,7 @@ class FortIOTest(EclTest): kw1.fwrite(f) pos1 = f.getPosition( ) kw2.fwrite(f) - - t.sync( ) + # Truncate file in read mode; should fail hard. with openFortIO("file") as f: with self.assertRaises(IOError): @@ -121,8 +120,6 @@ class FortIOTest(EclTest): kw1.fwrite( f ) self.assertEqual( f.filename() , "file") - t.sync( ) - with openFortIO("file") as f: kw2 = EclKW.fread( f ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_geertsma.py b/ThirdParty/Ert/python/tests/ecl_tests/test_geertsma.py index f991e88704..12a36297d8 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_geertsma.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_geertsma.py @@ -22,7 +22,7 @@ def create_init(grid, case): porv.fwrite(f) -def create_restart(grid, case, p1, p2=None): +def create_restart(grid, case, p1, p2=None, rporv1=None, rporv2=None): with openFortIO("%s.UNRST" % case, mode=FortIO.WRITE_MODE) as f: seq_hdr = EclKW("SEQNUM", 1, EclDataType.ECL_FLOAT) seq_hdr[0] = 10 @@ -39,6 +39,13 @@ def create_restart(grid, case, p1, p2=None): header.fwrite(f) p.fwrite(f) + if rporv1: + rp = EclKW("RPORV", grid.getNumActive(), EclDataType.ECL_FLOAT) + for idx, val in enumerate(rporv1): + rp[idx] = val + + rp.fwrite(f) + if p2: seq_hdr[0] = 20 header[66] = 2010 @@ -49,6 +56,13 @@ def create_restart(grid, case, p1, p2=None): header.fwrite(f) p.fwrite(f) + if rporv2: + rp = EclKW("RPORV", grid.getNumActive(), EclDataType.ECL_FLOAT) + for idx, val in enumerate(rporv2): + rp[idx] = val + + rp.fwrite(f) + class GeertsmaTest(EclTest): @@ -145,4 +159,62 @@ class GeertsmaTest(EclTest): dz = subsidence.evalGeertsma("S1", None, receiver, youngs_modulus, poisson_ratio, seabed) np.testing.assert_almost_equal(dz, 5.819790154474284e-08) + @staticmethod + def test_geertsma_kernel_seabed(): + grid = EclGrid.createRectangular(dims=(1, 1, 1), dV=(50, 50, 50)) + with TestAreaContext("Subsidence"): + p1 = [1] + create_restart(grid, "TEST", p1) + create_init(grid, "TEST") + init = EclFile("TEST.INIT") + restart_file = EclFile("TEST.UNRST") + + restart_view1 = restart_file.restartView(sim_time=datetime.date(2000, 1, 1)) + + subsidence = EclSubsidence(grid, init) + subsidence.add_survey_PRESSURE("S1", restart_view1) + + youngs_modulus = 5E8 + poisson_ratio = 0.3 + seabed = 300 + above = 100 + topres = 2000 + receiver = (1000, 1000, topres - seabed - above) + + dz = subsidence.evalGeertsma("S1", None, receiver, youngs_modulus, poisson_ratio, seabed) + np.testing.assert_almost_equal(dz, 5.819790154474284e-08) + + def test_geertsma_rporv_kernel_2_source_points_2_vintages(self): + grid = EclGrid.createRectangular(dims=(2, 1, 1), dV=(100, 100, 100)) + + with TestAreaContext("Subsidence"): + p1 = [1, 10] + p2 = [10, 20] + create_restart(grid, "TEST", + p1, p2, + rporv1=[10**5, 10**5], rporv2=[9*10**4, 9*10**4] + ) + create_init(grid, "TEST") + + init = EclFile("TEST.INIT") + restart_file = EclFile("TEST.UNRST") + + restart_view1 = restart_file.restartView(sim_time=datetime.date(2000, 1, 1)) + restart_view2 = restart_file.restartView(sim_time=datetime.date(2010, 1, 1)) + + subsidence = EclSubsidence(grid, init) + subsidence.add_survey_PRESSURE("S1", restart_view1) + subsidence.add_survey_PRESSURE("S2", restart_view2) + + youngs_modulus = 5E8 + poisson_ratio = 0.3 + seabed = 0 + receiver = (1000, 1000, 0) + + dz1 = subsidence.eval_geertsma_rporv("S1", None, receiver, youngs_modulus, poisson_ratio, seabed) + dz2 = subsidence.eval_geertsma_rporv("S2", None, receiver, youngs_modulus, poisson_ratio, seabed) + dz = subsidence.eval_geertsma_rporv("S1", "S2", receiver, youngs_modulus, poisson_ratio, seabed) + + np.testing.assert_almost_equal(dz, dz1-dz2) + self.assertTrue(dz > 0) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py index 58337e00ef..0473dbdc51 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # The file 'test_grdecl.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_equinor.py similarity index 93% rename from ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_equinor.py index a627d84cd9..35273b2220 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -18,15 +18,15 @@ import os from ecl.eclfile import EclKW, Ecl3DKW from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from cwrap import open as copen -@statoil_test() -class GRDECLStatoilTest(EclTest): +@equinor_test() +class GRDECLEquinorTest(EclTest): def setUp(self): - self.src_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/include/example_permx.GRDECL") + self.src_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/include/example_permx.GRDECL") self.file_list = [] def addFile(self, filename): @@ -42,7 +42,7 @@ class GRDECLStatoilTest(EclTest): kw = EclKW.read_grdecl(copen(self.src_file, "r"), "PERMX") self.assertTrue(kw) - grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE" )) + grid = EclGrid( self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE" )) kw = Ecl3DKW.read_grdecl(grid , copen(self.src_file, "r"), "PERMX") self.assertTrue( isinstance( kw , Ecl3DKW )) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py index b3df4dee7c..2095fa2378 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_grid.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -122,8 +122,8 @@ def average(points): return [elem/float(len(points)) for elem in p] # This test class should only have test cases which do not require -# external test data. Tests involving Statoil test data are in the -# test_grid_statoil module. +# external test data. Tests involving Equinor test data are in the +# test_grid_equinor module. class GridTest(EclTest): def test_oom_grid(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor.py similarity index 94% rename from ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor.py index a925b6ac0b..74a9c3a2bc 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_grid.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -30,21 +30,21 @@ from ecl.eclfile import EclKW, EclFile, openEclFile from ecl.grid import EclGrid from ecl.util.util import DoubleVector, IntVector from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class GridTest(EclTest): def egrid_file(self): - return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") + return self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") def grid_file(self): - return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.GRID") + return self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.GRID") def grdecl_file(self): - return self.createTestPath("Statoil/ECLIPSE/Gurbat/include/example_grid_sim.GRDECL") + return self.createTestPath("Equinor/ECLIPSE/Gurbat/include/example_grid_sim.GRDECL") def test_loadFromFile(self): g1 = EclGrid.loadFromFile( self.egrid_file() ) @@ -277,7 +277,7 @@ class GridTest(EclTest): @skipIf(EclTest.slowTestShouldNotRun(), "Slow test of numActive large memory skipped!") def test_num_active_large_memory(self): - case = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE") + case = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE") vecList = [] for i in range(12500): vec = DoubleVector() @@ -291,7 +291,7 @@ class GridTest(EclTest): def test_no_mapaxes_check_for_nan(self): - grid_paths = ["Statoil/ECLIPSE/NoMapaxes/ECLIPSE.EGRID", "Statoil/ECLIPSE/NoMapaxes/ECLIPSE.GRID"] + grid_paths = ["Equinor/ECLIPSE/NoMapaxes/ECLIPSE.EGRID", "Equinor/ECLIPSE/NoMapaxes/ECLIPSE.GRID"] for grid_path in grid_paths: test_grid_path = self.createTestPath(grid_path) @@ -309,7 +309,7 @@ class GridTest(EclTest): def test_valid_geometry(self): - grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/GRID_INVALID_CELL/PRED_RESEST_0_R_13_0.GRID")) + grid = EclGrid( self.createTestPath("Equinor/ECLIPSE/GRID_INVALID_CELL/PRED_RESEST_0_R_13_0.GRID")) self.assertTrue( grid.validCellGeometry( ijk = (27,0,0)) ) self.assertFalse( grid.validCellGeometry( ijk = (0,0,0)) ) @@ -328,7 +328,7 @@ class GridTest(EclTest): def test_lgr_get(self): - grid = EclGrid(self.createTestPath("Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID")) + grid = EclGrid(self.createTestPath("Equinor/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID")) for (nr,name) in [ ( 104 , "LG003017"), (2 , "LG006024"), ( 4 , "LG005025"), diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_coarse.py similarity index 84% rename from ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_coarse.py index 11f94ebc90..29029f0ad9 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_coarse.py @@ -1,6 +1,6 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # -# The file 'test_grid_statoil_coarse.py' is part of ERT - Ensemble based Reservoir Tool. +# The file 'test_grid_equinor_coarse.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 @@ -18,17 +18,17 @@ import math from ecl.util.test import TestAreaContext from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class GridCoarceTest(EclTest): def test_coarse(self): #work_area = TestArea("python/grid-test/testCoarse") with TestAreaContext("python/grid-test/testCoarse"): testGRID = True - g1 = EclGrid(self.createTestPath("Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2.EGRID")) + g1 = EclGrid(self.createTestPath("Equinor/ECLIPSE/LGCcase/LGC_TESTCASE2.EGRID")) g1.save_EGRID("LGC.EGRID") g2 = EclGrid("LGC.EGRID") diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_dual.py similarity index 84% rename from ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_dual.py index eeb907c075..d962448953 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_dual.py @@ -1,6 +1,6 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # -# The file 'test_grid_statoil_dual.py' is part of ERT - Ensemble based Reservoir Tool. +# The file 'test_grid_equinor_dual.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 @@ -18,16 +18,16 @@ import math from ecl.util.test import TestAreaContext from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class GridDualTest(EclTest): def egrid_file(self): - return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") + return self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") def grid_file(self): - return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.GRID") + return self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.GRID") def test_dual(self): with TestAreaContext("python/grid-test/testDual"): @@ -39,11 +39,11 @@ class GridDualTest(EclTest): self.assertFalse(grid.dualGrid()) self.assertTrue(grid.getNumActiveFracture() == 0) - dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.EGRID")) + dgrid = EclGrid(self.createTestPath("Equinor/ECLIPSE/DualPoro/DUALPOR_MSW.EGRID")) self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) self.assertTrue(dgrid.getNumActive() == 46118) - dgrid2 = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.GRID")) + dgrid2 = EclGrid(self.createTestPath("Equinor/ECLIPSE/DualPoro/DUALPOR_MSW.GRID")) self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) self.assertTrue(dgrid.getNumActive() == 46118) self.assertTrue(dgrid.equal(dgrid2)) @@ -52,7 +52,7 @@ class GridDualTest(EclTest): # The DUAL_DIFF grid has been manipulated to create a # situation where some cells are only matrix active, and some # cells are only fracture active. - dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUAL_DIFF.EGRID")) + dgrid = EclGrid(self.createTestPath("Equinor/ECLIPSE/DualPoro/DUAL_DIFF.EGRID")) self.assertTrue(dgrid.getNumActive() == 106) self.assertTrue(dgrid.getNumActiveFracture() == 105) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_large_case.py similarity index 78% rename from ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_large_case.py index 09b4b366df..3545e1b529 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_equinor_large_case.py @@ -1,6 +1,6 @@ -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # -# The file 'test_grid_statoil_large_case.py' is part of ERT - Ensemble based Reservoir Tool. +# The file 'test_grid_equinor_large_case.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 @@ -18,12 +18,12 @@ import math from ecl.util.test import TestAreaContext from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class GridLargeCaseTest(EclTest): def test_large_case(self): - grdecl_file = self.createTestPath("Statoil/ECLIPSE/1.6.0_issueGrdecl/test_aug2016_gridOnly.grdecl") + grdecl_file = self.createTestPath("Equinor/ECLIPSE/1.6.0_issueGrdecl/test_aug2016_gridOnly.grdecl") grid = EclGrid.loadFromGrdecl( grdecl_file ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_generator.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_generator.py index 9289003bc5..cf55ffcf43 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_generator.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_generator.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'test_grid_generator.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py index f02bdb8f17..f73e1b6b5f 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2018 Statoil ASA, Norway. +# Copyright (C) 2018 Equinor ASA, Norway. # # The file 'test_grid.pandas' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_kw_function.py b/ThirdParty/Ert/python/tests/ecl_tests/test_kw_function.py index 21f8452be8..5b42387c04 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_kw_function.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_kw_function.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_kw_function.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_layer.py b/ThirdParty/Ert/python/tests/ecl_tests/test_layer.py index 0c8aabf6f7..9b4b6a55a3 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_layer.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_layer.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. +# Copyright (C) 2014 Equinor ASA, Norway. # # The file 'test_layer.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_npv.py b/ThirdParty/Ert/python/tests/ecl_tests/test_npv.py index 43bd77493f..1b64680e43 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_npv.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_npv.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -29,11 +29,11 @@ from ecl.summary import EclNPV , NPVPriceVector from ecl.util.util import StringList, TimeVector, DoubleVector , CTime from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test base = "ECLIPSE" -path = "Statoil/ECLIPSE/Gurbat" +path = "Equinor/ECLIPSE/Gurbat" case = "%s/%s" % (path, base) def callable(x): @@ -45,7 +45,7 @@ def linear1(x): def linear2(x): return 2*x -@statoil_test() +@equinor_test() class NPVTest(EclTest): def setUp(self): self.case = self.createTestPath(case) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_region.py b/ThirdParty/Ert/python/tests/ecl_tests/test_region.py index 6c38697115..d077ae9dca 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_region.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_region.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # The file 'test_region.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_region_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_region_equinor.py similarity index 96% rename from ThirdParty/Ert/python/tests/ecl_tests/test_region_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_region_equinor.py index 16fc04090a..2ede1f71e6 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_region_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_region_equinor.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2012 Statoil ASA, Norway. +# Copyright (C) 2012 Equinor ASA, Norway. # # The file 'test_region.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -17,13 +17,13 @@ from ecl.eclfile import EclFile from ecl.grid import EclGrid, EclRegion from ecl.grid.faults import Layer -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class RegionTest(EclTest): def setUp(self): - case = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE") + case = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE") self.grid = EclGrid(case) self.rst_file = EclFile("%s.UNRST" % case) self.init_file = EclFile("%s.INIT" % case) @@ -166,7 +166,7 @@ class RegionTest(EclTest): def test_heidrun(self): - root = self.createTestPath("Statoil/ECLIPSE/Heidrun") + root = self.createTestPath("Equinor/ECLIPSE/Heidrun") grid = EclGrid( "%s/FF12_2013B2_AMAP_AOP-J15_NO62_MOVEX.EGRID" % root) polygon = [] diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_removed.py b/ThirdParty/Ert/python/tests/ecl_tests/test_removed.py index db480ffe82..9cc5eea2ae 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_removed.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_removed.py @@ -16,8 +16,6 @@ class Removed_2_1_Test(EclTest): with openFortIO("TEST" , mode = FortIO.WRITE_MODE) as f: kw.fwrite( f ) - t.sync() - f = EclFile( "TEST" ) with self.assertRaises(NotImplementedError): f.select_block( "KW" , 100 ) @@ -33,4 +31,4 @@ class Removed_2_1_Test(EclTest): with self.assertRaises(NotImplementedError): EclFile.restart_block( "TEST" ) - + diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_restart.py b/ThirdParty/Ert/python/tests/ecl_tests/test_restart.py index 32fa276aec..c28164a1b1 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_restart.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_restart.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -18,18 +18,18 @@ from _ctypes import ArgumentError import os import datetime from ecl.eclfile import EclFile -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class RestartTest(EclTest): def setUp(self): - self.xfile0 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0000") - self.u_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") - self.fmt_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.FUNRST") - self.grid_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") + self.xfile0 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0000") + self.u_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") + self.fmt_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.FUNRST") + self.grid_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") self.file_list = [] def addFile( self, filename ): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_restart_head.py b/ThirdParty/Ert/python/tests/ecl_tests/test_restart_head.py index c1683f6d41..b92e3cabfe 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_restart_head.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_restart_head.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_ecl_init_file.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -15,17 +15,17 @@ # for more details. import datetime -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl import EclFileFlagEnum from ecl.eclfile import Ecl3DKW , EclKW, EclRestartFile , EclFile, FortIO from ecl.grid import EclGrid -@statoil_test() +@equinor_test() class RestartHeadTest(EclTest): def setUp(self): - self.grid_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") - self.unrst_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") - self.xrst_file0 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0000") + self.grid_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") + self.unrst_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") + self.xrst_file0 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0000") def test_headers(self): g = EclGrid( self.grid_file ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_rft.py b/ThirdParty/Ert/python/tests/ecl_tests/test_rft.py index b903f3d78f..f4bf29b003 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_rft.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_rft.py @@ -1,19 +1,19 @@ #!/usr/bin/env python -# Copyright (C) 2016 Statoil ASA, Norway. -# +# Copyright (C) 2016 Equinor ASA, Norway. +# # The file 'test_rft.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 -# for more details. +# +# 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 +# for more details. import datetime @@ -32,5 +32,5 @@ class RFTTest(EclTest): def test_repr(self): rft = EclRFT( "WELL" , "RFT" , datetime.date(2015 , 10 , 1 ) , 100 ) - pfx = 'EclRFT(completed_cells = 0, date = 2015-10-01, RFT, MSW)' + pfx = 'EclRFT(completed_cells = 0, date = 2015-10-01, RFT)' self.assertEqual(pfx, repr(rft)[:len(pfx)]) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_rft_cell.py b/ThirdParty/Ert/python/tests/ecl_tests/test_rft_cell.py index 67fb0c0062..ba0cc007bc 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_rft_cell.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_rft_cell.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2013 Statoil ASA, Norway. +# Copyright (C) 2013 Equinor ASA, Norway. # # The file 'test_rft_cell.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -27,8 +27,8 @@ from tests import EclTest class RFTCellTest(EclTest): def setUp(self): - self.RFT_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.RFT") - self.PLT_file = self.createTestPath("Statoil/ECLIPSE/RFT/TEST1_1A.RFT") + self.RFT_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.RFT") + self.PLT_file = self.createTestPath("Equinor/ECLIPSE/RFT/TEST1_1A.RFT") def test_RFT_cell(self): i = 10 diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_rft_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_rft_equinor.py similarity index 81% rename from ThirdParty/Ert/python/tests/ecl_tests/test_rft_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_rft_equinor.py index e097551a44..051ee0582a 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_rft_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_rft_equinor.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # -# The file 'test_rft_statoil.py' is part of ERT - Ensemble based Reservoir Tool. +# The file 'test_rft_equinor.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 @@ -18,14 +18,14 @@ from __future__ import print_function import datetime from ecl.rft import EclRFTFile, EclRFTCell, EclPLTCell, WellTrajectory -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test -@statoil_test() +@equinor_test() class RFTTest(EclTest): def setUp(self): - self.RFT_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.RFT") - self.PLT_file = self.createTestPath("Statoil/ECLIPSE/RFT/TEST1_1A.RFT") + self.RFT_file = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.RFT") + self.PLT_file = self.createTestPath("Equinor/ECLIPSE/RFT/TEST1_1A.RFT") def test_RFT_load(self): @@ -53,10 +53,6 @@ class RFTTest(EclTest): for cell in rft: self.assertIsInstance(cell, EclRFTCell) - cell0 = rft.iget_sorted(0) - self.assertIsInstance(cell, EclRFTCell) - rft.sort() - for h in rftFile.getHeaders(): print(h) self.assertIsInstance(h[1], datetime.date) @@ -81,7 +77,7 @@ class RFTTest(EclTest): def test_basics(self): - wt = WellTrajectory(self.createTestPath("Statoil/ert-statoil/spotfire/gendata_rft_zone/E-3H.txt")) + wt = WellTrajectory(self.createTestPath("Equinor/ert-equinor/spotfire/gendata_rft_zone/E-3H.txt")) self.assertEqual(len(wt), 38) self.assertTrue(isinstance(str(wt), str)) self.assertTrue(isinstance(repr(wt), str)) @@ -92,12 +88,12 @@ class RFTTest(EclTest): WellTrajectory("/does/no/exist") with self.assertRaises(UserWarning): - WellTrajectory(self.createTestPath("Statoil/ert-statoil/spotfire/gendata_rft_zone/invalid_float.txt")) + WellTrajectory(self.createTestPath("Equinor/ert-equinor/spotfire/gendata_rft_zone/invalid_float.txt")) with self.assertRaises(UserWarning): - WellTrajectory(self.createTestPath("Statoil/ert-statoil/spotfire/gendata_rft_zone/missing_item.txt")) + WellTrajectory(self.createTestPath("Equinor/ert-equinor/spotfire/gendata_rft_zone/missing_item.txt")) - wt = WellTrajectory(self.createTestPath("Statoil/ert-statoil/spotfire/gendata_rft_zone/E-3H.txt")) + wt = WellTrajectory(self.createTestPath("Equinor/ert-equinor/spotfire/gendata_rft_zone/E-3H.txt")) self.assertEqual(len(wt), 38) with self.assertRaises(IndexError): @@ -115,7 +111,7 @@ class RFTTest(EclTest): def test_PLT(self): - rft_file = EclRFTFile(self.createTestPath("Statoil/ECLIPSE/Heidrun/RFT/2C3_MR61.RFT")) + rft_file = EclRFTFile(self.createTestPath("Equinor/ECLIPSE/Heidrun/RFT/2C3_MR61.RFT")) rft0 = rft_file[0] rft1 = rft_file[1] diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py b/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py index b29c8e0da9..5c33c87d04 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -22,8 +22,19 @@ import csv import shutil import cwrap import stat +import pandas + +def assert_frame_equal(a,b): + if not a.equals(b): + raise AssertionError("Expected dataframes to be equal") + +try: + from pandas.testing import assert_frame_equal +except ImportError: + pass + from contextlib import contextmanager -from unittest import skipIf, skipUnless, skipIf +from unittest import skipIf, skipUnless from ecl import EclUnitTypeEnum from ecl import EclDataType @@ -78,6 +89,21 @@ def create_case(case = "CSV", restart_case = None, restart_step = -1, data_start restart_case = restart_case, restart_step = restart_step) +def create_case2(case = "CSV", restart_case = None, restart_step = -1, data_start = None): + length = 100 + return createEclSum(case , [("WOPT", "OPX" , 0, "SM3") , ("FOPR" , None , 0, "SM3/DAY"), ("BPR" , None , 10, "SM3"), ("RPR", None, 3, "BARS"), ("COPR", "OPX", 421, "BARS")], + sim_length_days = length, + num_report_step = 10, + num_mini_step = 10, + data_start = data_start, + func_table = {"FOPT" : fopt, + "FOPR" : fopr , + "FGPT" : fgpt }, + restart_case = restart_case, + restart_step = restart_step) + + + class SumTest(EclTest): @@ -101,19 +127,26 @@ class SumTest(EclTest): def test_identify_var_type(self): - self.assertEnumIsFullyDefined( EclSumVarType , "ecl_smspec_var_type" , "lib/include/ert/ecl/smspec_node.hpp") + self.assertEnumIsFullyDefined( EclSumVarType , "ecl_smspec_var_type" , "lib/include/ert/ecl/smspec_node.h") self.assertEqual( EclSum.varType( "WWCT:OP_X") , EclSumVarType.ECL_SMSPEC_WELL_VAR ) self.assertEqual( EclSum.varType( "RPR") , EclSumVarType.ECL_SMSPEC_REGION_VAR ) self.assertEqual( EclSum.varType( "WNEWTON") , EclSumVarType.ECL_SMSPEC_MISC_VAR ) self.assertEqual( EclSum.varType( "AARQ:4") , EclSumVarType.ECL_SMSPEC_AQUIFER_VAR ) + self.assertEqual( EclSum.varType("RXFT"), EclSumVarType.ECL_SMSPEC_REGION_2_REGION_VAR) + self.assertEqual( EclSum.varType("RxxFT"), EclSumVarType.ECL_SMSPEC_REGION_2_REGION_VAR) + self.assertEqual( EclSum.varType("RXFR"), EclSumVarType.ECL_SMSPEC_REGION_2_REGION_VAR) + self.assertEqual( EclSum.varType("RxxFR"), EclSumVarType.ECL_SMSPEC_REGION_2_REGION_VAR) + self.assertEqual( EclSum.varType("RORFR"), EclSumVarType.ECL_SMSPEC_REGION_VAR) + case = createEclSum("CSV" , [("FOPT", None , 0, "SM3") , ("FOPR" , None , 0, "SM3/DAY"), ("AARQ" , None , 10, "???"), - ("RGPT" , None ,1, "SM3")]) + ("RGPT" , None ,1, "SM3")]) node1 = case.smspec_node( "FOPT" ) self.assertEqual( node1.varType( ) , EclSumVarType.ECL_SMSPEC_FIELD_VAR ) + self.assertIsNone(node1.wgname) node2 = case.smspec_node( "AARQ:10" ) self.assertEqual( node2.varType( ) , EclSumVarType.ECL_SMSPEC_AQUIFER_VAR ) @@ -549,6 +582,24 @@ class SumTest(EclTest): self.assertEqual(len(case), rows) + def test_csv_load(self): + case = create_case2() + frame = case.pandas_frame() + ecl_sum = EclSum.from_pandas("PANDAS", frame, dims=[20,10,5]) + + for key in frame.columns: + self.assertTrue(key in ecl_sum) + + df = ecl_sum.pandas_frame() + assert_frame_equal(frame, df) + + ecl_sum_less = EclSum.from_pandas("PANDAS", frame, dims=[20,10,5], headers=['BPR:10', 'RPR:3,1,1', 'COPR:OPX:1,2,3']) + del frame['WOPT:OPX'] + del frame['FOPR'] + df_less = ecl_sum_less.pandas_frame() + assert_frame_equal(frame, df_less) + + def test_total_and_rate(self): self.assertTrue( EclSum.is_total("FOPT")) self.assertTrue( EclSum.is_total("WWPT:OP_3")) @@ -568,8 +619,6 @@ class SumTest(EclTest): for time_index,value in enumerate(fopr): self.assertEqual(fopr[time_index], value) - - def test_write_not_implemented(self): path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") case = EclSum( path, lazy_load=True ) @@ -578,10 +627,55 @@ class SumTest(EclTest): case.fwrite( ) - def test_directory_conflict(self): with TestAreaContext("dir_conflict"): case = create_case("UNITS") case.fwrite() os.mkdir("UNITS") case2 = EclSum("./UNITS") + + + def test_resample_extrapolate(self): + """ + Test resampling of summary with extrapolate option of lower and upper boundaries enabled + """ + from ecl.util.util import TimeVector, CTime + + time_points = TimeVector() + + path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") + ecl_sum = EclSum( path, lazy_load=True ) + + start_time = ecl_sum.get_data_start_time() - datetime.timedelta(seconds=86400) + end_time = ecl_sum.get_end_time() + datetime.timedelta(seconds=86400) + delta = end_time - start_time + + N = 25 + time_points.initRange( CTime(start_time), + CTime(end_time), + CTime(int(delta.total_seconds()/(N - 1)))) + time_points.append(CTime(end_time)) + resampled = ecl_sum.resample( "OUTPUT_CASE", time_points, lower_extrapolation=True, upper_extrapolation=True ) + + for key in ecl_sum.keys(): + self.assertIn( key, resampled ) + + self.assertEqual(ecl_sum.get_data_start_time() - datetime.timedelta(seconds=86400), resampled.get_data_start_time()) + + key_not_rate = "FOPT" + for time_index,t in enumerate(time_points): + if t < ecl_sum.get_data_start_time(): + self.assertFloatEqual(resampled.iget( key_not_rate, time_index), ecl_sum._get_first_value(key_not_rate)) + elif t > ecl_sum.get_end_time(): + self.assertFloatEqual(resampled.iget( key_not_rate, time_index), ecl_sum.get_last_value( key_not_rate)) + else: + self.assertFloatEqual(resampled.iget( key_not_rate, time_index), ecl_sum.get_interp_direct( key_not_rate, t)) + + key_rate = "FOPR" + for time_index,t in enumerate(time_points): + if t < ecl_sum.get_data_start_time(): + self.assertFloatEqual(resampled.iget( key_rate, time_index), 0) + elif t > ecl_sum.get_end_time(): + self.assertFloatEqual(resampled.iget( key_rate, time_index), 0) + else: + self.assertFloatEqual(resampled.iget( key_rate, time_index), ecl_sum.get_interp_direct( key_rate, t)) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_sum_equinor.py similarity index 93% rename from ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py rename to ThirdParty/Ert/python/tests/ecl_tests/test_sum_equinor.py index 477d5135e3..aa1e6454d8 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_sum_equinor.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. # @@ -26,11 +26,11 @@ from ecl import EclUnitTypeEnum from ecl.util.util import StringList, TimeVector, DoubleVector, CTime from ecl.util.test import TestAreaContext -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test import csv base = "ECLIPSE" -path = "Statoil/ECLIPSE/Gurbat" +path = "Equinor/ECLIPSE/Gurbat" case = "%s/%s" % (path, base) @@ -42,7 +42,7 @@ def sum_get(*args): vec = sum[key] -@statoil_test() +@equinor_test() class SumTest(EclTest): def setUp(self): self.case = self.createTestPath(case) @@ -110,7 +110,7 @@ class SumTest(EclTest): def test_LLINEAR(self): - sum = EclSum( self.createTestPath("Statoil/ECLIPSE/Heidrun/LGRISSUE/EM-LTAA-ISEG_CARFIN_NWPROPS")) + sum = EclSum( self.createTestPath("Equinor/ECLIPSE/Heidrun/LGRISSUE/EM-LTAA-ISEG_CARFIN_NWPROPS")) self.assertTrue( sum.has_key("LLINEARS") ) @@ -163,7 +163,7 @@ class SumTest(EclTest): def test_dates2( self ): - sum = EclSum(self.createTestPath("Statoil/ECLIPSE/FF12/FF12_2013B3_AMAP2")) + sum = EclSum(self.createTestPath("Equinor/ECLIPSE/FF12/FF12_2013B3_AMAP2")) self.assertEqual(sum.end_date , datetime.date(2045, 1, 1)) @@ -216,9 +216,9 @@ class SumTest(EclTest): def test_restart(self): - hist = EclSum(self.createTestPath("Statoil/ECLIPSE/sum-restart/history/T07-4A-W2011-18-P1")) - base = EclSum(self.createTestPath("Statoil/ECLIPSE/sum-restart/prediction/BASECASE")) - pred = EclSum(self.createTestPath("Statoil/ECLIPSE/sum-restart/prediction/BASECASE"), include_restart=False) + hist = EclSum(self.createTestPath("Equinor/ECLIPSE/sum-restart/history/T07-4A-W2011-18-P1")) + base = EclSum(self.createTestPath("Equinor/ECLIPSE/sum-restart/prediction/BASECASE")) + pred = EclSum(self.createTestPath("Equinor/ECLIPSE/sum-restart/prediction/BASECASE"), include_restart=False) self.assertIsNotNone(hist) self.assertIsNotNone(base) @@ -311,7 +311,7 @@ class SumTest(EclTest): def test_segment(self): - sum = EclSum(self.createTestPath("Statoil/ECLIPSE/Oseberg/F8MLT/F8MLT-F4")) + sum = EclSum(self.createTestPath("Equinor/ECLIPSE/Oseberg/F8MLT/F8MLT-F4")) segment_vars = sum.keys("SOFR:F-8:*") self.assertIn("SOFR:F-8:1", segment_vars) for var in segment_vars: @@ -365,7 +365,7 @@ class SumTest(EclTest): # Loading this dataset is a test of loading a case where one report step is missing. def test_Heidrun(self): - sum = EclSum( self.createTestPath("Statoil/ECLIPSE/Heidrun/Summary/FF12_2013B3_CLEAN_RS")) + sum = EclSum( self.createTestPath("Equinor/ECLIPSE/Heidrun/Summary/FF12_2013B3_CLEAN_RS")) self.assertEqual( 452 , len(sum)) self.assertFloatEqual( 1.8533144e+8 , sum.last_value("FOPT")) @@ -422,13 +422,13 @@ class SumTest(EclTest): def test_aquifer(self): - case = EclSum( self.createTestPath( "Statoil/ECLIPSE/Aquifer/06_PRESSURE_R009-0")) + case = EclSum( self.createTestPath( "Equinor/ECLIPSE/Aquifer/06_PRESSURE_R009-0")) self.assertTrue( "AAQR:2" in case ) def test_restart_mapping(self): - history = EclSum( self.createTestPath( "Statoil/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0") ) - total = EclSum( self.createTestPath( "Statoil/ECLIPSE/SummaryRestart/Prediction/NOR-2013A_R007_PRED-0") , include_restart = True) + history = EclSum( self.createTestPath( "Equinor/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0") ) + total = EclSum( self.createTestPath( "Equinor/ECLIPSE/SummaryRestart/Prediction/NOR-2013A_R007_PRED-0") , include_restart = True) history_dates = history.get_dates( ) total_dates = total.get_dates( ) @@ -449,7 +449,7 @@ class SumTest(EclTest): def test_write(self): with TestAreaContext("my_space") as area: - intersect_summary = EclSum( self.createTestPath( "Statoil/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0"), lazy_load=False ) + intersect_summary = EclSum( self.createTestPath( "Equinor/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0"), lazy_load=False ) self.assertIsNotNone(intersect_summary) write_location = os.path.join(os.getcwd(), "CASE") @@ -459,7 +459,7 @@ class SumTest(EclTest): self.assertEqual(intersect_summary.keys(), reloaded_summary.keys()) def test_ix_case(self): - intersect_summary = EclSum(self.createTestPath("Statoil/ECLIPSE/ix/summary/CREATE_REGION_AROUND_WELL")) + intersect_summary = EclSum(self.createTestPath("Equinor/ECLIPSE/ix/summary/CREATE_REGION_AROUND_WELL")) self.assertIsNotNone(intersect_summary) self.assertTrue( @@ -467,7 +467,7 @@ class SumTest(EclTest): [intersect_summary.smspec_node(key).wgname for key in intersect_summary.keys()] ) - eclipse_summary = EclSum(self.createTestPath("Statoil/ECLIPSE/ix/summary/ECL100/E100_CREATE_REGION_AROUND_WELL")) + eclipse_summary = EclSum(self.createTestPath("Equinor/ECLIPSE/ix/summary/ECL100/E100_CREATE_REGION_AROUND_WELL")) self.assertIsNotNone(eclipse_summary) hwell_padder = lambda key : key if key.split(":")[-1] != "HWELL_PR" else key + "OD" @@ -478,8 +478,8 @@ class SumTest(EclTest): def test_ix_write(self): for data_set in [ - "Statoil/ECLIPSE/ix/summary/CREATE_REGION_AROUND_WELL", - "Statoil/ECLIPSE/ix/troll/IX_NOPH3_R04_75X75X1_GRID2.SMSPEC" + "Equinor/ECLIPSE/ix/summary/CREATE_REGION_AROUND_WELL", + "Equinor/ECLIPSE/ix/troll/IX_NOPH3_R04_75X75X1_GRID2.SMSPEC" ]: with TestAreaContext("my_space" + data_set.split("/")[-1]) as area: @@ -496,7 +496,7 @@ class SumTest(EclTest): ) def test_ix_caseII(self): - troll_summary = EclSum( self.createTestPath("Statoil/ECLIPSE/ix/troll/IX_NOPH3_R04_75X75X1_GRID2.SMSPEC")) + troll_summary = EclSum( self.createTestPath("Equinor/ECLIPSE/ix/troll/IX_NOPH3_R04_75X75X1_GRID2.SMSPEC")) self.assertIsNotNone(troll_summary) self.assertTrue("WMCTL:Q21BH1" in list(troll_summary.keys())) @@ -525,7 +525,6 @@ class SumTest(EclTest): for time_index,t in enumerate(time_points): self.assertFloatEqual(resampled.iget( key, time_index), self.ecl_sum.get_interp_direct( key, t)) - def test_summary_units(self): self.assertEqual(self.ecl_sum.unit_system, EclUnitTypeEnum.ECL_METRIC_UNITS) @@ -534,4 +533,4 @@ class SumTest(EclTest): # which was shut down brutally. This test verifies that we # can create a valid ecl_sum instance from what we find. def test_broken_case(self): - ecl_sum = EclSum( self.createTestPath("Statoil/ECLIPSE/SummaryFail3/COMBINED-AUTUMN2018_CARBSENS-0")) + ecl_sum = EclSum( self.createTestPath("Equinor/ECLIPSE/SummaryFail3/COMBINED-AUTUMN2018_CARBSENS-0")) diff --git a/ThirdParty/Ert/python/tests/global_tests/test_import.py b/ThirdParty/Ert/python/tests/global_tests/test_import.py index 6681589a8d..ef3c3b5eb5 100644 --- a/ThirdParty/Ert/python/tests/global_tests/test_import.py +++ b/ThirdParty/Ert/python/tests/global_tests/test_import.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/global_tests/test_pylint.py b/ThirdParty/Ert/python/tests/global_tests/test_pylint.py index 1dac7dafaf..ce93f60934 100644 --- a/ThirdParty/Ert/python/tests/global_tests/test_pylint.py +++ b/ThirdParty/Ert/python/tests/global_tests/test_pylint.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Statoil ASA, Norway. +# Copyright (C) 2017 Equinor ASA, Norway. # # This file is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/legacy_tests/test_test.py b/ThirdParty/Ert/python/tests/legacy_tests/test_test.py index 1b75b2941f..ba588d6333 100644 --- a/ThirdParty/Ert/python/tests/legacy_tests/test_test.py +++ b/ThirdParty/Ert/python/tests/legacy_tests/test_test.py @@ -2,7 +2,6 @@ from ert.test import TestRun from ert.test import path_exists from ert.test import SourceEnumerator from ert.test import TestArea , TestAreaContext -from ert.test import TempArea , TempAreaContext from ert.test import ErtTestRunner from ert.test import PathContext from ert.test import LintTestCase diff --git a/ThirdParty/Ert/python/tests/util_tests/test_rng.py b/ThirdParty/Ert/python/tests/util_tests/test_rng.py index 2a4f786705..70148013c5 100644 --- a/ThirdParty/Ert/python/tests/util_tests/test_rng.py +++ b/ThirdParty/Ert/python/tests/util_tests/test_rng.py @@ -37,7 +37,6 @@ class RngTest(EclTest): with TestAreaContext("rng_state") as t: rng.saveState( "rng.txt" ) - t.sync() val1 = rng.getInt() val2 = rng.getInt() rng.loadState( "rng.txt" ) diff --git a/ThirdParty/Ert/python/tests/util_tests/test_vectors.py b/ThirdParty/Ert/python/tests/util_tests/test_vectors.py index 47d306aacd..e16cfcea75 100644 --- a/ThirdParty/Ert/python/tests/util_tests/test_vectors.py +++ b/ThirdParty/Ert/python/tests/util_tests/test_vectors.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2011 Equinor ASA, Norway. # # The file 'test_vectors.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/util_tests/test_version.py b/ThirdParty/Ert/python/tests/util_tests/test_version.py index c0864b4a20..0a82658b86 100644 --- a/ThirdParty/Ert/python/tests/util_tests/test_version.py +++ b/ThirdParty/Ert/python/tests/util_tests/test_version.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Statoil ASA, Norway. +# Copyright (C) 2015 Equinor ASA, Norway. # # The file 'test_version.py' is part of ERT - Ensemble based Reservoir Tool. # diff --git a/ThirdParty/Ert/python/tests/util_tests/test_work_area.py b/ThirdParty/Ert/python/tests/util_tests/test_work_area.py index 0d7a69bae5..1a89ac7621 100644 --- a/ThirdParty/Ert/python/tests/util_tests/test_work_area.py +++ b/ThirdParty/Ert/python/tests/util_tests/test_work_area.py @@ -1,21 +1,21 @@ #!/usr/bin/env python -# Copyright (C) 2014 Statoil ASA, Norway. -# +# Copyright (C) 2014 Equinor ASA, Norway. +# # The file 'test_work_area.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 +# +# 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 # for more details. -import os.path +import os.path import os try: @@ -23,7 +23,7 @@ try: except ImportError: from unittest import skipIf -from ecl.util.test import TestAreaContext, TempAreaContext +from ecl.util.test import TestAreaContext from tests import EclTest @@ -33,39 +33,20 @@ class WorkAreaTest(EclTest): with TestAreaContext("TestArea") as test_area: with open("test_file" , "w") as fileH: fileH.write("Something") - + self.assertTrue( os.path.isfile( "test_file") ) - + with self.assertRaises(IOError): full_path = test_area.getFullPath( "does/not/exists" ) with self.assertRaises(IOError): full_path = test_area.getFullPath( "/already/absolute" ) - + full_path = test_area.getFullPath( "test_file" ) self.assertTrue( os.path.isfile( full_path )) self.assertTrue( os.path.isabs( full_path )) - - def test_temp_area(self): - with TestAreaContext("TestArea") as test_area: - cwd = os.getcwd() - with open("file.txt" , "w") as f: - f.write("File") - - with TempAreaContext("TempArea") as temp_area: - self.assertEqual( cwd, os.getcwd()) - self.assertEqual( cwd, temp_area.get_cwd()) - temp_area.copy_file( "file.txt" ) - self.assertTrue( os.path.isfile( os.path.join( temp_area.getPath( ) , "file.txt"))) - - os.mkdir("tmp") - os.chdir("tmp") - - self.assertEqual( os.getcwd() , os.path.join( cwd , "tmp")) - - def test_IOError(self): with TestAreaContext("TestArea") as test_area: with self.assertRaises(IOError): @@ -86,40 +67,33 @@ class WorkAreaTest(EclTest): with self.assertRaises(IOError): test_area.copy_directory( "path1/file.txt" ) - - def test_sync(self): - with TestAreaContext("test_sync") as t: - with open("file.txt" , "w") as f: - f.write("content") - t.sync() - self.assertTrue( os.path.isfile( "file.txt")) - + def test_multiple_areas(self): original_dir = os.getcwd() context_dirs = [] for i in range(3): loop_dir = os.getcwd() - self.assertEqual(loop_dir, original_dir, + self.assertEqual(loop_dir, original_dir, 'Wrong folder before creating TestAreaContext. Loop: {} -- CWD: {} ' .format(i, loop_dir)) - + with TestAreaContext("test_multiple_areas") as t: t_dir = t.get_cwd() - - self.assertNotIn(t_dir, context_dirs, + + self.assertNotIn(t_dir, context_dirs, 'Multiple TestAreaContext objects in the same folder. Loop {} -- CWD: {}' .format(i, loop_dir)) context_dirs.append(t_dir) - + # It is possible to make the following assert fail, but whoever run the tests should # try really really hard to make that happen - self.assertNotEqual(t_dir, original_dir, + self.assertNotEqual(t_dir, original_dir, 'TestAreaContext in the current working directory. Loop: {} -- CWD: {}' - .format(i, loop_dir)) - + .format(i, loop_dir)) + loop_dir = os.getcwd() - self.assertEqual(loop_dir, original_dir, + self.assertEqual(loop_dir, original_dir, 'Wrong folder after creating TestAreaContext. Loop: {} -- CWD: {} ' .format(i, loop_dir)) - + diff --git a/ThirdParty/Ert/python/tests/well_tests/CMakeLists.txt b/ThirdParty/Ert/python/tests/well_tests/CMakeLists.txt index 00d362918c..f943b5d5f4 100644 --- a/ThirdParty/Ert/python/tests/well_tests/CMakeLists.txt +++ b/ThirdParty/Ert/python/tests/well_tests/CMakeLists.txt @@ -3,6 +3,7 @@ set(TEST_SOURCES test_ecl_well.py test_ecl_well2.py test_ecl_well3.py + test_well_missing_ICON.py ) add_python_package("python.tests.well_tests" ${PYTHON_INSTALL_PREFIX}/tests/well_tests "${TEST_SOURCES}" False) @@ -10,3 +11,4 @@ add_python_package("python.tests.well_tests" ${PYTHON_INSTALL_PREFIX}/tests/wel addPythonTest(tests.well_tests.test_ecl_well.EclWellTest) addPythonTest(tests.well_tests.test_ecl_well2.EclWellTest2) addPythonTest(tests.well_tests.test_ecl_well3.EclWellTest3) +addPythonTest(tests.well_tests.test_well_missing_ICON.EclWellICONTest) diff --git a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py index cb3b5c3038..391fe05c52 100644 --- a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py +++ b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py @@ -2,11 +2,11 @@ import datetime from ecl import EclFileFlagEnum from ecl.eclfile import EclFile from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl.util.util.ctime import CTime from ecl.well import WellInfo, WellConnection, WellTypeEnum, WellConnectionDirectionEnum, WellSegment -@statoil_test() +@equinor_test() class EclWellTest(EclTest): ALL_WELLS = ['E5H', 'G1H', 'M41', 'J41', 'D10H', 'P41', 'L41', 'M42', 'S41', 'S13H', 'Q12HT2', 'O41', 'L11H', 'Q21H', 'E6CH', 'D4Y1H', 'D4Y2H', 'I13Y1H', 'Q21AY1H', 'F5AH', 'O14Y4HT2', 'K24Y1H', 'K24Y3H', 'S21H', 'N11H', @@ -39,8 +39,8 @@ class EclWellTest(EclTest): def getWellInfoWithNoWellSegments(self): """ @rtype: WellInfo """ if EclWellTest.__well_info_with_no_well_segments is None: - grid_path = self.createTestPath("Statoil/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.EGRID") - rst_path_1 = self.createTestPath("Statoil/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.X0135") + grid_path = self.createTestPath("Equinor/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.EGRID") + rst_path_1 = self.createTestPath("Equinor/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.X0135") grid = EclGrid(grid_path) @@ -54,8 +54,8 @@ class EclWellTest(EclTest): def getWellInfo(self): """ @rtype: WellInfo """ if EclWellTest.__well_info is None: - grid_path = self.createTestPath("Statoil/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.EGRID") - rst_path_1 = self.createTestPath("Statoil/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.X0135") + grid_path = self.createTestPath("Equinor/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.EGRID") + rst_path_1 = self.createTestPath("Equinor/ECLIPSE/Troll/MSW/T07-4A-W2012-16-F3.X0135") grid = EclGrid(grid_path) @@ -68,7 +68,7 @@ class EclWellTest(EclTest): def test_no_such_well(self): - grid_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") + grid_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") rst_path1 = self.createTestPath("nosuch/path/ECLIPSE.X001") rst_path2 = self.createTestPath("nosuch/path/ECLIPSE.X002") grid = EclGrid(grid_path) @@ -78,11 +78,11 @@ class EclWellTest(EclTest): _ = WellInfo(grid, [rst_path1, rst_path2]) def test_construction(self): - grid_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") - rst_path_1 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0011") - rst_path_2 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0022") - rst_path_3 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0035") - rst_path_4 = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.X0061") + grid_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") + rst_path_1 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0011") + rst_path_2 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0022") + rst_path_3 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0035") + rst_path_4 = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.X0061") grid = EclGrid(grid_path) @@ -449,7 +449,7 @@ class EclWellTest(EclTest): def test_load_broken_direction(self): - grid_path = self.createTestPath("Statoil/ECLIPSE/icon-invalid-value/R6_HM2016B_FFP_BASE.EGRID") - rst_path = self.createTestPath("Statoil/ECLIPSE/icon-invalid-value/R6_HM2016B_FFP_BASE.UNRST") + grid_path = self.createTestPath("Equinor/ECLIPSE/icon-invalid-value/R6_HM2016B_FFP_BASE.EGRID") + rst_path = self.createTestPath("Equinor/ECLIPSE/icon-invalid-value/R6_HM2016B_FFP_BASE.UNRST") grid = EclGrid(grid_path) well_info = WellInfo(grid, rst_path) diff --git a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well2.py b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well2.py index 554e18bda2..2535228939 100644 --- a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well2.py +++ b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well2.py @@ -4,19 +4,19 @@ import os.path from ecl import EclFileFlagEnum from ecl.eclfile import EclFile from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl.util.util.ctime import CTime from ecl.well import WellInfo, WellConnection, WellTypeEnum, WellConnectionDirectionEnum, WellSegment -@statoil_test() +@equinor_test() class EclWellTest2(EclTest): grid = None def getGrid(self): if EclWellTest2.grid is None: - EclWellTest2.grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Troll/Ref2014/T07-4A-W2014-06.EGRID")) + EclWellTest2.grid = EclGrid( self.createTestPath("Equinor/ECLIPSE/Troll/Ref2014/T07-4A-W2014-06.EGRID")) return EclWellTest2.grid @@ -25,7 +25,7 @@ class EclWellTest2(EclTest): segment_length = [2660 , 20 , 121 , 1347.916 , 20.585 , 56.249 , 115.503 , 106.978 , 47.124 , 279.529, 128.534 , 165.33 , 59.97 , 936.719 ] - well_info = WellInfo( self.getGrid() , self.createTestPath( os.path.join("Statoil/ECLIPSE/Troll/Ref2014" , rst_file ))) + well_info = WellInfo( self.getGrid() , self.createTestPath( os.path.join("Equinor/ECLIPSE/Troll/Ref2014" , rst_file ))) well_time_line = well_info["F4BYH"] for well_state in well_time_line: self.assertTrue( well_state.isMultiSegmentWell() ) diff --git a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well3.py b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well3.py index 9252f111d6..027cfc47cf 100644 --- a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well3.py +++ b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well3.py @@ -4,18 +4,18 @@ import os.path from ecl.eclfile import EclFile from ecl.grid import EclGrid from ecl.summary import EclSum -from tests import EclTest, statoil_test +from tests import EclTest, equinor_test from ecl.util.util.ctime import CTime from ecl.well import WellInfo, WellConnection, WellTypeEnum, WellConnectionDirectionEnum, WellSegment -@statoil_test() +@equinor_test() class EclWellTest3(EclTest): grid = None def test_rates(self): - grid_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") - rst_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST") - sum_path = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") + grid_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.EGRID") + rst_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.UNRST") + sum_path = self.createTestPath("Equinor/ECLIPSE/Gurbat/ECLIPSE.SMSPEC") grid = EclGrid(grid_path) well_info = WellInfo(grid, rst_path) diff --git a/ThirdParty/Ert/python/tests/well_tests/test_well_missing_ICON.py b/ThirdParty/Ert/python/tests/well_tests/test_well_missing_ICON.py new file mode 100644 index 0000000000..28cb69d1af --- /dev/null +++ b/ThirdParty/Ert/python/tests/well_tests/test_well_missing_ICON.py @@ -0,0 +1,28 @@ +import datetime +from tests import EclTest +from ecl.grid import EclGridGenerator +from ecl.well import WellInfo, WellConnection, WellTypeEnum, WellConnectionDirectionEnum, WellSegment + + + + +class EclWellICONTest(EclTest): + + def setUp(self): + self.grid = EclGridGenerator.create_rectangular((46,112,22), (1,1,1)) + self.rst_file_ICON0 = self.createTestPath("local/ECLIPSE/well/missing-ICON/ICON0.X0027") + self.rst_file_ICON1 = self.createTestPath("local/ECLIPSE/well/missing-ICON/ICON1.X0027") + + + def check_connections(self, well_info, expected): + well = well_info["B-2H"] + well_state = well[0] + self.assertEqual( well_state.hasGlobalConnections(), expected) + + + def test_missing_icon(self): + well_info_ICON0 = WellInfo(self.grid, self.rst_file_ICON0) + well_info_ICON1 = WellInfo(self.grid, self.rst_file_ICON1) + + self.check_connections(well_info_ICON0, False) + self.check_connections(well_info_ICON1, True) diff --git a/ThirdParty/Ert/python/txt-doc/README.txt b/ThirdParty/Ert/python/txt-doc/README.txt new file mode 100644 index 0000000000..7a7a6b294a --- /dev/null +++ b/ThirdParty/Ert/python/txt-doc/README.txt @@ -0,0 +1,4 @@ +The files 'devel.txt', 'import.txt', 'tips.txt' and 'install.txt' in the 'txt-doc/' +directory are old text files with documentation. The content of these files is - +to a varyiing degree - relevant and valuable, but it should be integrated into +the rst files, and then deleted. diff --git a/ThirdParty/Ert/python/doc/devel.txt b/ThirdParty/Ert/python/txt-doc/devel.txt similarity index 99% rename from ThirdParty/Ert/python/doc/devel.txt rename to ThirdParty/Ert/python/txt-doc/devel.txt index 7bae061d39..0b72477791 100644 --- a/ThirdParty/Ert/python/doc/devel.txt +++ b/ThirdParty/Ert/python/txt-doc/devel.txt @@ -13,7 +13,7 @@ Developer documentation 4.2 Prototyping 4.3 Python classes 5 Garbage collection and 'data_owner' - 6 Installation in Statoil + 6 Installation in Equinor @@ -210,12 +210,12 @@ The following excerpt from ecl_kw.y illustrates this: # Load the shared library import libecl <--- Step 1 - Class EclKW: <-------------· + Class EclKW: <-------------� # Pure Python code to implement the EclKW class, | # based on the functions prototyped below. | Step 3 - .... <-------------· + .... <-------------� - # Create a wrapper instance which wraps the libecl library. <--------· + # Create a wrapper instance which wraps the libecl library. <--------� cwrapper = CWrapper( libecl.lib ) | | # Register the type mapping "ecl_kw" <-> EclKW | Step 2 @@ -224,7 +224,7 @@ The following excerpt from ecl_kw.y illustrates this: # Prototype the functions needed to implement the Python class | cfunc.alloc_new = cwrapper.prototype("long ecl_kw_alloc( char* , int , int )") cfunc.free = cwrapper.prototype("void ecl_kw_free( ecl_kw )") | - .... <--------· + .... <--------� ------------------------------------------------------------ These three steps are described in more detail in 4.1 - 4.3 below. @@ -423,7 +423,7 @@ takeover' or 'orphaning' of objects). -6 Installation in Statoil +6 Installation in Equinor -In Statoil the ert Python libraries are installed in the /project/res +In Equinor the ert Python libraries are installed in the /project/res hierarchy. diff --git a/ThirdParty/Ert/python/doc/import.txt b/ThirdParty/Ert/python/txt-doc/import.txt similarity index 100% rename from ThirdParty/Ert/python/doc/import.txt rename to ThirdParty/Ert/python/txt-doc/import.txt diff --git a/ThirdParty/Ert/python/doc/install.txt b/ThirdParty/Ert/python/txt-doc/install.txt similarity index 100% rename from ThirdParty/Ert/python/doc/install.txt rename to ThirdParty/Ert/python/txt-doc/install.txt diff --git a/ThirdParty/Ert/docs/tips.txt b/ThirdParty/Ert/python/txt-doc/tips.txt similarity index 99% rename from ThirdParty/Ert/docs/tips.txt rename to ThirdParty/Ert/python/txt-doc/tips.txt index d6bf3c18dc..40e8b9c349 100644 --- a/ThirdParty/Ert/docs/tips.txt +++ b/ThirdParty/Ert/python/txt-doc/tips.txt @@ -4,7 +4,7 @@ Table of contents: 2. About gen_data / gen_param and gen_obs. 3. Some tips for implementing a obs_script 4. About the ERT filesystem - 5. Installing ERT software in Statoil + 5. Installing ERT software in Equinor ********************************************************************** @@ -440,7 +440,7 @@ program, the block_fs system then has an api for reading and writing The block_fs_driver/block_fs combination is quite complex, but it has not had any hickups for about 1.5 years of extensive use in -Statoil. Observe that if you pull the plug on ERT you might loose some +Equinor. Observe that if you pull the plug on ERT you might loose some of the data which has been stored with the block_fs driver, but partly written and malformed data will be detected and discarded at the next boot. You are therefore guaranteed (add as many quotes you like to the @@ -524,10 +524,10 @@ enkf_fs. Not very important functions, but convenient enough. ********************************************************************** -5. Installing ERT software in Statoil +5. Installing ERT software in Equinor ------------------------------------- -Installation of research software in Statoil is according to the +Installation of research software in Equinor is according to the general guideline: 1. Log in to a computer in Trondheim with the correct version of diff --git a/ThirdParty/Ert/redhat/ecl.spec b/ThirdParty/Ert/redhat/ecl.spec index cca9c92159..7c85366a8e 100644 --- a/ThirdParty/Ert/redhat/ecl.spec +++ b/ThirdParty/Ert/redhat/ecl.spec @@ -2,7 +2,7 @@ # spec file for package ecl # -%define tag final +%define tag rc1 Name: ecl Version: 2018.10 @@ -11,7 +11,7 @@ Summary: ECL library License: GPL-3+ Group: Development/Libraries/C and C++ Url: http://ert.nr.no -Source0: https://github.com/Statoil/libecl/archive/release/%{version}/%{tag}.tar.gz#/%{name}-%{version}.tar.gz +Source0: https://github.com/Equinor/libecl/archive/release/%{version}/%{tag}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: lapack-devel zlib-devel iputils BuildRequires: devtoolset-6-toolchain %{?!el6:BuildRequires: python-devel numpy python-pandas python-cwrap} diff --git a/ThirdParty/Ert/requirements.txt b/ThirdParty/Ert/requirements.txt index 4d44c49dca..303f7ff42b 100644 --- a/ThirdParty/Ert/requirements.txt +++ b/ThirdParty/Ert/requirements.txt @@ -1,3 +1,7 @@ cwrap numpy pandas +sphinx +future +six +functools32;python_version=='2.7' diff --git a/ThirdParty/Ert/script/download-pr b/ThirdParty/Ert/script/download-pr index 7e6f01ad12..fb82bb3940 100644 --- a/ThirdParty/Ert/script/download-pr +++ b/ThirdParty/Ert/script/download-pr @@ -4,7 +4,7 @@ import json import os import sys -url_fmt = "https://api.github.com/repos/Statoil/libecl/pulls/%d" +url_fmt = "https://api.github.com/repos/Equinor/libecl/pulls/%d" def getPRList( api_token, pr1, pr2): pr = pr1 @@ -38,7 +38,7 @@ def printPRList( pr_list , fileH): title = pr["title"] body = pr["body"] nr = pr["number"] - url = "https://github.com/Statoil/libecl/pull/{}/".format(nr) + url = "https://github.com/Equinor/libecl/pull/{}/".format(nr) try: title = str(title) diff --git a/ThirdParty/Ert/setup.py b/ThirdParty/Ert/setup.py index 5dacb9973b..ac71393d32 100644 --- a/ThirdParty/Ert/setup.py +++ b/ThirdParty/Ert/setup.py @@ -31,13 +31,13 @@ class CMakeBuild(build_ext): subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp) setup( - name='statoil_libecl', + name='equinor_libecl', version='0.1.1', author_email='chandan.nath@gmail.com', description='libecl', long_description=open("README.md", "r").read(), long_description_content_type="text/markdown", - url="https://github.com/statoil/libecl", + url="https://github.com/equinor/libecl", license="GNU General Public License, Version 3, 29 June 2007", packages=find_packages(where='python', exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), package_dir={'': 'python'}, diff --git a/ThirdParty/Ert/test-data/README.txt b/ThirdParty/Ert/test-data/README.txt index 2e7e908124..182de174d3 100644 --- a/ThirdParty/Ert/test-data/README.txt +++ b/ThirdParty/Ert/test-data/README.txt @@ -2,11 +2,11 @@ This directory is meant as a holding place for test data for the ERT project. The local/ directory should contain test-data which is checked in an distributed as part of the solution. -In addition many of the tests expect to find a Statoil/ subdirectory -in the current directory. This directory should link to Statoil +In addition many of the tests expect to find a Equinor/ subdirectory +in the current directory. This directory should link to Equinor internal test data. This data is currently located on the enkf disk in -Bergen; before you can start using the Statoil specific test data you +Bergen; before you can start using the Equinor specific test data you must add the following symlink: - ln -s /ErtTestData Statoil + ln -s /ErtTestData Equinor diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SHORT.SMSPEC b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SHORT.SMSPEC new file mode 100644 index 0000000000000000000000000000000000000000..ffeee8809c9d3787541f14210e30b638f28527e5 GIT binary patch literal 64700 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 z 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 O2=mMO`u`pM`~Lu!y8uuC literal 0 HcmV?d00001 diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA index ccfa835647..d1447bee5a 100644 --- a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA +++ b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA @@ -3,7 +3,7 @@ -- individual contents of the database are licensed under the Database Contents -- License: http://opendatacommons.org/licenses/dbcl/1.0/ --- Copyright (C) 2016 Statoil +-- Copyright (C) 2016 Equinor -- NOTE: This deck is currently not supported by the OPM -- simulator flow due to lack of support for LGR. diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON0.X0027 b/ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON0.X0027 new file mode 100644 index 0000000000000000000000000000000000000000..37ad813f10d487d0a83ae948be7b627ec7a30796 GIT binary patch literal 9280 zcmeHMO-NKx6uzc4{a6mEVP+&);-V4CexSfNzc_-Wgb}oih!!o{BxNlkT=qlK#?gf> zTa+zw5d;ZE(I%o6)v_=NLast9=bd}s_s+X_?j5C6 zxbt9dDxHcYl`0!%S)om-6{nz;DzBcxwahISURu#~8rY!J?Q41FkS?!;-U?I!y#V6Q zl3~>PflEO7EQ?p!2-O1Y)3$MF_ID3huG=`a^*|l48erecfC_*@yJ`Hc!yK2jupwsX zIdna+X%1hSWK7~#i30oPGvtqfe2^OoxGRw31uZ##B#!7JuC_@tK#mA zf@IUiTEYyt>rFV>eK_u|Md|~~AOvehs3m%)$K}SE@hFONRe?D7hbS56QJX7KJ*zse zyn0rPU(c}vFF)V<-roQEOXk5?+Nt03{!>FD;zcuG3;NUdIXC*>b=;{rFWM9#Sv$7* z?D*xVXp`T+((Vj+&utp7Jf~=rU#WJvUvw$|hdMt>`OViZ{fmz8P4|675a+9xXHt)~ z4qTjX?BDU1@kk8E{TzleQuk~5e*Eo!s~+up;dWi}JC^TPwBb9>ey2J=+wVU4Hab3i z#nJwv{m;Aq>B!B>!FZE1v)j2aef^}^{d~!M5*3F(q+`v=Np=-$?zl=V<8q$4FFfPC z)mrDHj8pu0PrhXRr%t#M%{Tr+S>pP&|JJPCFwaW z^^aG0DRqC&9%?~3+|}LDsn^kSEVB(ig(rV#$@$yT|HnWX=ZbLWkyKYB1Y6-ZxqW@r zC~RwhCV=}F?v)9aD**1pWiM{r-yn@f;8#?bVnq#Jqnr)Q;bJ!B#g;LeovmdtFu=2p zEx;;(`)~e2mwe-SiJX}%=3J98Vz^coF#|m3A^5&{cE?=fJi*+uxdsxf1jfKRL}~yy zuL(HU*<1q&Rsv;!>t-Xs+~WLJ1K2ebBv=WYfoeo-1|-+`zn7iY0;kyq1Ov>i?SSN3 ztu8O|eJJ nBC;#Z^Eto7BRh+>CnGxy?Zy4$hWJTCd%_Su6=^HlFQ4HjU3Hwz literal 0 HcmV?d00001 diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON1.X0027 b/ThirdParty/Ert/test-data/local/ECLIPSE/well/missing-ICON/ICON1.X0027 new file mode 100644 index 0000000000000000000000000000000000000000..7ed2efdc203e62e5762786591e8c7947eb484740 GIT binary patch literal 38168 zcmeI5ONbm*6oxB~W_(0v)I?(**bx@$ zNfzVMg~o+h2!a7caU-G&b*X3&BoKAsMu_LTUH_!*>8ks1#>C`YICHD3PTjBS?|S|B zRwq?ejqlpCf5+U8soAPpahU1K=2g|oC#|lkk!w%b-xXnc@tnV%ts_Na>`WBDY z)0bL(v&ERjehX{&ALX!pI$-gV#mGOF^gi5R)fS8U>Sf2QhWCNRCG|YE?HY@<7MEMV zzR2QY3ku7dwm&4a{JGMWS(~F@TD{IHjv`tD|WfQR3hyHCq5453}c8khmi{_ls zNA0K{lIpW+1<;5<<2NigK9;ihcd(RddRrH;0^xo$KD+m!>E6Al`k84H#O@iRTPC00 z7qsb~>Pa-oUBycG!?!4hx}V$`%4B_2?S9kyyihA|-=hzF{o6Z#Z9nks?}t7*I@euy z&yT-un3?Fc*8F!7uU@bF=7Aq}zPI{$)lDtTt~t8#*<&wHs&2~rzs&C*?Cp2c_G&*> zH|53VYkk$R{EzG7BbJxDTzu8j_s%`@i#5{yqj#L?^VGJ3FXp!WZ}PQ0YNH!Yhqn&t z^I)y>XK?=6`aJo}R{r+8 zEaabfJe0})g$dJYcd#B@bzynKbymmka@FDwZr5^u)_vvETYA_17*E&J!R?hUvGva^ zAKhZpAIZB_o?$wffZaU#&f-_`1-MVTXu!T zCJX!vUYTI}Vhen@ym+I(vBT(y$U)$Qo=44-TE+{}>$Bh=3 zS>V5ULf7#|e~J1`&gElG+i08Xg4HjJ2 z6kO~4SThm4EU5zAH#-&_TU_5(TlhWHMDViY3S4U~Znn^|#<-VX*OpvnZ_pIr*xG8L zV{J`6eS!N>Jo?CS)56QrE5MlioJIdJ$MYMX-6NO?UY1IMa1M_@vd|A#t(}>hdeB<8 zzS!#c%*0)D^v?~J>4`gr&YzvQytFf$YIqMG={2hJRsSNUS8Td!WU|=vdLuqS6W6-_Kw7>L$ z(jS`2Air%JhEVBeBtpLz<4PTil>MQfER$8Ov~~E6PRAmJL4GcScZ>MVP{$&LL4GcS zcM3LI+?2>5KbK*vcyR?>0aw5ka0OfeSHKl;1W}F;aXK`MLYScOVAix0JU1 zAU~JEcOVAueNfsMTme_W6*ylN z;5nM#+3`Dp6t6=*zAdMa4})=|6bAXZ44(I4;1g09R2#coj&~+?-n){ax%wU!gI11;h8zYASahWz8GQM z2!otl20l*={8&t@((ytu@MAGX>3E?S_^}wHbi7au{8)@pI$kJ7@NALqykNXActJ6! zWBb8&Ox#%zXxeUgI#h^cc(#9Y^mmz=Nv32?F zckKHhKbN6?hK{YvJN7XK`MC`Bmvn4h{?CONgZx|u`sn-MJ^mPj{7lB!d_A6yPGZsD z6l0N}$qG8b;645n2D;`l&`AvX=3@InelA1(aqI_uj4=lJxeS{1;tIF|u7E4x3gjxl za~t=z%@*MqF7j+mPVPMlpC`t0`a&4DTBI=8hurI=n4@t&o=P>dAsS?UYL;CYeK=5@%)J+AP1VlYihuKlS_S} z7%A^3m-<36Qha);FBBuirI=mP zek#H!^@U;tKNVq=`a&^+pNcR_eW4h^PemA|zEF(dry`6}UnoY3*D3XdVg#>a*Os=v zfKp#5M(`mKMyW3pBlwR9qtq9Q5xhZ!QR)lDNbv@xzEF&m=XUlr_a4QzueaE0k-{K9 zmtm`TNmF3Kr>CWRmMh>2xB_Qi0iH#8KAW=$&n1!PtWsYn#&Y^XF~WT=vLEE+-VgD4 zVx)MsQeP-W@ND{CtR7ZMeW4h^vsuG!&!nZkP>kT&B8*aBC`RyX5k{#m6eDE}tkf5Z zK^^OxDfNY7q>O=;`a&^MJR7;W=OEiIMv7-E^@U=jj8B#NLNQXtr%HXH7%AgZrM^&% zlyRw2UnoY(m{F-O6k|Dkp%^Kit<)Ea5&ACed}+J3yDv0>yj&;>;L}Gs7s}rHe!2o> I3XF9A27q0mlK=n! literal 0 HcmV?d00001 diff --git a/ThirdParty/Ert/test-data/local/util/latex/report_OK.tex b/ThirdParty/Ert/test-data/local/util/latex/report_OK.tex index 21c215939b..7c17203c07 100644 --- a/ThirdParty/Ert/test-data/local/util/latex/report_OK.tex +++ b/ThirdParty/Ert/test-data/local/util/latex/report_OK.tex @@ -1,7 +1,7 @@ \documentclass[screen,8pt]{beamer} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} -\usetheme{statoil} +\usetheme{equinor} \usepackage{amsmath,amssymb,amsfonts} \usepackage{graphicx} \usepackage[tight]{subfigure} diff --git a/ThirdParty/Ert/test-data/local/util/latex/report_error.tex b/ThirdParty/Ert/test-data/local/util/latex/report_error.tex index 1a51a6bc7f..d09d5c3835 100644 --- a/ThirdParty/Ert/test-data/local/util/latex/report_error.tex +++ b/ThirdParty/Ert/test-data/local/util/latex/report_error.tex @@ -1,7 +1,7 @@ \documentclass[screen,8pt]{beamer} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} -\usetheme{statoil} +\usetheme{equinor} \usepackage{amsmath,amssymb,amsfonts} \usepackage{graphicx} \usepackage[tight]{subfigure}