diff --git a/pyproject.toml b/pyproject.toml index 567e1bf1f..6acb3c64f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ test = [ "pandas-stubs", "types-setuptools", "types-PyYAML", +"gstools", ] [tool.black] diff --git a/semeio/workflows/localisation/local_script_lib.py b/semeio/workflows/localisation/local_script_lib.py index a3084c065..a6da7373d 100644 --- a/semeio/workflows/localisation/local_script_lib.py +++ b/semeio/workflows/localisation/local_script_lib.py @@ -1078,15 +1078,6 @@ def add_ministeps( param_for_field, user_config.log_level, ) - - # write_qc_parameter_field( - # node_name, - # corr_spec.name, - # corr_spec.field_scale, - # grid_for_field, - # param_for_field, - # user_config.log_level, - # ) update_step["row_scaling_parameters"].append( [node_name, row_scaling] ) diff --git a/tests/workflows/localisation/example_case/README b/tests/workflows/localisation/example_case/README new file mode 100644 index 000000000..9fba569d5 --- /dev/null +++ b/tests/workflows/localisation/example_case/README @@ -0,0 +1,55 @@ +## Directory for Test Case for Non-Adaptive Localisation (`LOCALISATION_JOB`) +​ +### Main Components: +​ +- **ERT config file:** `sim_field.ert` +​ + The ERT model depends on: + - `scripts/sim_fields.py` + - `scripts/common_functions.py` +​ +​ +- **ERT Keyword Input:** + - **GRID:** Input grid is made by `scripts/make_reference_data.py` + - **OBS_CONFIG:** Observations are extracted from an upscaled realization made by `scripts/make_reference_data.py` + - **GEN_DATA:** Prediction of observables made by forward model `SIM_FIELD` which runs `scripts/sim_fields.py` + - **FIELD:** Prior realizations of field made by forward model `SIM_FIELD` which runs `scripts/sim_fields.py` +​ +- **Other ERT Input Files:** + - `localisation.wf` +​ +- **Other Files:** + - `randomseeds.txt`: Not used by ERT, but by `sim_fields.py`. This file can be generated by `scripts/make_reference_data.py` + - `UpscaledGrid.EGRID`: Not used by ERT, but by `sim_fields.py`. This file can be generated by `scripts/make_reference_data.py` +​ +### Typical Workflow: +​ +- **Preparation to create reference data:** + - Prepare ERT config input by running `scripts/make_reference_data.py`. + - The preparation step is **only necessary** if the reference data need to be updated. + - QC manually the created reference data (GRDECL files to appear in the init_files directory). + - The created reference data should be checked into git if they are modified. + - The reference data is used to check the results from running pytest on test_full.py + +​- **Run the pytest on test_full.py** + - The test script will run through a number of cases and compare a selected realization with the reference. + +- **How to modify the test:** + - To modify the test, edit the template file for the ERT configuration file + - Edit the alternative parameter settings in the file common_function.py + - Run the script scripts/make_reference_data.py + - QC manually the created reference data files + - Add the new reference files to git + +### What the Script `sim_fields.py` Does: +1. It must be installed as a FORWARD model in ERT. This is done in the ERT config template file. +​1. Requires 4 input arguments: iteration number, realization_number, config file , config path +1. Get iteration and realisation number from ERT. +2. If iteration = 0, then: + - Simulate field and export to file to be used in `FIELD` keyword in ERT config file. + - Upscale field and optionally export to file for QC purpose. + Else: + - Import updated field from ERT. + - Upscale field and optionally export file for QC purpose. +3. Extract predicted values of observables from upscaled field (values for selected grid cells related to the upscaled grid) and write `GEN_DATA` files. +4. Optionally write some files for QC purpose.Directory for test case for non-adaptive localisation (LOCALISATION_JOB) diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A2_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A2_local.grdecl new file mode 100644 index 000000000..718a55f64 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A2_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.003016 -0.494571 + -1.028435 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 -0.829884 + -1.867067 -2.117355 -1.216993 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 -1.915480 -2.726342 -3.124574 + -2.504564 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 -0.876790 -0.636449 -0.371928 -0.186803 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 999999999999999945575230987042816.000000 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 999999999999999945575230987042816.000000 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 999999999999999945575230987042816.000000 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 999999999999999945575230987042816.000000 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A_local.grdecl new file mode 100644 index 000000000..13da8ea21 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_A_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_B_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_B_local.grdecl new file mode 100644 index 000000000..13da8ea21 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_B_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_C_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_C_local.grdecl new file mode 100644 index 000000000..cdf227831 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_C_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.662012 0.092502 -1.249170 -2.481425 -2.643038 -2.015550 + -1.732791 -2.259825 -3.021738 -3.374325 2.535338 2.215707 + 0.622777 -1.049959 -1.704248 -1.537606 -1.549673 -2.107112 + -2.676758 -2.857547 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 0.545837 -0.318973 -0.824143 -0.816984 -0.678996 -0.777436 + -0.967488 -0.856602 -0.316280 0.517896 -0.841584 -1.226023 + -1.207091 -0.902073 -0.387598 0.025259 -0.029104 -0.373039 + -0.433728 0.006049 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.995523 -1.374976 -0.900708 0.206069 1.040176 1.223922 + 1.279978 1.478402 1.243197 0.178017 0.235147 0.157758 + 0.172461 0.312229 0.509417 0.808807 1.215309 1.370256 + 0.795799 -0.342228 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + -0.049208 0.944598 1.588994 1.513464 1.166571 1.047943 + 1.075387 0.881568 0.389300 -0.185701 -0.035406 1.009202 + 1.709299 1.983187 1.760534 0.946370 0.064703 -0.146747 + 0.213693 0.432429 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + 1.324994 0.901444 0.074174 -0.849109 -1.649805 -1.964304 + -1.696768 -1.163499 -0.598027 -0.028493 1.430932 1.254107 + 0.654710 -0.078125 -0.653691 -0.862671 -0.729918 -0.454728 + -0.200309 -0.092174 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + -0.057085 -0.287224 -0.724738 -0.876790 -0.636449 -0.371928 + -0.186803 0.130124 0.381840 0.089729 0.439765 -0.143754 + -1.070861 -1.915480 -2.726342 -3.124574 -2.504564 -1.177302 + -0.224223 -0.178808 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.526481 0.509107 0.391517 -0.025932 -0.279426 -0.127581 + 0.017761 -0.193278 -0.633775 -1.029683 0.648341 0.376487 + 0.306689 0.234835 0.003016 -0.494571 -1.028435 -1.095739 + -0.725329 -0.679467 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_D.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_D.grdecl new file mode 100644 index 000000000..13da8ea21 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_D.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_E_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_E_local.grdecl new file mode 100644 index 000000000..13da8ea21 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_E_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_F_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_F_local.grdecl new file mode 100644 index 000000000..13da8ea21 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_F_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_G_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_G_local.grdecl new file mode 100644 index 000000000..cdf227831 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter0_G_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.662012 0.092502 -1.249170 -2.481425 -2.643038 -2.015550 + -1.732791 -2.259825 -3.021738 -3.374325 2.535338 2.215707 + 0.622777 -1.049959 -1.704248 -1.537606 -1.549673 -2.107112 + -2.676758 -2.857547 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 0.545837 -0.318973 -0.824143 -0.816984 -0.678996 -0.777436 + -0.967488 -0.856602 -0.316280 0.517896 -0.841584 -1.226023 + -1.207091 -0.902073 -0.387598 0.025259 -0.029104 -0.373039 + -0.433728 0.006049 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.995523 -1.374976 -0.900708 0.206069 1.040176 1.223922 + 1.279978 1.478402 1.243197 0.178017 0.235147 0.157758 + 0.172461 0.312229 0.509417 0.808807 1.215309 1.370256 + 0.795799 -0.342228 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + -0.049208 0.944598 1.588994 1.513464 1.166571 1.047943 + 1.075387 0.881568 0.389300 -0.185701 -0.035406 1.009202 + 1.709299 1.983187 1.760534 0.946370 0.064703 -0.146747 + 0.213693 0.432429 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + 1.324994 0.901444 0.074174 -0.849109 -1.649805 -1.964304 + -1.696768 -1.163499 -0.598027 -0.028493 1.430932 1.254107 + 0.654710 -0.078125 -0.653691 -0.862671 -0.729918 -0.454728 + -0.200309 -0.092174 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + -0.057085 -0.287224 -0.724738 -0.876790 -0.636449 -0.371928 + -0.186803 0.130124 0.381840 0.089729 0.439765 -0.143754 + -1.070861 -1.915480 -2.726342 -3.124574 -2.504564 -1.177302 + -0.224223 -0.178808 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.526481 0.509107 0.391517 -0.025932 -0.279426 -0.127581 + 0.017761 -0.193278 -0.633775 -1.029683 0.648341 0.376487 + 0.306689 0.234835 0.003016 -0.494571 -1.028435 -1.095739 + -0.725329 -0.679467 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A2_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A2_local.grdecl new file mode 100644 index 000000000..826f39f47 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A2_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 -0.025439 -0.499686 + -1.025187 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 -0.227774 -0.402043 -0.176976 0.012591 -0.188477 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 -1.104130 + -2.056793 -2.207476 -1.245579 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 -2.149746 -2.849843 -3.153856 + -2.503523 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 -0.908881 -0.656306 -0.381115 -0.188604 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.538834 0.159408 + 0.151831 0.260319 0.256477 0.275927 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 999999999999999945575230987042816.000000 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 999999999999999945575230987042816.000000 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 999999999999999945575230987042816.000000 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 999999999999999945575230987042816.000000 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 999999999999999945575230987042816.000000 + 999999999999999945575230987042816.000000 999999999999999945575230987042816.000000 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A_local.grdecl new file mode 100644 index 000000000..4bd40f618 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_A_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.677030 -1.916461 -1.234550 0.036298 + 1.080500 1.341265 0.997033 0.657986 0.617346 0.557741 + -0.785418 -1.138156 -1.132628 -0.879481 -0.405060 0.006809 + -0.035418 -0.373511 -0.433511 0.006049 0.769581 0.062903 + -0.452333 -0.645152 -0.663255 -0.772958 -0.955062 -0.851693 + -0.314759 0.518246 1.967144 1.617958 0.749545 -0.002046 + -0.417782 -0.717122 -1.107298 -1.288744 -0.874998 -0.019301 + 2.806293 2.787779 1.551428 -0.208671 -1.304757 -1.426859 + -1.513472 -2.089342 -2.670547 -2.856769 0.728909 0.219844 + -1.055842 -2.294567 -2.544213 -1.989089 -1.728381 -2.258027 + -3.021247 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_B_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_B_local.grdecl new file mode 100644 index 000000000..0005ac71e --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_B_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.629633 0.334735 0.244305 0.178606 -0.025440 -0.499686 + -1.025187 -1.093356 -0.725006 -0.679467 0.424872 0.316520 + 0.147939 -0.227774 -0.402043 -0.176976 0.012591 -0.188477 + -0.631527 -1.029457 0.721032 0.377646 -0.197684 -1.104130 + -2.056793 -2.207476 -1.245579 -0.115779 0.089260 -0.479708 + 0.304551 -0.341557 -1.325423 -2.149746 -2.849843 -3.153856 + -2.503523 -1.175000 -0.223699 -0.178820 -0.080649 -0.322371 + -0.764448 -0.908881 -0.656306 -0.381115 -0.188604 0.130685 + 0.382037 0.089729 1.203098 0.997691 0.538834 0.159407 + 0.151831 0.260320 0.256477 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + 0.389300 -0.185701 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + 0.235147 0.157758 0.172461 0.312229 0.509417 0.808807 + 1.215309 1.370256 0.795799 -0.342228 -0.995523 -1.374976 + -0.900708 0.206069 1.040176 1.223922 1.279978 1.478402 + 1.243197 0.178017 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.841584 -1.226023 -1.207091 -0.902073 -0.387598 0.025259 + -0.029104 -0.373039 -0.433728 0.006049 0.545837 -0.318973 + -0.824143 -0.816984 -0.678996 -0.777436 -0.967488 -0.856602 + -0.316280 0.517896 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 2.535338 2.215707 0.622777 -1.049959 -1.704248 -1.537606 + -1.549673 -2.107112 -2.676758 -2.857547 0.662012 0.092502 + -1.249170 -2.481425 -2.643038 -2.015550 -1.732791 -2.259825 + -3.021738 -3.374325 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_C_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_C_local.grdecl new file mode 100644 index 000000000..f77f41d45 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_C_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.662012 0.092502 -1.249170 -2.481425 -2.643038 -2.015550 + -1.732791 -2.259825 -3.021738 -3.374325 2.535338 2.215707 + 0.622777 -1.049959 -1.704248 -1.537606 -1.549673 -2.107112 + -2.676758 -2.857547 1.752741 1.156656 0.156627 -0.349148 + -0.425633 -0.648444 -1.098076 -1.299050 -0.878778 -0.019675 + 0.545837 -0.318973 -0.824143 -0.816984 -0.678996 -0.777436 + -0.967488 -0.856602 -0.316280 0.517896 -0.841584 -1.226023 + -1.207091 -0.902073 -0.387598 0.025259 -0.029104 -0.373039 + -0.433728 0.006049 -1.679243 -1.919407 -1.234238 0.040584 + 1.085511 1.344037 0.997618 0.657986 0.617346 0.557741 + -0.995523 -1.374976 -0.900708 0.206069 1.040176 1.223922 + 1.279978 1.478402 1.243197 0.178017 0.235147 0.157758 + 0.172461 0.312229 0.509417 0.808807 1.215309 1.370256 + 0.795799 -0.342228 0.296088 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.562969 1.421198 0.483566 -0.607791 + -0.049208 0.944598 1.588994 1.513464 1.166571 1.047943 + 1.075387 0.881568 0.389300 -0.185701 -0.035406 1.009202 + 1.709299 1.983187 1.760534 0.946370 0.064703 -0.146747 + 0.213693 0.432429 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + 1.324994 0.901444 0.074174 -0.849109 -1.649805 -1.964304 + -1.696768 -1.163499 -0.598027 -0.028493 1.430932 1.254107 + 0.654710 -0.078125 -0.653691 -0.862671 -0.729918 -0.454728 + -0.200309 -0.092174 1.203098 0.997692 0.538834 0.159408 + 0.151831 0.260319 0.256477 0.275927 0.215435 -0.279581 + -0.080649 -0.322371 -0.764447 -0.908881 -0.656306 -0.381115 + -0.188604 0.130684 0.382037 0.089729 0.304551 -0.341557 + -1.325423 -2.149746 -2.849843 -3.153856 -2.503523 -1.175001 + -0.223698 -0.178820 0.721032 0.377647 -0.197684 -1.104130 + -2.056793 -2.207476 -1.245579 -0.115779 0.089260 -0.479708 + 0.424872 0.316521 0.147938 -0.227774 -0.402043 -0.176976 + 0.012591 -0.188477 -0.631527 -1.029457 0.629634 0.334735 + 0.244304 0.178606 -0.025439 -0.499686 -1.025187 -1.093356 + -0.725006 -0.679467 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_D.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_D.grdecl new file mode 100644 index 000000000..b03341305 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_D.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.058295 0.248749 0.388570 0.249038 0.000283 -0.176982 + -0.328420 -0.484198 -0.589901 -0.695144 -0.315096 -0.277978 + -0.276790 -0.312213 -0.269854 -0.147767 -0.122723 -0.248172 + -0.371110 -0.465613 -1.020727 -1.177666 -1.161339 -1.148812 + -1.337923 -1.390415 -0.852292 -0.042150 0.261905 -0.077604 + -1.009536 -0.847495 -0.697763 -0.750847 -0.950620 -0.969765 + -0.615036 -0.067567 0.305606 0.250316 -0.420416 -0.792555 + -1.180631 -0.999140 -0.325773 0.295402 0.577985 0.641194 + 0.622060 0.494645 0.381958 -0.273400 -0.644773 -0.434449 + 0.077097 0.389331 0.406498 0.389883 0.425638 0.373432 + 0.557541 0.432428 0.527930 0.494641 0.224039 -0.120332 + -0.398642 -0.423386 -0.010316 0.589501 0.588478 0.124527 + -0.270139 -0.533729 -0.830287 -1.131914 -1.236447 -1.091899 + -0.751424 -0.229210 -0.052205 -0.067141 0.066797 0.101213 + -0.231870 -0.866168 -1.454288 -1.735008 -1.712798 -1.465199 + -0.786013 -0.120096 0.854054 1.528835 1.507371 0.874103 + 0.091204 -0.371360 -0.431444 -0.426733 -0.142205 0.318141 + 0.967773 1.505608 1.583705 1.187642 0.723000 0.451266 + 0.193373 -0.228383 0.476335 0.524315 0.668647 0.547055 + 0.134166 -0.294362 -0.565245 -0.648533 -0.553100 -0.392055 + -0.297262 -0.426719 -0.352796 -0.284941 -0.492572 -1.019570 + -1.572755 -1.718771 -1.257758 -0.442012 -1.062786 -1.278902 + -0.813618 0.065464 0.569216 0.263687 -0.355284 -0.607314 + -0.467468 -0.241040 -1.265793 -0.853971 0.033670 0.687807 + 0.818975 0.593910 0.193730 -0.225818 -0.475444 -0.519302 + -0.775314 -0.416251 0.034658 0.207452 0.195375 0.163425 + 0.029731 -0.312759 -0.703724 -0.835337 -0.314654 -0.500735 + -0.469920 -0.304734 -0.207327 -0.322978 -0.506223 -0.528140 + -0.396959 -0.198479 0.043096 -0.169129 -0.345117 -0.418549 + -0.510572 -0.733959 -1.007160 -1.025567 -0.579104 0.056893 + 0.457937 0.108470 -0.548896 -0.979114 -1.024414 -1.005246 + -1.128199 -1.241025 -1.160557 -0.918426 -0.041656 -0.567358 + -1.017082 -1.132163 -0.793021 -0.343733 -0.297997 -0.729932 + -1.226567 -1.377502 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_E_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_E_local.grdecl new file mode 100644 index 000000000..164372e94 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_E_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391517 -0.025932 -0.279426 -0.127581 0.017761 -0.193278 + -0.633775 -1.029683 0.859417 0.607622 0.091949 -0.829884 + -1.867067 -2.117355 -1.216993 -0.109772 0.090068 -0.479618 + 0.439765 -0.143754 -1.070861 -1.915480 -2.726342 -3.124574 + -2.504564 -1.177302 -0.224223 -0.178808 -0.057085 -0.287224 + -0.724738 -0.876790 -0.636449 -0.371928 -0.186803 0.130124 + 0.381840 0.089729 1.202264 0.996304 0.536597 0.157487 + 0.151960 0.261694 0.257023 0.275927 0.215435 -0.279581 + 1.430932 1.254107 0.654710 -0.078125 -0.653691 -0.862671 + -0.729918 -0.454728 -0.200309 -0.092174 1.324994 0.901444 + 0.074174 -0.849109 -1.649805 -1.964304 -1.696768 -1.163499 + -0.598027 -0.028493 0.899565 0.992203 0.749731 0.404224 + -0.167782 -1.022487 -1.668451 -1.600215 -1.044804 -0.566005 + -0.035406 1.009202 1.709299 1.983187 1.760534 0.946370 + 0.064703 -0.146747 0.213693 0.432429 -0.049208 0.944598 + 1.588994 1.513464 1.166571 1.047943 1.075387 0.881568 + -0.238143 -0.109934 0.390472 0.753952 1.023120 0.847401 + 0.682307 1.046445 1.725379 1.567073 0.702032 -0.382223 + -0.262876 0.157758 0.172461 0.312229 0.509417 0.808807 + 2.048589 2.678183 2.160811 0.606263 -1.286302 -1.515503 + -0.900708 0.206069 1.040176 1.223922 1.428210 1.932714 + 1.873495 0.937052 -1.368768 -1.618878 -1.261231 0.040584 + 1.085511 0.566150 0.340310 0.322680 0.728392 1.134462 + -0.141165 -0.467429 -0.634675 -0.902073 -0.387598 -0.397320 + -0.366566 -0.448727 -0.189603 0.574898 1.203215 0.463139 + -0.148902 -0.465059 -0.632746 -0.753503 -0.812524 -0.672923 + -0.102951 0.910524 2.142118 1.741012 0.822085 0.090545 + -0.411376 -0.875820 -1.168968 -1.063000 -0.552467 0.190168 + 3.331424 3.387353 2.309292 0.673060 -0.530516 -0.945719 + -1.098227 -1.442308 -1.805538 -1.984318 1.496248 1.191897 + 0.236994 -0.868205 -1.410640 -1.409458 -1.497087 -1.971519 + -2.470902 -2.588709 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_F_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_F_local.grdecl new file mode 100644 index 000000000..e3850c811 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_F_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.648341 0.376487 0.306689 0.234835 0.003016 -0.494571 + -1.028435 -1.095739 -0.725329 -0.679467 0.526481 0.509107 + 0.391374 -0.023878 -0.273295 -0.122468 0.016831 -0.198939 + -0.636846 -1.026473 0.854990 0.587617 0.076319 -0.826784 + -1.845253 -2.088240 -1.196803 -0.100361 0.101494 -0.460296 + 0.416105 -0.149265 -1.036649 -1.856664 -2.652755 -3.043142 + -2.427564 -1.126902 -0.197833 -0.150158 -0.055808 -0.292010 + -0.727036 -0.863188 -0.599546 -0.323781 -0.146615 0.151039 + 0.377920 0.099002 1.159265 0.913927 0.442901 0.083079 + 0.146301 0.328343 0.314699 0.315541 0.254183 -0.217592 + 1.382339 1.182361 0.606164 -0.074510 -0.512851 -0.599575 + -0.556185 -0.402004 -0.171722 -0.034386 1.299749 0.856614 + 0.039093 -0.813428 -1.370089 -1.451543 -1.283660 -0.999643 + -0.564703 -0.015819 0.869501 0.934594 0.686416 0.334369 + -0.201242 -0.828715 -1.268825 -1.403175 -1.056628 -0.581179 + -0.082381 0.883116 1.544651 1.770907 1.501780 0.848208 + 0.235476 -0.092404 0.065977 0.333041 -0.086845 0.850050 + 1.454510 1.348493 1.025901 0.843455 0.743175 0.669055 + 0.304108 -0.241397 0.283275 0.710515 0.965203 0.711999 + 0.281040 -0.008500 -0.258105 -0.155182 0.076932 -0.525380 + 0.218085 0.120154 0.144979 0.266826 0.274259 -0.063610 + -0.706025 -0.859636 -0.201938 -0.423356 -0.984475 -1.346387 + -0.885522 0.207641 0.991150 0.874515 0.277199 0.084113 + 0.436803 0.028687 -1.642724 -1.771777 -1.099965 0.083042 + 1.075412 1.225557 0.752793 0.391639 0.446377 0.474999 + -0.832171 -1.124079 -1.055536 -0.790068 -0.338841 0.032714 + -0.033998 -0.381813 -0.458102 -0.083964 0.478834 -0.389831 + -0.818266 -0.749837 -0.595607 -0.706766 -0.914550 -0.820072 + -0.313926 0.432227 1.639994 0.966942 0.034676 -0.378038 + -0.398683 -0.584507 -1.007885 -1.202743 -0.801227 0.002337 + 2.448313 2.022981 0.450787 -1.105491 -1.668478 -1.479002 + -1.479979 -1.990964 -2.507444 -2.668368 0.655684 0.058050 + -1.259949 -2.426922 -2.541627 -1.906752 -1.623146 -2.131591 + -2.867963 -3.213965 / diff --git a/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_G_local.grdecl b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_G_local.grdecl new file mode 100644 index 000000000..0aea1419c --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/FieldParam_real5_iter1_G_local.grdecl @@ -0,0 +1,35 @@ +FIELDPAR + 0.655684 0.058050 -1.259949 -2.426922 -2.541627 -1.906752 + -1.623146 -2.131591 -2.867963 -3.213965 2.448313 2.022981 + 0.450787 -1.105491 -1.668478 -1.479002 -1.479979 -1.990964 + -2.507444 -2.668368 1.639994 0.966942 0.034676 -0.378038 + -0.398683 -0.584507 -1.007885 -1.202743 -0.801227 0.002337 + 0.478834 -0.389831 -0.818266 -0.749837 -0.595607 -0.706766 + -0.914550 -0.820072 -0.313926 0.432227 -0.832171 -1.124079 + -1.055536 -0.790068 -0.338841 0.032714 -0.033998 -0.381813 + -0.458102 -0.083964 -1.642724 -1.771777 -1.099965 0.083042 + 1.075412 1.225557 0.752793 0.391639 0.446377 0.474999 + -0.984475 -1.346387 -0.885522 0.207641 0.991150 0.874515 + 0.277199 0.084113 0.436803 0.028687 0.218085 0.120154 + 0.144979 0.266826 0.274259 -0.063610 -0.706025 -0.859636 + -0.201938 -0.423356 0.283275 0.710515 0.965203 0.711999 + 0.281040 -0.008500 -0.258105 -0.155182 0.076932 -0.525380 + -0.086845 0.850050 1.454510 1.348493 1.025901 0.843455 + 0.743175 0.669055 0.304108 -0.241397 -0.082381 0.883116 + 1.544651 1.770907 1.501780 0.848208 0.235476 -0.092404 + 0.065977 0.333041 0.869501 0.934594 0.686416 0.334369 + -0.201242 -0.828715 -1.268825 -1.403175 -1.056628 -0.581179 + 1.299749 0.856614 0.039093 -0.813428 -1.370089 -1.451543 + -1.283660 -0.999643 -0.564703 -0.015819 1.382339 1.182361 + 0.606164 -0.074510 -0.512851 -0.599575 -0.556185 -0.402004 + -0.171722 -0.034386 1.159265 0.913927 0.442901 0.083079 + 0.146301 0.328343 0.314699 0.315541 0.254183 -0.217592 + -0.055808 -0.292010 -0.727036 -0.863188 -0.599546 -0.323781 + -0.146615 0.151039 0.377920 0.099002 0.416105 -0.149265 + -1.036649 -1.856664 -2.652755 -3.043142 -2.427564 -1.126902 + -0.197833 -0.150158 0.854990 0.587617 0.076319 -0.826784 + -1.845253 -2.088240 -1.196803 -0.100361 0.101494 -0.460296 + 0.526481 0.509107 0.391374 -0.023878 -0.273295 -0.122468 + 0.016831 -0.198939 -0.636846 -1.026473 0.648341 0.376487 + 0.306689 0.234835 0.003016 -0.494571 -1.028435 -1.095739 + -0.725329 -0.679467 / diff --git a/tests/workflows/localisation/example_case/init_files/README b/tests/workflows/localisation/example_case/init_files/README new file mode 100644 index 000000000..6a8c65626 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/README @@ -0,0 +1,18 @@ +### Directory with reference data and input files + +- **Input files:** + - `sim_field_template.ert` + - `polygons.txt` + - `region_polygons.txt` + - `scaling_factor.grdecl` + - `scaling_factor_rms_orgo.grdecl` + +- **Reference files:** + - `FieldParam_real5_iter0_X_local.grdecl` + - `FieldParam_real5_iter3_X_local.grdecl` + - `X is case name (A, B, C, ...)` + +- **Temporary files:** + - Initial ensemble files are stored here when running scripts/make_reference_data.py: + - `FieldParam.roff`: The field parameter + - `Upscaled.roff`: The upscaled field parameter (for QC purpose) diff --git a/tests/workflows/localisation/example_case/init_files/polygons.txt b/tests/workflows/localisation/example_case/init_files/polygons.txt new file mode 100644 index 000000000..4a45ad4e8 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/polygons.txt @@ -0,0 +1,17 @@ +499.666718 2093.778320 25.000000 +341.397217 1917.105408 0.000000 +216.253906 1324.514893 0.000000 +-18.913147 1133.715820 0.000000 +106.429382 890.193115 0.000000 +130.630096 479.416870 0.000000 +-64.992249 440.292480 0.000000 +204.256226 -47.930542 0.000000 +561.117737 -119.302979 0.000000 +714.058411 38.735840 0.000000 +1087.448486 541.147339 0.000000 +879.294128 1025.106445 0.000000 +738.789978 1514.269440 0.000000 +754.401611 1878.539673 0.000000 +582.674133 2123.121155 0.000000 +499.666718 2093.778320 25.000000 +999.000000 999.000000 999.000000 diff --git a/tests/workflows/localisation/example_case/init_files/region_polygons.txt b/tests/workflows/localisation/example_case/init_files/region_polygons.txt new file mode 100644 index 000000000..0c5a68db4 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/region_polygons.txt @@ -0,0 +1,153 @@ +424.509949 2079.387421 20.833294 +349.525574 2077.578644 23.765421 +260.721008 2077.669594 24.845678 +169.519867 2077.044716 25.000004 +86.164909 2070.750626 25.000002 +16.176638 2044.482727 25.000000 +-36.105103 1981.598633 25.000004 +-67.602112 1871.688156 25.000002 +-80.282654 1729.270020 25.000000 +-77.376656 1575.095093 25.000004 +-61.402237 1427.718933 24.845680 +-32.030331 1296.914978 23.765432 +11.779886 1190.261230 20.833336 +70.523544 1115.098511 15.586418 +142.512741 1077.817566 9.413568 +225.513870 1084.571716 4.166626 +316.264160 1136.641357 1.234479 +407.384247 1215.814209 0.154193 +490.465576 1299.004700 -0.000122 +559.404480 1367.602234 -0.000051 +617.315918 1420.894714 0.000038 +669.619995 1462.644531 0.000081 +720.154053 1495.998566 0.000036 +766.425232 1521.639862 -0.000063 +804.358276 1539.635681 -0.000163 +832.164429 1550.605621 -0.000220 +857.200378 1557.378571 -0.000241 +889.109863 1563.335663 -0.000244 +934.286072 1574.346130 -0.000244 +986.121887 1606.231659 -0.000244 +1034.759888 1677.301727 -0.000244 +1068.650513 1796.007446 -0.000244 +1069.475220 1931.365677 -0.000244 +1017.223267 2042.534809 -0.000244 +902.403015 2099.124138 0.154078 +757.601257 2112.546516 1.234336 +625.923889 2104.665764 4.166463 +538.766174 2093.921379 9.413428 +480.680878 2085.055855 15.586329 +424.509949 2079.387421 20.833294 +999.000000 999.000000 999.000000 +1175.375488 1016.951172 -0.000163 +1127.616089 1031.741028 -0.000216 +1066.552368 1035.509888 -0.000205 +995.064148 1029.995544 -0.000122 +916.582642 1016.936829 0.000030 +836.747009 998.074219 0.000200 +761.747864 975.148926 0.000326 +696.421936 947.580444 0.000360 +640.188721 905.502197 0.000332 +591.113647 836.726074 0.000285 +547.842468 735.448120 0.000256 +511.342438 621.401733 0.000246 +483.161316 520.704346 0.000244 +463.492584 453.733765 0.000243 +447.112701 417.910889 0.000232 +427.443970 404.916626 0.000203 +400.120544 407.141479 0.000152 +369.624359 419.813477 0.000092 +342.649261 438.869873 0.000041 +324.282745 461.092529 0.000014 +313.187164 486.642090 0.000014 +306.418579 516.523315 0.000041 +301.349274 551.017334 0.000092 +296.616669 587.508423 0.000152 +291.174377 622.656738 0.000203 +283.304962 654.361938 0.000232 +268.606812 685.481689 0.000243 +242.006943 720.113525 0.000244 +200.838959 760.598633 0.000244 +152.061737 802.254272 0.000244 +105.040504 838.642090 0.000244 +66.897408 864.863159 0.000244 +35.782269 882.177368 0.000244 +7.601859 893.384766 0.000244 +-20.563051 899.712036 0.000244 +-46.935501 896.092651 0.000244 +-68.564507 875.886963 0.000244 +-84.266357 831.946533 0.000244 +-99.926460 755.086914 0.000244 +-123.197540 635.614624 0.000244 +-156.755280 471.414795 0.000244 +-183.367401 290.685303 0.000244 +-180.824615 129.202026 0.000244 +-130.081009 14.246216 0.000244 +-24.744156 -60.882324 0.000244 +138.414948 -111.378418 0.000244 +355.891235 -149.908936 0.000244 +597.242981 -179.027344 0.000244 +825.294128 -198.758301 0.000244 +1009.999023 -207.018066 0.000244 +1149.831543 -193.288574 0.000244 +1250.396118 -144.943359 0.000244 +1316.705811 -52.310303 0.000244 +1351.408203 82.465698 0.000244 +1356.560181 254.284424 0.000244 +1336.038330 453.482178 0.000241 +1300.999146 652.138062 0.000220 +1264.419189 817.766602 0.000163 +1235.577637 926.227905 0.000060 +1208.965210 986.761230 -0.000060 +1175.375488 1016.951172 -0.000163 +999.000000 999.000000 999.000000 +1100.404907 1563.663239 -0.000244 +1093.085693 1580.043121 -0.000241 +1080.155762 1597.196869 -0.000220 +1049.040649 1608.933655 -0.000163 +990.550293 1609.417297 -0.000062 +909.037842 1594.230499 0.000048 +812.241943 1559.310425 0.000122 +707.159241 1502.077637 0.000128 +597.820374 1425.885376 0.000089 +487.514221 1335.570435 0.000041 +380.109985 1238.548706 0.000012 +281.798523 1152.554382 0.000002 +199.351074 1097.901123 0.000000 +137.217148 1087.896362 0.000000 +90.559929 1107.823669 0.000000 +52.220978 1135.960205 0.000000 +17.030819 1153.067566 0.000000 +-12.224041 1149.843445 0.000000 +-30.768122 1119.469666 0.000000 +-33.904774 1058.583801 0.000000 +-17.252659 977.645142 0.000000 +23.490715 890.568726 0.000000 +88.479721 808.518433 0.000000 +161.276154 731.652832 0.000000 +221.293686 657.379761 0.000000 +254.415771 584.146362 0.000000 +272.405029 514.559692 0.000000 +293.493774 452.265869 0.000000 +331.234711 402.557861 -0.000002 +380.462097 377.315674 -0.000012 +431.330383 390.064941 -0.000041 +475.952148 448.652710 -0.000090 +514.272339 538.209106 -0.000140 +548.194092 638.184570 -0.000163 +580.220703 730.961548 -0.000142 +615.257507 810.648438 -0.000102 +658.809998 874.285400 -0.000081 +715.118774 920.285522 -0.000104 +783.363953 952.553223 -0.000154 +861.460938 976.365906 -0.000203 +945.597290 999.150879 -0.000232 +1025.049927 1036.934814 -0.000243 +1087.368286 1107.894287 -0.000244 +1123.369019 1221.228210 -0.000244 +1136.937866 1350.224487 -0.000244 +1135.228271 1459.193237 -0.000244 +1125.039185 1521.875244 -0.000244 +1111.754639 1549.733948 -0.000244 +1100.404907 1563.663239 -0.000244 +999.000000 999.000000 999.000000 diff --git a/tests/workflows/localisation/example_case/init_files/scaling_factor.grdecl b/tests/workflows/localisation/example_case/init_files/scaling_factor.grdecl new file mode 100644 index 000000000..4d6f606f5 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/scaling_factor.grdecl @@ -0,0 +1,63 @@ + +SCALING + 0 0 0 0 0 + 0 0 0 0 0 + + 0 0 0.0024178524 0.00884367712 0.0132498778 + 0.0161081199 0.0182318985 0.0201500896 0.0203383286 0.0155032165 + + 0.003006696 0.0156889092 0.0205063 0.0220940653 0.0239405781 + 0.0273311734 0.0326220095 0.0396278054 0.0452148803 0.0438990891 + + 0.0279479939 0.0363404155 0.03613998 0.0340526439 0.0340892971 + 0.0368285999 0.0430386923 0.0538446382 0.0647787303 0.0673846528 + + 0.0432741642 0.0517198518 0.0529378206 0.0574502349 0.0607241429 + 0.0538347289 0.0475190282 0.0564772375 0.0722196251 0.0810511559 + + 0.0468719564 0.0599104799 0.0680627897 0.0913911909 0.117351525 + 0.108548783 0.0624484308 0.0494863279 0.0646237284 0.0794273764 + + 0.0423487797 0.0586890392 0.0715542361 0.120984368 0.216681033 + 0.261977315 0.183652744 0.0777159408 0.0435763821 0.0589708723 + + 0.0365328901 0.0551960096 0.0803627595 0.175753772 0.354921192 + 0.496848464 0.433681875 0.222422212 0.0679221153 0.036710728 + + 0.0362647735 0.0638489351 0.109380685 0.24080199 0.456255645 + 0.638256907 0.630086362 0.419066995 0.165060177 0.0379007943 + + 0.0416177697 0.0837309957 0.136203006 0.264866084 0.480560392 + 0.683874905 0.733731925 0.542562187 0.313413531 0.103217475 + + 0.0437682532 0.0769556612 0.112662002 0.229829431 0.461149663 + 0.723126411 0.871051311 0.711820066 0.450462759 0.227276623 + + 0.0451645106 0.063203834 0.066589959 0.159034893 0.425005674 + 0.744041264 0.956496 0.911683619 0.516521394 0.283591837 + + 0.0492031202 0.0741543695 0.0527167879 0.0891754478 0.352179855 + 0.695928216 0.895608008 0.852726817 0.517417789 0.260448962 + + 0.0523970835 0.0939117745 0.0628247038 0.0399134271 0.198853135 + 0.46667394 0.65412581 0.635288835 0.387747556 0.149869889 + + 0.0571080595 0.113578357 0.0907923728 0.0506353714 0.069845207 + 0.152088627 0.252010256 0.238708615 0.124544971 0.055357337 + + 0.0635695606 0.127395019 0.125238523 0.0950208232 0.0677052438 + 0.0437932834 0.0376545079 0.0385723859 0.0507421643 0.0839931592 + + 0.0676470697 0.128882632 0.141776979 0.128613114 0.107911579 + 0.0893575996 0.0812080279 0.0852842182 0.10028512 0.122700267 + + 0.0620717965 0.114647269 0.134200275 0.135575622 0.131714463 + 0.128724501 0.129031375 0.13239418 0.137205586 0.140333056 + + 0.0413737856 0.0846893489 0.106586784 0.114918746 0.118551478 + 0.120768428 0.12276534 0.125401542 0.126825631 0.122835122 + + 0.00877429079 0.0441762544 0.0665985122 0.0785425529 0.0850359648 + 0.0885261223 0.0905158073 0.0923460945 0.0924721509 0.0868233591 + + / diff --git a/tests/workflows/localisation/example_case/init_files/scaling_factor_rms_origo.grdecl b/tests/workflows/localisation/example_case/init_files/scaling_factor_rms_origo.grdecl new file mode 100644 index 000000000..b0f6f9926 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/scaling_factor_rms_origo.grdecl @@ -0,0 +1,63 @@ + +SCALING + 0.00877429079 0.0441762544 0.0665985122 0.0785425529 0.0850359648 + 0.0885261223 0.0905158073 0.0923460945 0.0924721509 0.0868233591 + + 0.0413737856 0.0846893489 0.106586784 0.114918746 0.118551478 + 0.120768428 0.12276534 0.125401542 0.126825631 0.122835122 + + 0.0620717965 0.114647269 0.134200275 0.135575622 0.131714463 + 0.128724501 0.129031375 0.13239418 0.137205586 0.140333056 + + 0.0676470697 0.128882632 0.141776979 0.128613114 0.107911579 + 0.0893575996 0.0812080279 0.0852842182 0.10028512 0.122700267 + + 0.0635695606 0.127395019 0.125238523 0.0950208232 0.0677052438 + 0.0437932834 0.0376545079 0.0385723859 0.0507421643 0.0839931592 + + 0.0571080595 0.113578357 0.0907923728 0.0506353714 0.069845207 + 0.152088627 0.252010256 0.238708615 0.124544971 0.055357337 + + 0.0523970835 0.0939117745 0.0628247038 0.0399134271 0.198853135 + 0.46667394 0.65412581 0.635288835 0.387747556 0.149869889 + + 0.0492031202 0.0741543695 0.0527167879 0.0891754478 0.352179855 + 0.695928216 0.895608008 0.852726817 0.517417789 0.260448962 + + 0.0451645106 0.063203834 0.066589959 0.159034893 0.425005674 + 0.744041264 0.956496 0.911683619 0.516521394 0.283591837 + + 0.0437682532 0.0769556612 0.112662002 0.229829431 0.461149663 + 0.723126411 0.871051311 0.711820066 0.450462759 0.227276623 + + 0.0416177697 0.0837309957 0.136203006 0.264866084 0.480560392 + 0.683874905 0.733731925 0.542562187 0.313413531 0.103217475 + + 0.0362647735 0.0638489351 0.109380685 0.24080199 0.456255645 + 0.638256907 0.630086362 0.419066995 0.165060177 0.0379007943 + + 0.0365328901 0.0551960096 0.0803627595 0.175753772 0.354921192 + 0.496848464 0.433681875 0.222422212 0.0679221153 0.036710728 + + 0.0423487797 0.0586890392 0.0715542361 0.120984368 0.216681033 + 0.261977315 0.183652744 0.0777159408 0.0435763821 0.0589708723 + + 0.0468719564 0.0599104799 0.0680627897 0.0913911909 0.117351525 + 0.108548783 0.0624484308 0.0494863279 0.0646237284 0.0794273764 + + 0.0432741642 0.0517198518 0.0529378206 0.0574502349 0.0607241429 + 0.0538347289 0.0475190282 0.0564772375 0.0722196251 0.0810511559 + + 0.0279479939 0.0363404155 0.03613998 0.0340526439 0.0340892971 + 0.0368285999 0.0430386923 0.0538446382 0.0647787303 0.0673846528 + + 0.003006696 0.0156889092 0.0205063 0.0220940653 0.0239405781 + 0.0273311734 0.0326220095 0.0396278054 0.0452148803 0.0438990891 + + 0 0 0.0024178524 0.00884367712 0.0132498778 + 0.0161081199 0.0182318985 0.0201500896 0.0203383286 0.0155032165 + + 0 0 0 0 0 + 0 0 0 0 0 + + / diff --git a/tests/workflows/localisation/example_case/init_files/sim_field_template.ert b/tests/workflows/localisation/example_case/init_files/sim_field_template.ert new file mode 100644 index 000000000..806bbf7c7 --- /dev/null +++ b/tests/workflows/localisation/example_case/init_files/sim_field_template.ert @@ -0,0 +1,56 @@ +DEFINE $$USER +DEFINE ${CASE_NAME} +DEFINE ${ENSEMBLE_SEED_FILE} +DEFINE /example_config.yml + +INSTALL_JOB SIM_FIELD scripts/FM_SIM_FIELD +----------------------------------------------------- +-- Observations +----------------------------------------------------- + +DEFINE /observations/observations.obs +OBS_CONFIG + +JOBNAME sim_fields_ + + +NUM_REALIZATIONS ${NREAL} -- Set number of realizations to run +MAX_RUNTIME 18000 -- Set the maximum allowed run time (in seconds) +MIN_REALIZATIONS 1 -- Success criteria +MAX_SUBMIT 1 -- How many times should the queue system retry a simulation. + +QUEUE_SYSTEM LOCAL +QUEUE_OPTION LOCAL MAX_RUNNING 10 +RANDOM_SEED ${ERT_START_SEED} -- ERT seed value + +RUNPATH simulations//realization-/iter- +ENSPATH output//storage -- Storage of internal ert data +UPDATE_LOG_PATH output//update_log -- Info of active and inactive data points +RUNPATH_FILE output//runpath_file -- List of runpaths + +-- Activate localisation setup +${LOAD_LOCALISATION_WORKFLOW} +${HOOK_LOCALISATION_WORKFLOW} + +--Result data from forward model-- +GEN_DATA RESULT_UPSCALED_FIELD RESULT_FILE:${RESPONSE_FILE_PREFIX}_%d.txt REPORT_STEPS:0 INPUT_FORMAT:ASCII OUTPUT_FORMAT:ASCII + +----------------------------------------------------- +-- Forward models +----------------------------------------------------- +--Simulate Gaussian field with trend and calculate upscaled values. Observables are upscaled values of selected grid cells. +FORWARD_MODEL MAKE_DIRECTORY(=init_files) +-- Is used to identify iteration number (only relevant for old komodo versions) +FORWARD_MODEL MAKE_DIRECTORY(=) +-- The common seed file +FORWARD_MODEL COPY_FILE(=/, =/) + +FORWARD_MODEL MAKE_SYMLINK(=/${GRID_FILE_NAME}, =/${GRID_FILE_NAME}) +FORWARD_MODEL MAKE_SYMLINK(=/${GRID_FILE_NAME_UPSCALED}, =/${GRID_FILE_NAME_UPSCALED}) + +-- The main forward model simulating gaussian field with trend, and upscale +FORWARD_MODEL SIM_FIELD(=, =, =, =) + +GRID /${GRID_FILE_NAME} -- Necessary for AHM using field parameters + +FIELD FIELDPAR PARAMETER ${UPDATED_FIELDPARAM_FILE_NAME} INIT_FILES:${INITIAL_FIELDPARAM_FILE_NAME} MIN:-5.0 MAX:5.0 FORWARD_INIT:True diff --git a/tests/workflows/localisation/example_case/localisation.wf b/tests/workflows/localisation/example_case/localisation.wf new file mode 100644 index 000000000..c6477f3d7 --- /dev/null +++ b/tests/workflows/localisation/example_case/localisation.wf @@ -0,0 +1 @@ +LOCALISATION_JOB local_config.yml diff --git a/tests/workflows/localisation/example_case/scripts/FM_SIM_FIELD b/tests/workflows/localisation/example_case/scripts/FM_SIM_FIELD new file mode 100644 index 000000000..53ae455ca --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/FM_SIM_FIELD @@ -0,0 +1,6 @@ +EXECUTABLE ./sim_fields.py + +ARGLIST + +STDERR sim_fields.stderr +STDOUT sim_fields.stdout diff --git a/tests/workflows/localisation/example_case/scripts/README b/tests/workflows/localisation/example_case/scripts/README new file mode 100644 index 000000000..b8670faa1 --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/README @@ -0,0 +1,11 @@ +### Source code scripts + +- `common_functions.py`: Functions used by the two scripts make_reference_data.py and sim_fields.py +- `make_reference_data.py`: + - Create grid files, random seed file localisation config file and observation files for the test cases + - Create reference data (assuming the ERT and localistion code is correct and updated) +- `sim_fields.py`: + - Used as forward model in ERT + - Simulate the GRF field, upscale it, extract responses (predictions) of observations. + +- `FM_SIM_FIELD`: ERT configuration of forward model SIM_FIELD using sim_fields.py. diff --git a/tests/workflows/localisation/example_case/scripts/__init__.py b/tests/workflows/localisation/example_case/scripts/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/workflows/localisation/example_case/scripts/common_functions.py b/tests/workflows/localisation/example_case/scripts/common_functions.py new file mode 100644 index 000000000..f11b3e1dc --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/common_functions.py @@ -0,0 +1,1880 @@ +""" +Common functions used by the scripts: init_test_case.py and sim_field.py +""" +import copy +import dataclasses +import math +import os +import random +import shutil +from dataclasses import asdict, dataclass +from pathlib import Path +from string import Template +from typing import Any, Dict, Tuple + +import gstools as gs +import numpy as np +import xtgeo +import yaml + +# pylint: disable=too-many-lines +# pylint: disable=missing-function-docstring, too-many-locals, invalid-name +# pylint: disable=raise-missing-from +# pylint: disable=too-many-nested-blocks + + +# Settings for the test case in the following dataclasses +@dataclass +class ModelSize: + """ + Length, width, thickness of a box containing the field + Same size is used for both fine scale grid with + the simulated field and the coarse scale grid + containing upscaled values of the simulated field. + """ + + size: Tuple[float] = (1000.0, 2000.0, 50.0) + polygon_file: str = None + use_eclipse_grid_index_origo: bool = True + + def reset_to_default(self): + self.size = (1000.0, 2000.0, 50.0) + self.polygon_file = None + self.use_eclipse_grid_index_origo = True + + +@dataclass +class Field: + """ + Define the dimension (number of grid cells) for fine scale grid, + name of output files and specification of model parameters for + simulation of gaussian field with option to use linear trend. + Relative standard deviation specify standard deviation of + gaussian residual field relative to the trends span of value + (max trend value - min trend value) + """ + + # pylint: disable=too-many-instance-attributes + name: str = "FIELDPAR" + algorithm: str = "gstools" + file_format: str = "ROFF" + initial_file_name_prefix: str = "init_files/FieldParam" + updated_file_name_prefix: str = "FieldParam" + seed_file: str = "randomseeds.txt" + variogram: str = "gaussian" + correlation_range: Tuple[float] = (250.0, 500.0, 2.0) + correlation_azimuth: float = 0.0 + correlation_dip: float = 0.0 + correlation_exponent: float = 1.9 + trend_use: bool = False + trend_params: Tuple[float] = (1.0, -1.0) + trend_relstd: float = 0.15 + grid_dimension: Tuple[int] = (10, 20, 1) + grid_file_name: str = "GRID_STANDARD.EGRID" + + def reset_to_default(self): + self.name = "FIELDPAR" + self.algorithm = "gstools" + self.file_format = "ROFF" + self.initial_file_name_prefix = "init_files/FieldParam" + self.updated_file_name_prefix = "FieldParam" + self.seed_file = "randomseeds.txt" + self.variogram = "gaussian" + self.correlation_range = (250.0, 500.0, 2.0) + self.correlation_azimuth = 0.0 + self.correlation_dip = 0.0 + self.correlation_exponent = 1.9 + self.trend_use = False + self.trend_params = (1.0, -1.0) + self.trend_relstd = 0.15 + self.grid_dimension = (10, 20, 1) + self.grid_file_name = "GRID_STANDARD.EGRID" + + +@dataclass +class Response: + """ + Specify the coarse grid dimensions, name of file and type + of average operation to calculated upscaled values that + are predictions of observations of the same grid cells. + Which cell indices are observed are specified in + observation settings. + """ + + # pylint: disable=too-many-instance-attributes + name: str = "UPSCALED" + grid_dimension: Tuple[int] = (2, 4, 1) + upscaled_file_name: str = "Upscaled" + grid_file_name: str = "GRID_STANDARD_UPSCALED.EGRID" + file_format: str = "ROFF" + write_upscaled_field: bool = True + response_function: str = "average" + gen_data_file_prefix: str = "UpscaledField" + ert_config_template_file: str = "init_files/sim_field_template.ert" + ert_config_file: str = "sim_field.ert" + + def reset_to_default(self): + self.name = "UPSCALED" + self.grid_dimension = (2, 4, 1) + self.upscaled_file_name = "Upscaled" + self.grid_file_name = "GRID_STANDARD_UPSCALED.EGRID" + self.file_format = "ROFF" + self.write_upscaled_field = True + self.response_function = "average" + self.gen_data_file_prefix = "UpscaledField" + self.ert_config_template_file = "init_files/sim_field_template.ert" + self.ert_config_file = "sim_field.ert" + + +# pylint: disable=too-many-instance-attributes +@dataclass +class Observation: + """ + Specify name of files for generated observations + and also position of observations. Grid cell indices for grid cells + with observations are calculated from position of observations. + """ + + directory: str = "observations" + file_name: str = "observations.obs" + data_dir: str = "obs_data" + reference_param_file: str = "init_files/ObsField" + reference_field_name: str = "ObsField" + rel_error: float = 0.10 + min_abs_error: float = 0.01 + selected_grid_cells: Tuple[Tuple[int]] = None + obs_positions: Tuple[Tuple[float]] = None + obs_values: Tuple[float] = None + + def reset_to_default(self): + self.directory = "observations" + self.file_name = "observations.obs" + self.data_dir = "obs_data" + self.reference_param_file = "init_files/ObsField" + self.reference_field_name = "ObsField" + self.rel_error = 0.10 + self.min_abs_error = 0.01 + self.selected_grid_cells = None + self.obs_positions = None + self.obs_values = None + + +@dataclass +class Localisation: + """ + Specify settings for the localisation config file. + """ + + method: str = "gaussian" + region_polygons: str = None + region_file: str = None + scaling_file: str = None + use_localisation: bool = True + + def reset_to_default(self): + self.method = "gaussian" + self.region_polygons = None + self.region_file = None + self.scaling_file = None + self.use_localisation = True + + +@dataclass +class Optional: + """ + Specify if some optional files should be + written or not (for QC purpose). + """ + + write_obs_pred_diff_field_file: bool = False + + def reset_to_default(self): + self.write_obs_pred_diff_field_file = False + + +@dataclass +class Settings: + """ + Settings for the test case + """ + + case_name: str = None + model_size: ModelSize = None + field: Field = None + response: Response = None + observation: Observation = None + localisation: Localisation = None + optional: Optional = None + + def update(self, updates): + for key, value in updates.items(): + if hasattr(self, key): + attr = getattr(self, key) + if dataclasses.is_dataclass(attr): + for attr_key, attr_value in value.items(): + if hasattr(attr, attr_key): + setattr(attr, attr_key, attr_value) + else: + setattr(self, key, value) + self.set_observed_cell_indices() + + def to_dict(self): + main_dict = {"settings": {}} + for key, value in asdict(self).items(): + if dataclasses.is_dataclass(key): + sub_dict = {} + for key2, value2 in asdict(key): + sub_dict[key2] = value2 + main_dict["settings"][key] = sub_dict + else: + main_dict["settings"][key] = value + return main_dict + + def reset_to_default(self): + self.model_size = ModelSize() + self.model_size.reset_to_default() + self.field = Field() + self.field.reset_to_default() + self.response = Response() + self.response.reset_to_default() + self.localisation = Localisation() + self.localisation.reset_to_default() + self.observation = Observation() + self.observation.reset_to_default() + self.optional = Optional() + self.optional.reset_to_default() + self.case_name = "A" + + def set_observed_cell_indices(self): + self.observation.selected_grid_cells = cell_index_list_from_obs_positions( + self.response.grid_dimension, + self.model_size.size, + self.observation.obs_positions, + self.model_size.use_eclipse_grid_index_origo, + ) + + +def read_config_file(config_file_name: Path) -> Dict[str, Any]: + with open(config_file_name, "r", encoding="utf-8") as f: + settings = yaml.safe_load(f) + case_name = settings["settings"]["case_name"] + model_size = ModelSize(**settings["settings"]["model_size"]) + field = Field(**settings["settings"]["field"]) + response = Response(**settings["settings"]["response"]) + observation = Observation(**settings["settings"]["observation"]) + localisation = Localisation(**settings["settings"]["localisation"]) + optional = Optional(**settings["settings"]["optional"]) + settings = Settings( + case_name=case_name, + model_size=model_size, + field=field, + response=response, + observation=observation, + localisation=localisation, + optional=optional, + ) + settings.set_observed_cell_indices() + return settings + + +def update_key(key, default_value, settings_dict, parent_key=None): + value = settings_dict.get(key, default_value) + if value != default_value: + if parent_key: + print(f"Changed settings parameter for {key} under {parent_key} : {value} ") + else: + print(f"Changed settings parameter for {key} : {value} ") + return value + + +def update_settings(settings_original: Settings, config_dict: dict): + # pylint: disable=too-many-branches, too-many-statements + settings_dict = config_dict["settings"] + settings = copy.deepcopy(settings_original) + valid_keys = [ + "case_name", + "model_size", + "field", + "response", + "observation", + "localisation", + "optional", + ] + for key in settings_dict: + if key not in valid_keys: + raise KeyError(f"Unknown keyword {key} in 'settings' ") + + key = "case_name" + if key in settings_dict: + settings[key] = settings_dict[key] + + key = "model_size" + model_size_dict = settings_dict[key] if key in settings_dict else None + valid_keys = [ + "size", + "polygon_file", + "use_eclipse_grid_index_origo", + ] + if model_size_dict: + err_msg = [] + for sub_key in model_size_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + model_size_object = settings.model_size + model_size_object.size = update_key( + "size", model_size_object.size, model_size_dict, key + ) + model_size_object.polygon_file = update_key( + "polygon_file", model_size_object.polygon_file, model_size_dict, key + ) + model_size_object.use_eclipse_grid_index_origo = update_key( + "use_eclipse_grid_index_origo", + model_size_object.use_eclipse_grid_index_origo, + model_size_dict, + key, + ) + + key = "field" + field_dict = settings_dict[key] if key in settings_dict else None + valid_keys = [ + "name", + "algorithm", + "file_format", + "initial_file_name_prefix", + "updated_file_name_prefix", + "seed_file", + "variogram", + "correlation_range", + "correlation_azimuth", + "correlation_dip", + "correlation_exponent", + "trend_use", + "trend_params", + "trend_relstd", + "grid_dimension", + "grid_file_name", + ] + if field_dict: + err_msg = [] + for sub_key in field_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + field = settings.field + field.name = update_key("name", field.name, field_dict, key) + field.algorithm = update_key("algorithm", field.algorithm, field_dict, key) + field.file_format = update_key( + "file_format", field.file_format, field_dict, key + ) + field.initial_file_name_prefix = update_key( + "initial_file_name_prefix", field.initial_file_name_prefix, field_dict, key + ) + field.updated_file_name_prefix = update_key( + "updated_file_name_prefix", field.updated_file_name_prefix, field_dict, key + ) + field.seed_file = update_key("seed_file", field.seed_file, field_dict, key) + field.variogram = update_key("variogram", field.variogram, field_dict, key) + field.correlation_range = update_key( + "correlation_range", field.correlation_range, field_dict, key + ) + field.correlation_azimuth = update_key( + "correlation_azimuth", field.correlation_azimuth, field_dict, key + ) + field.correlation_dip = update_key( + "correlation_dip", field.correlation_dip, field_dict, key + ) + field.correlation_exponent = update_key( + "correlation_exponent", field.correlation_exponent, field_dict, key + ) + field.trend_use = update_key("trend_use", field.trend_use, field_dict, key) + field.trend_params = update_key( + "trend_params", field.trend_params, field_dict, key + ) + field.grid_dimension = update_key( + "grid_dimension", field.grid_dimension, field_dict, key + ) + field.grid_file_name = update_key( + "grid_file_name", field.grid_file_name, field_dict, key + ) + + key = "response" + response_dict = settings_dict[key] if key in settings_dict else None + valid_keys = [ + "name", + "grid_dimension", + "upscaled_file_name", + "grid_file_name", + "file_format", + "write_upscaled_field", + "response_function", + "gen_data_file_prefix", + "ert_config_template_file", + "ert_config_file", + ] + if response_dict: + err_msg = [] + for sub_key in response_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + response = settings.response + response.name = update_key("name", response.name, response_dict, key) + response.grid_dimension = update_key( + "grid_dimension", response.grid_dimension, response_dict, key + ) + response.upscaled_file_name = update_key( + "upscaled_file_name", response.upscaled_file_name, response_dict, key + ) + response.grid_file_name = update_key( + "grid_file_name", response.grid_file_name, response_dict, key + ) + response.file_format = update_key( + "file_format", response.file_format, response_dict, key + ) + response.write_upscaled_field = update_key( + "write_upscaled_field", response.write_upscaled_field, response_dict, key + ) + response.response_function = update_key( + "response_function", response.response_function, response_dict, key + ) + response.gen_data_file_prefix = update_key( + "gen_data_file_prefix", response.gen_data_file_prefix, response_dict, key + ) + response.ert_config_template_file = update_key( + "ert_config_template_file", + response.ert_config_template_file, + response_dict, + key, + ) + response.ert_config_file = update_key( + "ert_config_file", + response.ert_config_file, + response_dict, + key, + ) + + key = "observation" + obs_dict = settings_dict[key] if key in settings_dict else None + valid_keys = [ + "directory", + "file_name", + "data_dir", + "reference_param_file", + "reference_field_name", + "rel_error", + "min_abs_error", + "obs_positions", + ] + + if obs_dict: + err_msg = [] + for sub_key in obs_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + observation = settings.observation + observation.directory = update_key( + "directory", observation.directory, obs_dict, key + ) + observation.file_name = update_key( + "file_name", observation.file_name, obs_dict, key + ) + observation.data_dir = update_key( + "data_dir", observation.data_dir, obs_dict, key + ) + observation.reference_param_file = update_key( + "reference_param_file", observation.reference_param_file, obs_dict, key + ) + observation.reference_field_name = update_key( + "reference_field_name", observation.reference_field_name, obs_dict, key + ) + observation.rel_error = update_key( + "rel_error", observation.rel_error, obs_dict, key + ) + observation.min_abs_error = update_key( + "min_abs_error", observation.min_abs_error, obs_dict, key + ) + observation.obs_positions = update_key( + "obs_positions", observation.obs_positions, obs_dict, key + ) + + key = "localisation" + local_dict = settings_dict[key] if key in settings_dict else None + valid_keys = ["method", "use_localisation"] + + if local_dict: + err_msg = [] + for sub_key in local_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + localisation = settings.localisation + localisation.method = update_key("method", localisation.method, local_dict, key) + localisation.use_localisation = update_key( + "use_localisation", localisation.use_localisation, local_dict, key + ) + + key = "optional" + optional_dict = settings_dict[key] if key in settings_dict else None + valid_keys = ["write_obs_pred_diff_field_file"] + + if optional_dict: + err_msg = [] + for sub_key in optional_dict: + if sub_key not in valid_keys: + err_msg.append(f" {sub_key}") + if len(err_msg) > 0: + print(f"Unknown keywords in config file under keyword {key}: ") + for text in err_msg: + print(text) + raise KeyError("Unknown keywords") + + optional = settings.optional + optional.write_obs_pred_diff_field_file = update_key( + "write_obs_pred_diff_field_file", + optional.write_obs_pred_diff_field_file, + optional_dict, + key, + ) + settings.set_observed_cell_indices() + return settings + + +def generate_field_and_upscale( + # pylint: disable=too-many-arguments + real_number: int, + iteration: int, + seed_file_name: str, + algorithm_method: str, + field_name: str, + field_file_name: str, + file_format: str, + grid_dimension: tuple, + model_size: tuple, + variogram_name: str, + corr_ranges: tuple, + azimuth: float, + dip: float, + alpha: float, + use_trend: bool, + trend_params: tuple, + relative_std: float, + upscale_name: str, + response_function: str, + upscaled_file_name: str, + grid_dimension_upscaled: tuple, + write_upscaled_field: bool, + use_standard_grid_index_origo: bool, +): + start_seed = get_seed(seed_file_name, real_number) + if algorithm_method == "gstools": + print(f"Use algorithm: {algorithm_method} with version: {gs.__version__} ") + residual_field = simulate_field_using_gstools( + start_seed, + variogram_name, + corr_ranges, + azimuth, + grid_dimension, + model_size, + use_standard_grid_index_origo, + ) + else: + print("Use algorithm: gaussianfft") + residual_field = simulate_field( + start_seed, + variogram_name, + corr_ranges, + azimuth, + dip, + alpha, + grid_dimension, + model_size, + use_standard_grid_index_origo, + ) + if use_trend: + trend_field = trend(grid_dimension, model_size, trend_params) + field3D = trend_field + relative_std * residual_field + else: + field3D = residual_field + + # Write field parameter for fine scale grid + field_object = export_field( + field3D, field_name, field_file_name, file_format, grid_dimension + ) + + field_values = field_object.values + + # Calculate upscaled values for selected coarse grid cells + upscaled_values = upscaling( + field_values, + response_function, + file_format, + upscale_name, + write_upscaled_field, + upscaled_file_name, + grid_dimension_upscaled, + iteration, + ) + return upscaled_values + + +def get_seed(seed_file_name, r_number): + with open(seed_file_name, "r", encoding="utf8") as file: + lines = file.readlines() + try: + seed_value = int(lines[r_number]) + except IndexError as exc: + raise IOError("Seed value not found for realization {r_number} ") from exc + except ValueError as exc: + raise IOError( + "Invalid seed value in file for realization{r_number}" + ) from exc + return seed_value + + +def upscaling( + # pylint: disable=too-many-arguments + field_values, + response_function_name: str, + file_format: str, + upscaled_field_name: str, + write_upscaled_field: bool, + upscaled_file_name: str, + dimension: tuple, + iteration: int = 0, +): + """ + Calculate upscaled values and optionally write upscaled values to file. + Return upscaled values + """ + NX, NY, NZ = dimension + upscaled_values = np.zeros((NX, NY, NZ), dtype=np.float32, order="F") + upscaled_values[:, :, :] = -999 + + if response_function_name == "average": + upscaled_values = upscale_average( + field_values, + upscaled_values, + ) + + if write_upscaled_field: + if iteration == 0: + upscaled_file_name = "init_files/" + upscaled_file_name + + write_upscaled_field_to_file( + upscaled_values, + upscaled_file_name, + upscaled_field_name, + file_format=file_format, + ) + + return upscaled_values + + +# pylint: disable=too-many-arguments +def write_upscaled_field_to_file( + upscaled_values, + upscaled_file_name, + upscaled_field_name, + selected_cell_index_list=None, + file_format="ROFF", +): + nx, ny, nz = upscaled_values.shape + + field_object = xtgeo.grid3d.GridProperty( + ncol=nx, + nrow=ny, + nlay=nz, + values=upscaled_values, + discrete=False, + name=upscaled_field_name, + ) + + if file_format.upper() == "ROFF": + fullfilename = upscaled_file_name + ".roff" + field_object.to_file(fullfilename, fformat="roff") + elif file_format.upper() == "GRDECL": + fullfilename = upscaled_file_name + ".GRDECL" + field_object.to_file(fullfilename, fformat="grdecl") + else: + raise ValueError(f"Unknown file format: {file_format} ") + print(f"Write upscaled field file: {fullfilename} ") + + if selected_cell_index_list is not None: + # Grid index order to xtgeo must be c-order masked array + selected_upscaled_values = np.ma.zeros((nx, ny, nz), dtype=np.float32) + selected_upscaled_values[:, :, :] = -1 + nobs = get_nobs_from_cell_index_list(selected_cell_index_list) + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices( + obs_number, selected_cell_index_list + ) + selected_upscaled_values[Iindx, Jindx, Kindx] = upscaled_values[ + Iindx, Jindx, Kindx + ] + + field_name_selected = upscaled_field_name + "_conditioned_cells" + file_name_selected = "init_files/" + field_name_selected + ".roff" + cond_field_object = xtgeo.grid3d.GridProperty( + ncol=nx, + nrow=ny, + nlay=nz, + values=selected_upscaled_values, + discrete=False, + name=field_name_selected, + ) + print(f"Write conditioned cell values as field: {file_name_selected}") + cond_field_object.to_file(file_name_selected, fformat="roff") + + return field_object + + +def upscale_average(field_values, upscaled_values): + """ + Input: field_values (numpy 3D) + coarse_cell_index_list (list of tuples (I,J,K)) + Output: upscaled_values (numpy 3D) initialized outside + but filled in specified (I,J,K) cells. + """ + nx, ny, nz = field_values.shape + NX, NY, NZ = upscaled_values.shape + + print(f"Number of fine scale grid cells: (nx,ny,nz): ({nx},{ny},{nz})") + print(f"Number of coarse scale grid cells: (NX,NY,NZ): ({NX},{NY},{NZ}) ") + mx = int(nx / NX) + my = int(ny / NY) + mz = int(nz / NZ) + print( + "Number of fine scale grid cells per coarse grid cell: " + f"(mx,my,mz): ({mx},{my},{mz}) " + ) + + print("Calculate upscaled values for all grid cells") + for Kindx in range(NZ): + for Jindx in range(NY): + for Iindx in range(NX): + i_slice = slice(Iindx * mx, (Iindx + 1) * mx) + j_slice = slice(Jindx * my, (Jindx + 1) * my) + k_slice = slice(Kindx * mz, (Kindx + 1) * mz) + upscaled_values[Iindx, Jindx, Kindx] = np.mean( + field_values[i_slice, j_slice, k_slice] + ) + return upscaled_values + + +def trend(grid_dimension: tuple, model_size: tuple, trend_params: tuple): + """ + Return 3D numpy array with values following a linear trend + scaled to take values between 0 and 1. + """ + nx, ny, nz = grid_dimension + xsize, ysize, _ = model_size + a, b = trend_params + + x0 = 0.0 + y0 = 0.0 + dx = xsize / nx + dy = ysize / ny + + maxsize = ysize + if xsize > ysize: + maxsize = xsize + + val = np.zeros((nx, ny, nz), dtype=np.float32, order="F") + for i in range(nx): + x = x0 + i * dx + for j in range(ny): + y = y0 + j * dy + for k in range(nz): + val[i, j, k] = a * (x - x0) / maxsize + b * (y - y0) / maxsize + + minval = np.min(val) + maxval = np.max(val) + val_normalized = (val - minval) / (maxval - minval) + return val_normalized + + +def simulate_field( + start_seed: int, + variogram_name: str, + corr_ranges: tuple, + azimuth: float, + dip: float, + alpha: float, + grid_dimension: tuple, + model_size: tuple, + use_standard_grid_index_origo: bool, +): + # pylint: disable=import-outside-toplevel + # This function will not be available untill gaussianfft is available on python 3.10 + # import gaussianfft as sim # isort: skip + # dummy code to avoid pylint complaining in github actions + sim = None + nx, ny, nz = grid_dimension + xrange, yrange, zrange = corr_ranges + xsize, ysize, zsize = model_size + + dx = xsize / nx + dy = ysize / ny + dz = zsize / nz + + print(f"Start seed: {start_seed}") + sim.seed(start_seed) + + variogram = sim.variogram( + variogram_name, + xrange, + perp_range=yrange, + depth_range=zrange, + azimuth=azimuth - 90, + dip=dip, + power=alpha, + ) + + print(f"Simulate field with size: nx={nx},ny={ny} ") + # gaussianfft.simulate will save the values in F-order + field1D = sim.simulate(variogram, nx, dx, ny, dy, nz, dz) + field_sim = field1D.reshape((nx, ny, nz), order="F") + if use_standard_grid_index_origo: + field_c_order = np.ma.zeros((nx, ny, nz), dtype=np.float32) + j_indices = -np.arange(ny) + ny - 1 + # Flip j index and use c-order + field_c_order[:, j_indices, :] = field_sim[:, :, :] + return field_c_order + # Change to C-order + field_c_order = np.ma.zeros((nx, ny, nz), dtype=np.float32) + field_c_order[:, :, :] = field_sim[:, :, :] + return field_c_order + + +def simulate_field_using_gstools( + start_seed: int, + variogram_name: str, + corr_ranges: tuple, + azimuth: float, + grid_dimension: tuple, + model_size: tuple, + use_standard_grid_index_origo: bool, +): + # pylint: disable=no-member, + xrange, yrange, zrange = corr_ranges + xsize, ysize, zsize = model_size + nx, ny, nz = grid_dimension + + dx = xsize / nx + dy = ysize / ny + dz = zsize / nz + + x = np.arange(0.5 * dx, xsize, dx) + y = np.arange(0.5 * dy, ysize, dy) + z = np.arange(0.5 * dz, zsize, dz) + # Rescale factor is set to: + # sqrt(3.0) for gaussian correlation functions, + # 3.0 for exponetial correlation function, + # to ensure the correlation function have the same definition of correlation + # lenght as is used in RMS and gaussianfft algorithm. + print(f"Variogram name: {variogram_name}") + if variogram_name.upper() == "GAUSSIAN": + model = gs.Gaussian( + dim=3, + var=1.0, + len_scale=[xrange, yrange, zrange], + angles=np.pi * (0.5 - azimuth / 180.0), + rescale=math.sqrt(3), + ) + elif variogram_name.upper() == "EXPONENTIAL": + model = gs.Exponential( + dim=3, + var=1.0, + len_scale=[xrange, yrange, zrange], + angles=np.pi * (0.5 - azimuth / 180.0), + rescale=3, + ) + else: + raise ValueError(f"Unknown variogram type: {variogram_name} ") + + print(f"Start seed: {start_seed}") + print(f"Simulate field with size: nx={nx},ny={ny} nz={nz} ") + srf = gs.SRF(model, seed=start_seed) + field_srf = srf.structured([x, y, z], store="Field") + field = field_srf.reshape((nx, ny, nz)) + if use_standard_grid_index_origo: + field_flip_j_index = np.ma.zeros((nx, ny, nz), dtype=np.float32) + j_indices = -np.arange(ny) + ny - 1 + field_flip_j_index[:, j_indices, :] = field[:, :, :] + return field_flip_j_index + + return field + + +def export_field( + field3D, + field_name: str, + field_file_name: str, + file_format: str, + grid_dimension: tuple, +): + """ + Export initial realization of field to roff format + Input field3D should be C-index order since xtgeo requires that + """ + nx, ny, nz = grid_dimension + field_object = xtgeo.grid3d.GridProperty( + ncol=nx, nrow=ny, nlay=nz, values=field3D, discrete=False, name=field_name + ) + if file_format.upper() == "GRDECL": + fullfilename = field_file_name + ".grdecl" + field_object.to_file( + fullfilename, fformat="grdecl", dtype="float32", fmt="%20.6f" + ) + elif file_format.upper() == "ROFF": + fullfilename = field_file_name + ".roff" + field_object.to_file(fullfilename, fformat="roff") + else: + raise IOError(f"Unknown file format for fields: {file_format} ") + print(f"Write field file: {fullfilename} ") + return field_object + + +def read_field_from_file( + input_file_name: str, name: str, file_format: str, grid_file_name: str +): + """ + Read field from roff formatted file and return xtgeo property object + """ + if file_format.upper() == "GRDECL": + grid = xtgeo.grid_from_file(grid_file_name, fformat="egrid") + fullfilename = input_file_name + ".grdecl" + field_object = xtgeo.grid3d.GridProperty( + fullfilename, fformat="grdecl", grid=grid, name=name + ) + elif file_format.upper() == "ROFF": + fullfilename = input_file_name + ".roff" + field_object = xtgeo.gridproperty_from_file( + fullfilename, fformat="roff", name=name + ) + else: + raise IOError(f"Unknown file format for fields: {file_format} ") + return field_object + + +def read_obs_field_from_file( + file_format: str, pred_obs_file_name: str, grid_file_name: str, field_name: str +): + """ + Read field parameter containing parameter with observed values + for selected grid cells + """ + if file_format.upper() == "ROFF": + fullfilename = pred_obs_file_name + ".roff" + obs_field_object = xtgeo.gridproperty_from_file(fullfilename, fformat="roff") + elif file_format.upper() == "GRDECL": + grid = xtgeo.grid_from_file(grid_file_name, fformat="egrid") + fullfilename = pred_obs_file_name + ".grdecl" + obs_field_object = xtgeo.gridproperty_from_file( + fullfilename, fformat="grdecl", grid=grid, name=field_name + ) + else: + raise IOError(f"Unknown file format:{file_format} ") + return obs_field_object + + +def read_upscaled_field_from_file( + iteration: int, + input_file_name: str, + file_format: str, + upscaled_field_name: str, + grid_file_name: str, +): + """ + Read upscaled field parameter either from initial ensemble or updated ensemble. + Return xtgeo property object + """ + + if iteration == 0: + filename = "init_files/" + input_file_name + else: + filename = input_file_name + if file_format.upper() == "ROFF": + fullfilename = filename + ".roff" + field_object = xtgeo.gridproperty_from_file(fullfilename, fformat="roff") + elif file_format.upper() == "GRDECL": + grid = xtgeo.grid_from_file(grid_file_name, fformat="egrid") + fullfilename = filename + ".grdecl" + field_object = xtgeo.gridproperty_from_file( + fullfilename, fformat="grdecl", grid=grid, name=upscaled_field_name + ) + else: + raise IOError(f"Unknown file format:{file_format} ") + return field_object + + +def write_obs_pred_diff_field( + upscaled_field_object, observation_field_object, file_format: str +): + """ + Get xtgeo property objects for predicted values for observables + and observation values. + Write file with difference as roff formatted file. + """ + nx, ny, nz = upscaled_field_object.dimensions + values_diff = upscaled_field_object.values - observation_field_object.values + + diff_object = xtgeo.grid3d.GridProperty( + ncol=nx, + nrow=ny, + nlay=nz, + values=values_diff, + discrete=False, + name="DiffObsPred", + ) + + filename = "DiffObsPred" + if file_format.upper() == "ROFF": + fullfilename = filename + ".roff" + diff_object.to_file(fullfilename, fformat="roff") + elif file_format.upper() == "GRDECL": + fullfilename = filename + ".grdecl" + diff_object.to_file(fullfilename, fformat="grdecl") + else: + raise IOError(f"Unknown file format: {file_format} ") + print( + "Write field with difference between upscaled reference " + "field from which observations are extracted and " + f"and prediction from current realization: {fullfilename} " + ) + + +def get_cell_indices(obs_number, cell_indx_list): + if cell_indx_list is None: + return None + if len(cell_indx_list) == 0: + return None + try: + Iindx = cell_indx_list[obs_number][0] + Jindx = cell_indx_list[obs_number][1] + Kindx = cell_indx_list[obs_number][2] + except IndexError: + try: + Iindx = cell_indx_list[0] + Jindx = cell_indx_list[1] + Kindx = cell_indx_list[2] + except IndexError: + raise ValueError(f"Index error for cell indices in: {cell_indx_list}") + + return (Iindx, Jindx, Kindx) + + +def get_obs_pos(obs_number, obs_pos_list): + x = obs_pos_list[obs_number][0] + y = obs_pos_list[obs_number][1] + z = obs_pos_list[obs_number][2] + + return (x, y, z) + + +def get_nobs_from_cell_index_list(cell_index_list: list): + """ + Check if cell_index_list is a single tuple (i,j,k) or + a list of tuples of type (i,j,k). + Return number of cell_indices found in list + """ + is_list_of_ints = all(isinstance(indx, int) for indx in cell_index_list) + if is_list_of_ints: + nobs = 1 + else: + # list of tuples (x,y,z) + nobs = len(cell_index_list) + return nobs + + +def get_nobs_from_position_list(obs_positions: list): + """ + Check if obs_positions is a single tuple (x,y,z) or + a list of tuples of type (x,y,z). + Return number of positions found in list + """ + if not obs_positions: + return 0 + is_list_of_floats = all( + isinstance(coordinate, float) for coordinate in obs_positions + ) + if is_list_of_floats: + nobs = 1 + else: + # list of tuples (x,y,z) + nobs = len(obs_positions) + return nobs + + +def obs_positions_from_cell_index( + grid_dimension_upscaled: tuple, + model_size: tuple, + cell_indx_list: list, + use_eclipse_origo: bool, +): + nx, ny, nz = grid_dimension_upscaled + xsize, ysize, zsize = model_size + + dx = xsize / nx + dy = ysize / ny + dz = zsize / nz + + if use_eclipse_origo: + print("Grid index origin: Eclipse standard") + else: + print("Grid index origin: RMS standard") + print( + "Observation reference point coordinates is always " + "from origin at lower left corner" + ) + + pos_list = [] + nobs = get_nobs_from_cell_index_list(cell_indx_list) + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, cell_indx_list) + x = (Iindx + 0.5) * dx + z = (Kindx + 0.5) * dz + if use_eclipse_origo: + y = ysize - (Jindx + 0.5) * dy + else: + y = (Jindx + 0.5) * dy + + pos_list.append((x, y, z)) + + return pos_list + + +def cell_index_list_from_obs_positions( + grid_dimension_upscaled: tuple, + model_size: tuple, + obs_positions: list, + use_eclipse_origo: bool, +): + nx, ny, nz = grid_dimension_upscaled + xsize, ysize, zsize = model_size + + dx = xsize / nx + dy = ysize / ny + dz = zsize / nz + + if use_eclipse_origo: + print("Grid index origin: Eclipse standard") + else: + print("Grid index origin: RMS standard") + print( + "Observation reference point coordinates is always " + "from origin at lower left corner" + ) + + cell_index_list = [] + nobs = get_nobs_from_position_list(obs_positions) + for obs_number in range(nobs): + obs_pos = get_obs_pos(obs_number, obs_positions) + Iindx = int(obs_pos[0] / dx) + Jindx = int(obs_pos[1] / dy) + Kindx = int(obs_pos[2] / dz) + if use_eclipse_origo: + Jindx = ny - Jindx - 1 + cell_index_list.append((Iindx, Jindx, Kindx)) + + return cell_index_list + + +def read_observations( + config_path: str, + observation_dir: str, + obs_data_dir: str, + cell_index_list: list, +): + values = [] + for index in cell_index_list: + Iindx = index[0] + Jindx = index[1] + Kindx = index[2] + filename = ( + config_path + + "/" + + observation_dir + + "/" + + obs_data_dir + + "/" + + "obs_" + + str(Iindx + 1) + + "_" + + str(Jindx + 1) + + "_" + + str(Kindx + 1) + + ".txt" + ) + print(f"Read observations from: {filename}") + with open(filename, "r", encoding="utf-8") as file: + lines = file.readlines() + for line in lines: + words = line.split() + if len(words) == 2: + values.append(float(words[0])) + return values + + +def write_gen_obs( + upscaled_values, + observation_dir: str, + obs_file_name: str, + obs_data_dir: str, + cell_index_list: list, + rel_err: float, + min_err: float, +): + if os.path.exists(observation_dir): + shutil.rmtree(observation_dir) + print(f"Create directory: {observation_dir} ") + os.makedirs(observation_dir) + data_dir = observation_dir + "/" + obs_data_dir + if not os.path.exists(data_dir): + print(f"Create directory: {data_dir} ") + os.makedirs(data_dir) + + print(f"Write observation file: {obs_file_name} ") + filename = observation_dir + "/" + obs_file_name + observation_value_list = [] + with open(filename, "w", encoding="utf8") as obs_file: + # Check if obs_position list is a single tuple (i,j,k) + # or a list of tuples of type (i,j,k) + nobs = get_nobs_from_cell_index_list(cell_index_list) + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, cell_index_list) + value = upscaled_values[Iindx, Jindx, Kindx] + observation_value_list.append(value) + value_err = math.fabs(value) * rel_err + value_err = max(value_err, min_err) + + obs_data_relative_file_name = ( + obs_data_dir + + "/obs_" + + str(Iindx + 1) + + "_" + + str(Jindx + 1) + + "_" + + str(Kindx + 1) + + ".txt" + ) + + obs_file.write(f"GENERAL_OBSERVATION OBS_{Iindx+1}_{Jindx+1}_{Kindx+1} ") + obs_file.write("{ ") + obs_file.write( + f"DATA = RESULT_UPSCALED_FIELD ; INDEX_LIST = {obs_number} ; " + ) + obs_file.write("RESTART = 0; ") + obs_file.write(f"OBS_FILE = ./{obs_data_relative_file_name} ; ") + obs_file.write(" };\n") + + data_file_name = observation_dir + "/" + obs_data_relative_file_name + print(f"Write file: {data_file_name} ") + with open(data_file_name, "w", encoding="utf8") as data_file: + data_file.write(f"{value} {value_err}\n") + + +def create_grid( + grid_file_name, + dimensions, + size, + standard_grid_index_origo, + polygon_file_name=None, +): + xsize, ysize, zsize = size + nx, ny, nz = dimensions + if standard_grid_index_origo: + flip = -1 + x0 = 0.0 + y0 = ysize + z0 = 0.0 + else: + flip = 1 + x0 = 0.0 + y0 = 0.0 + z0 = 0.0 + + dx = xsize / nx + dy = ysize / ny + dz = zsize / nz + + grid_object = xtgeo.create_box_grid( + dimension=(nx, ny, nz), + origin=(x0, y0, z0), + increment=(dx, dy, dz), + rotation=0.0, + flip=flip, + ) + + if polygon_file_name is not None and os.path.exists(polygon_file_name): + print(f"Use polygon file {polygon_file_name} to create actnum ") + polygon = xtgeo.polygons_from_file(polygon_file_name, fformat="xyz") + grid_object.inactivate_outside(polygon) + + print(f"Write grid file: {grid_file_name} ") + grid_object.to_file(grid_file_name, fformat="egrid") + return grid_object + + +# pylint: disable=too-many-statements,too-many-branches +def write_localisation_config( + obs_positions: list, + obs_index_list: list, + field_name: str, + corr_ranges: tuple, + azimuth: float, + config_file_name: str = "local_config.yml", + write_scaling: bool = True, + localisation_method: str = "gaussian", + segment_file_name: str = None, + scaling_param_file_name: str = None, +): + space = " " * 2 + space2 = " " * 4 + space3 = " " * 6 + print(f"Write localisation config file: {config_file_name}") + with open(config_file_name, "w", encoding="utf8") as file: + file.write("log_level: 3\n") + file.write(f"write_scaling_factors: {write_scaling}\n") + file.write("correlations:\n") + nobs = get_nobs_from_position_list(obs_positions) + if nobs != get_nobs_from_cell_index_list(obs_index_list): + raise ValueError( + "Inconsistency between observation list and cell-index_list" + ) + local_method = localisation_method.lower() + if local_method in ["gaussian", "exponential"]: + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, obs_index_list) + obs_name = f"OBS_{Iindx+1}_{Jindx+1}_{Kindx+1}" + pos = obs_positions[obs_number] + file.write(f"{space}- name: CORR_{obs_number}\n") + file.write(f"{space2}obs_group:\n") + file.write(f'{space3}add: ["{obs_name}"]\n') + file.write(f"{space2}param_group:\n") + file.write(f'{space3}add: ["{field_name}"]\n') + file.write(f"{space2}field_scale:\n") + if local_method == "gaussian": + file.write(f"{space3}method: gaussian_decay\n") + else: + file.write(f"{space3}method: exponential_decay\n") + file.write(f"{space3}main_range: {corr_ranges[0]}\n") + file.write(f"{space3}perp_range: {corr_ranges[1]}\n") + file.write(f"{space3}azimuth: {azimuth}\n") + file.write(f"{space3}ref_point: [ {pos[0]}, {pos[1]} ]\n") + + if local_method == "constant": + # Constant scaling factor, use only one correlation group + file.write(f"{space}- name: CORR\n") + file.write(f"{space2}obs_group:\n") + file.write(f"{space3}add: [ ") + obs_list = "" + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, obs_index_list) + obs_name = f' "OBS_{Iindx+1}_{Jindx+1}_{Kindx+1}" ' + obs_list += obs_name + if obs_number < (nobs - 1): + obs_list += ", " + else: + obs_list += " ]" + file.write(obs_list) + file.write("\n") + pos = obs_positions[0] + file.write(f"{space2}param_group:\n") + file.write(f'{space3}add: ["{field_name}"]\n') + file.write(f"{space2}field_scale:\n") + file.write(f"{space3}method: constant\n") + file.write(f"{space3}value: 1.0\n") + + if local_method == "region": + # Use region parameter with one obs per region + if segment_file_name is None or len(segment_file_name) == 0: + raise ValueError("Missing segment file name when using region") + + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, obs_index_list) + obs_name = f"OBS_{Iindx+1}_{Jindx+1}_{Kindx+1}" + pos = obs_positions[obs_number] + file.write(f"{space}- name: CORR_{obs_number}\n") + file.write(f"{space2}obs_group:\n") + file.write(f'{space3}add: ["{obs_name}"]\n') + file.write(f"{space2}param_group:\n") + file.write(f'{space3}add: ["{field_name}"]\n') + file.write(f"{space2}field_scale:\n") + file.write(f"{space3}method: segment\n") + file.write(f'{space3}segment_filename: "{segment_file_name}"\n') + file.write(f'{space3}param_name: "Region"\n') + file.write(f"{space3}active_segments: [ {obs_number + 1} ]\n") + file.write(f"{space3}scalingfactors: [ 1.0 ]\n") + file.write(f"{space3}smooth_ranges: [ 1, 1 ]\n") + + if local_method == "scaling_file": + # Use a scaling factor from file + file.write(f"{space}- name: CORR\n") + file.write(f"{space2}obs_group:\n") + file.write(f"{space3}add: [ ") + obs_list = "" + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, obs_index_list) + obs_name = f' "OBS_{Iindx+1}_{Jindx+1}_{Kindx+1}" ' + obs_list += obs_name + if obs_number < (nobs - 1): + obs_list += ", " + else: + obs_list += " ]" + file.write(obs_list) + file.write("\n") + pos = obs_positions[0] + file.write(f"{space2}param_group:\n") + file.write(f'{space3}add: ["{field_name}"]\n') + file.write(f"{space2}field_scale:\n") + file.write(f"{space3}method: from_file\n") + file.write(f'{space3}filename: "{scaling_param_file_name}"\n') + file.write(f'{space3}param_name: "SCALING"\n') + + +def generate_seed_file( + file_name: str, + start_seed: int = 9828862224, + number_of_seeds: int = 1000, +): + print(f"Generate random seed file: {file_name}") + random.seed(start_seed) + with open(file_name, "w", encoding="utf8") as file: + for _ in range(number_of_seeds): + file.write(f"{random.randint(1, 999999999)}\n") + + +def generate_segments( + polygon_file_name: str, + region_file_name: str, + grid_object, +): + if polygon_file_name is None or not os.path.exists(polygon_file_name): + raise ValueError( + f"Missing polygon file {polygon_file_name} when creating region parameter" + ) + dimensions = grid_object.dimensions + nx = dimensions[0] + ny = dimensions[1] + nz = dimensions[2] + codenames_dict = { + 1: "RegionA", + 2: "RegionB", + 3: "RegionC", + } + region_object = xtgeo.GridProperty( + ncol=nx, + nrow=ny, + nlay=nz, + name="Region", + discrete=True, + values=np.zeros((nx, ny, nz), dtype=np.int32), + codes=codenames_dict, + grid=grid_object, + ) + + print(f"Use polygon file {polygon_file_name} to create region parameter ") + polygon_object = xtgeo.polygons_from_file(polygon_file_name, fformat="xyz") + for poly_id in [0, 1, 2]: + wpoly = polygon_object.copy() + wpoly.dataframe = wpoly.dataframe[wpoly.dataframe.POLY_ID == poly_id] + region_object.set_inside(wpoly, poly_id + 1) + + print(f"Write region parameter: {region_file_name} ") + region_object.to_file(region_file_name, fformat="grdecl") + + +def create_ert_config_file( + template_file_name: str, + case_name: str, + ensemble_seed_file_name: str, + nreal: int, + ert_start_seed: int, + response_file_name_prefix: str, + grid_file_name: str, + upscaled_grid_file_name: str, + initial_field_param_file_prefix: str, + updated_field_param_file_prefix: str, + field_file_format: str, + use_localisation: bool, + output_config_file_name: str = "sim_field.ert", +) -> None: + try: + with open(template_file_name, "r", encoding="utf-8") as file: + lines = file.readlines() + except IOError: + raise IOError(f"Cannot open and read file: {template_file_name}") + + load_workflow = "LOAD_WORKFLOW localisation.wf LOCALISATION_WORKFLOW" + hook_workflow = "HOOK_WORKFLOW LOCALISATION_WORKFLOW PRE_FIRST_UPDATE" + local = "_local" if use_localisation else "" + + strings_to_replace_dict = { + "CASE_NAME": "sim_field_" + case_name + local, + "ENSEMBLE_SEED_FILE": ensemble_seed_file_name, + "NREAL": str(nreal), + "ERT_START_SEED": str(ert_start_seed), + "RESPONSE_FILE_PREFIX": response_file_name_prefix, + "GRID_FILE_NAME": grid_file_name, + "GRID_FILE_NAME_UPSCALED": upscaled_grid_file_name, + "INITIAL_FIELDPARAM_FILE_NAME": initial_field_param_file_prefix + + "." + + field_file_format.lower(), + "UPDATED_FIELDPARAM_FILE_NAME": updated_field_param_file_prefix + + "." + + field_file_format.lower(), + "LOAD_LOCALISATION_WORKFLOW": load_workflow + if use_localisation + else "-- " + load_workflow, + "HOOK_LOCALISATION_WORKFLOW": hook_workflow + if use_localisation + else "-- " + hook_workflow, + } + template_file_contents = Template("".join(lines)) + updated_contents = template_file_contents.safe_substitute(strings_to_replace_dict) + + if use_localisation: + print(f"Write ERT config file with localisation: {output_config_file_name}") + else: + print(f"Write ERT config file: {output_config_file_name}") + with open(output_config_file_name, "w", encoding="utf-8") as file: + file.write(updated_contents) + + +def initialize_case(settings): + # Create seed file + generate_seed_file(settings.field.seed_file) + + # Create grid for the field parameter + grid_object = create_grid( + settings.field.grid_file_name, + settings.field.grid_dimension, + settings.model_size.size, + settings.model_size.use_eclipse_grid_index_origo, + settings.model_size.polygon_file, + ) + + # Create coarse grid to be used in QC of upscaled field parameter + create_grid( + settings.response.grid_file_name, + settings.response.grid_dimension, + settings.model_size.size, + settings.model_size.use_eclipse_grid_index_origo, + settings.model_size.polygon_file, + ) + + print("Generate field parameter and upscale this.") + print( + f"The upscaled field {settings.observation.reference_param_file} " + "is used when extracting observations." + ) + + # Simulate field (with trend) + real_number = 0 + iteration = 0 + upscaled_values = generate_field_and_upscale( + real_number, + iteration, + settings.field.seed_file, + settings.field.algorithm, + settings.field.name, + settings.field.initial_file_name_prefix, + settings.field.file_format, + settings.field.grid_dimension, + settings.model_size.size, + settings.field.variogram, + settings.field.correlation_range, + settings.field.correlation_azimuth, + settings.field.correlation_dip, + settings.field.correlation_exponent, + settings.field.trend_use, + settings.field.trend_params, + settings.field.trend_relstd, + settings.response.name, + settings.response.response_function, + settings.response.upscaled_file_name, + settings.response.grid_dimension, + settings.response.write_upscaled_field, + settings.model_size.use_eclipse_grid_index_origo, + ) + + # Create observations by extracting from existing upscaled field + print( + "Selected grid cells having observations: " + f"{settings.observation.selected_grid_cells}" + ) + write_gen_obs( + upscaled_values, + settings.observation.directory, + settings.observation.file_name, + settings.observation.data_dir, + settings.observation.selected_grid_cells, + settings.observation.rel_error, + settings.observation.min_abs_error, + ) + + # Write upscaled field used as reference + # since obs are extracted from this field + write_upscaled_field_to_file( + upscaled_values, + settings.observation.reference_param_file, + upscaled_field_name=settings.observation.reference_field_name, + selected_cell_index_list=settings.observation.selected_grid_cells, + file_format=settings.field.file_format, + ) + + # Write file for non-adaptive localisation using distance based localisation + write_localisation_config( + settings.observation.obs_positions, + settings.observation.selected_grid_cells, + settings.field.name, + settings.field.correlation_range, + settings.field.correlation_azimuth, + config_file_name="local_config.yml", + write_scaling=True, + localisation_method=settings.localisation.method, + segment_file_name=settings.localisation.region_file, + scaling_param_file_name=settings.localisation.scaling_file, + ) + + if settings.localisation.method == "region": + generate_segments( + settings.localisation.region_polygons, + settings.localisation.region_file, + grid_object, + ) + + create_ert_config_file( + settings.response.ert_config_template_file, + settings.case_name, + settings.field.seed_file, + 10, + 59716487, + settings.response.gen_data_file_prefix, + settings.field.grid_file_name, + settings.response.grid_file_name, + settings.field.initial_file_name_prefix, + settings.field.updated_file_name_prefix, + settings.field.file_format, + settings.localisation.use_localisation, + settings.response.ert_config_file, + ) + + +def example_cases(name): + """ + Define the different cases here. + They define how to modify default settings + for the varios cases to test. + """ + if name == "A": + params = { + "case_name": "A", + "model_size": { + "use_eclipse_grid_index_origo": True, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD_UPSCALED.EGRID", + }, + "observation": { + "obs_positions": [ + [750.0, 750.0, 25.0], + [250.0, 1750.0, 25.0], + [250.0, 250.0, 25.0], + ], + }, + "localisation": { + "use_localisation": True, + }, + } + elif name == "B": + params = { + "case_name": "B", + "model_size": { + "use_eclipse_grid_index_origo": True, + }, + "field": { + "file_format": "GRDECL", + "grid_file_name": "GRID_STANDARD.EGRID", + }, + "response": { + "file_format": "GRDECL", + "grid_file_name": "GRID_STANDARD_UPSCALED.EGRID", + }, + "observation": { + "obs_positions": [[750.0, 750.0, 25.0], [250.0, 1750.0, 25.0]], + }, + "localisation": { + "use_localisation": True, + }, + } + elif name == "C": + params = { + "case_name": "C", + "model_size": { + "use_eclipse_grid_index_origo": False, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_RMS_ORIGO.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_RMS_ORIGO_UPSCALED.EGRID", + }, + "observation": { + "obs_positions": [[750.0, 750.0, 25.0], [250.0, 1750.0, 25.0]], + }, + "localisation": { + "use_localisation": True, + }, + } + elif name == "A2": + params = { + "case_name": "A2", + "model_size": { + "use_eclipse_grid_index_origo": True, + "polygon_file": "init_files/polygons.txt", + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_WITH_ACTNUM.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "UpscaleGrid.EGRID", + }, + "observation": { + "obs_positions": [[750.0, 750.0, 25.0], [250.0, 1750.0, 25.0]], + }, + "localisation": { + "use_localisation": True, + }, + } + elif name == "D": + params = { + "case_name": "D", + "model_size": { + "use_eclipse_grid_index_origo": True, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD_UPSCALED.EGRID", + }, + "localisation": { + "method": "constant", + "use_localisation": True, + }, + "observation": { + "obs_positions": [[750.0, 750.0, 25.0], [250.0, 1750.0, 25.0]], + }, + } + elif name == "E": + params = { + "case_name": "E", + "model_size": { + "use_eclipse_grid_index_origo": True, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD_UPSCALED.EGRID", + }, + "localisation": { + "method": "region", + "region_polygons": "init_files/region_polygons.txt", + "region_file": "regions.grdecl", + "use_localisation": True, + }, + "observation": { + "obs_positions": [[450.0, 1750.0, 25.0], [250.0, 250.0, 25.0]], + }, + } + elif name == "F": + params = { + "case_name": "F", + "model_size": { + "use_eclipse_grid_index_origo": True, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_STANDARD_UPSCALED.EGRID", + }, + "localisation": { + "method": "scaling_file", + "scaling_file": "init_files/scaling_factor.grdecl", + "use_localisation": True, + }, + "observation": { + "obs_positions": [[650.0, 850.0, 25.0]], + }, + } + elif name == "G": + params = { + "case_name": "G", + "model_size": { + "use_eclipse_grid_index_origo": False, + "polygon_file": None, + }, + "field": { + "file_format": "ROFF", + "grid_file_name": "GRID_RMS_ORIGO.EGRID", + }, + "response": { + "file_format": "ROFF", + "grid_file_name": "GRID_RMS_ORIGO_UPSCALED.EGRID", + }, + "localisation": { + "method": "scaling_file", + "scaling_file": "init_files/scaling_factor_rms_origo.grdecl", + "use_localisation": True, + }, + "observation": { + "obs_positions": [[650.0, 850.0, 25.0]], + }, + } + return params diff --git a/tests/workflows/localisation/example_case/scripts/make_reference_data.py b/tests/workflows/localisation/example_case/scripts/make_reference_data.py new file mode 100755 index 000000000..cfd701531 --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/make_reference_data.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +""" +This script can be used to create reference data for the pytest test_full.py +It uses the same configurations, the same code and random seed and run ERT +for each case using localisation. Note that each time the reference data +(GRDECL files ofr one selected realization) need to be updated, they must +be quality checked that they are correct. Visualize them , compare runs +with and without localisation to check the differences. +""" +# pylint: disable=import-error,missing-function-docstring,redefined-outer-name + +import copy +import subprocess +import yaml +from common_functions import ( + Settings, + initialize_case, + example_cases, +) + + +def example_config(case_name, use_localisation): + settings = Settings() + settings.reset_to_default() + new_settings = example_cases(case_name) + settings.update(new_settings) + + updated_settings = copy.deepcopy(settings) + updated_settings.localisation.use_localisation = use_localisation + + # Write yml file for the sim_fields.py script + main_settings_dict = updated_settings.to_dict() + with open("example_config.yml", "w", encoding="utf-8") as file: + file.write( + yaml.safe_dump(main_settings_dict, indent=4, default_flow_style=False) + ) + return updated_settings + + +def run_case(settings, select_real=5, select_iter=1): + initialize_case(settings) + # Run case in ERT + print("Run ERT") + case_name = settings.case_name + use_localisation = settings.localisation.use_localisation + local = "_local" if use_localisation else "" + command = [ + "ert", + "ensemble_smoother", + "--target-case", + f"case_{case_name}{local}", + "sim_field.ert", + ] + subprocess.run(command, check=True) + + grid_file_name = settings.field.grid_file_name + file_format = settings.field.file_format.lower() + # Select one of the realizations for the initial and updated + # ensemble as a reference for each case. + # Convert the files to GRDECL format. If the cases have + # generated correct results, save the references + # to git as reference data for the test_full.py pytest script. + print("Convert reference file to GRDECL format") + command = [ + "cp", + f"simulations/sim_field_{case_name}{local}/" + f"realization-{select_real}/iter-0/init_files/FieldParam.{file_format}", + f"init_files/FieldParam_real{select_real}_iter0_{case_name}{local}." + f"{file_format}", + ] + subprocess.run(command, check=True) + + command = [ + "cp", + f"simulations/sim_field_{case_name}{local}/" + f"realization-{select_real}/iter-{select_iter}/FieldParam.{file_format}", + f"init_files/FieldParam_real{select_real}_iter{select_iter}_{case_name}{local}." + f"{file_format}", + ] + subprocess.run(command, check=True) + + command = [ + "./scripts/roff_to_grdecl.py", + f"init_files/FieldParam_real{select_real}_iter0_{case_name}{local}." + f"{file_format}", + f"init_files/FieldParam_real{select_real}_iter0_{case_name}{local}.grdecl", + f"{grid_file_name}", + ] + subprocess.run(command, check=True) + + command = [ + "./scripts/roff_to_grdecl.py", + f"init_files/FieldParam_real{select_real}_iter{select_iter}_{case_name}{local}." + f"{file_format}", + f"init_files/FieldParam_real{select_real}_iter{select_iter}_{case_name}{local}." + "grdecl", + f"{grid_file_name}", + ] + subprocess.run(command, check=True) + + +if __name__ == "__main__": + # Realisation number selected to be used as reference realisation + SELECT_REAL = 5 + # Use ensemble smoother + SELECT_ITER = 1 + for case_name in ["A", "B", "C", "D", "E", "F", "G", "A2"]: + print(f"Case: {case_name}") + # Make the file example_config.yml to be used in the ERT + # forward model sim_field.py + settings_with_localisation = example_config(case_name, use_localisation=True) + settings_without_localisation = example_config( + case_name, use_localisation=False + ) + + # Initialize the case: + # - create seed file, + # - create grids, + # - simulate one unconditioned realization, + # - calculate response, + # - extract synthetic observations from response, + # - create localisation config file, (local_config.yml) + # - create ert config file (sim_field.ert) + # - prepare region parameter for case using regions + + print("Run without localisation") + run_case( + settings_without_localisation, + select_real=SELECT_REAL, + select_iter=SELECT_ITER, + ) + + print("\nRun with localisation") + run_case( + settings_with_localisation, + select_real=SELECT_REAL, + select_iter=SELECT_ITER, + ) diff --git a/tests/workflows/localisation/example_case/scripts/roff_to_grdecl.py b/tests/workflows/localisation/example_case/scripts/roff_to_grdecl.py new file mode 100755 index 000000000..a79b0e3ee --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/roff_to_grdecl.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +""" +Script converting a grid parameter file from ROFF to GRDECL +""" + +import sys +from pathlib import PurePath + +import xtgeo + + +def main(argv): + """ + Convert a grid parameter file from ROFF to GRDECL + and can also take as input a GRDECL file and write + to another GRDECL file with fixed format + """ + input_file = argv[1] + output_file = argv[2] + grid_file = argv[3] + param_name = "FIELDPAR" + grid_obj = xtgeo.grid_from_file(grid_file, fformat="egrid") + # Check extension to find input format + suffix = PurePath(input_file).suffix + if suffix.upper() == ".ROFF": + print(f"Read file: {input_file} in ROFF format") + field_obj = xtgeo.gridproperty_from_file( + input_file, fformat="roff", name=param_name, grid=grid_obj + ) + field_obj.mask_undef() + print(f"Write file: {output_file} in GRDECL format") + field_obj.to_file(output_file, fformat="grdecl", fmt="%20.6f") + elif suffix.upper() == ".GRDECL": + # Ensure the grdecl file use a fixed format for the values + # to more easily compare it with a reference + print(f"Read file: {input_file} in GRDECL format") + field_obj = xtgeo.gridproperty_from_file( + input_file, fformat="grdecl", name=param_name, grid=grid_obj + ) + field_obj.mask_undef() + print(f"Write file: {output_file} in GRDECL format") + field_obj.to_file(output_file, fformat="grdecl", fmt="%20.6f") + + +if __name__ == "__main__": + args = sys.argv + if len(args) < 4: + print( + "Usage: roff_to_grdecl.py " + " " + ) + else: + main(args) diff --git a/tests/workflows/localisation/example_case/scripts/sim_fields.py b/tests/workflows/localisation/example_case/scripts/sim_fields.py new file mode 100755 index 000000000..dbdf2885b --- /dev/null +++ b/tests/workflows/localisation/example_case/scripts/sim_fields.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +""" +Script used as forward model in ERT to test localisation. +""" +import os +import sys + +# pylint: disable=import-error, redefined-outer-name +# pylint: disable=missing-function-docstring,invalid-name +from common_functions import ( + generate_field_and_upscale, + get_cell_indices, + get_nobs_from_cell_index_list, + read_config_file, + read_field_from_file, + read_obs_field_from_file, + read_observations, + read_upscaled_field_from_file, + upscaling, + write_obs_pred_diff_field, +) + + +def write_prediction_gen_data( + upscaled_values, cell_indx_list: list, response_file_name_prefix: str +): + """ + Write GEN_DATA file with predicted values of observables (selected upscaled values) + """ + print(response_file_name_prefix) + response_file_name = response_file_name_prefix + "_0.txt" + print(f"Write GEN_DATA file with prediction of observations: {response_file_name}") + with open(response_file_name, "w", encoding="utf8") as file: + # NOTE: The sequence of values must be the same as for the observations + nobs = get_nobs_from_cell_index_list(cell_indx_list) + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, cell_indx_list) + value = upscaled_values[Iindx, Jindx, Kindx] + file.write(f"{value}\n") + + +# pylint: disable=too-many-arguments,too-many-locals +def write_obs_and_predictions( + config_path: str, + upscaled_values, + cell_index_list: list, + observation_dir: str, + obs_data_dir: str, + predicted_obs_file_name: str = "obs_and_prediction.txt", +): + obs_values = read_observations( + config_path, observation_dir, obs_data_dir, cell_index_list + ) + nobs = get_nobs_from_cell_index_list(cell_index_list) + filename = config_path + "/" + predicted_obs_file_name + print(f"Write file: {filename}") + with open(predicted_obs_file_name, "w", encoding="utf-8") as file: + file.write(" Cell_index Obs_value Predicted_obs_value Difference\n") + for obs_number in range(nobs): + (Iindx, Jindx, Kindx) = get_cell_indices(obs_number, cell_index_list) + predicted_obs_values = upscaled_values[Iindx, Jindx, Kindx] + obs_value = obs_values[obs_number] + diff_obs_pred = obs_value - predicted_obs_values + file.write( + f"({Iindx+1}, {Jindx+1}, {Kindx + 1}) " + f"{obs_value:10.5f} {predicted_obs_values:10.5f} " + f"{diff_obs_pred:10.5f} \n" + ) + + +def get_iteration_real_number_config_file(argv): + if len(argv) < 4: + raise IOError( + "Missing command line arguments " + ) + arg1 = argv[1] + if arg1 is None: + raise IOError( + "Missing iteration number (argv[1]) when running this script manually" + ) + iteration = int(arg1) + print(f"ERT iteration: {iteration}") + + arg2 = argv[2] + if arg2 is None: + raise IOError("Missing real_number (argv[2]) when running this script manually") + real_number = int(arg2) + print(f"ERT realization: {real_number}") + + config_file_name = argv[3] + + config_path = argv[4] + return iteration, real_number, config_file_name, config_path + + +def main(args): + """ + For iteration = 0: + - simulate field, export to file as initial ensemble realization + - upscale and extract predicted values for observables + (selected coarse grid cell values) + For iteration > 0: + - Import updated field from ERT. + - upscale and extract predicted values for observables + (selected coarse grid cell values) + """ + + # NOTE: Both the fine scale grid with simulated field values + # and the coarse grid with upscaled values must have Eclipse grid index origin + + # Read config_file if it exists. Use default settings for everything not specified. + ( + iteration, + real_number, + config_file_name, + config_path, + ) = get_iteration_real_number_config_file(args) + settings = read_config_file(config_file_name) + + print(f"Config path: {config_path}") + if iteration == 0: + print(f"Generate new field parameter realization:{real_number} ") + # Simulate field (with trend) + upscaled_values = generate_field_and_upscale( + real_number, + iteration, + os.path.join(config_path, settings.field.seed_file), + settings.field.algorithm, + settings.field.name, + settings.field.initial_file_name_prefix, + settings.field.file_format, + settings.field.grid_dimension, + settings.model_size.size, + settings.field.variogram, + settings.field.correlation_range, + settings.field.correlation_azimuth, + settings.field.correlation_dip, + settings.field.correlation_exponent, + settings.field.trend_use, + settings.field.trend_params, + settings.field.trend_relstd, + settings.response.name, + settings.response.response_function, + settings.response.upscaled_file_name, + settings.response.grid_dimension, + settings.response.write_upscaled_field, + settings.model_size.use_eclipse_grid_index_origo, + ) + + else: + print(f"Import updated field parameter realization: {real_number} ") + field_object = read_field_from_file( + settings.field.updated_file_name_prefix, + settings.field.name, + settings.field.file_format, + settings.field.grid_file_name, + ) + field_values = field_object.values + + # Calculate upscaled values for selected coarse grid cells + upscaled_values = upscaling( + field_values, + settings.response.response_function, + settings.response.file_format, + settings.response.name, + settings.response.write_upscaled_field, + settings.response.upscaled_file_name, + settings.response.grid_dimension, + iteration=iteration, + ) + # Write GEN_DATA file + write_prediction_gen_data( + upscaled_values, + settings.observation.selected_grid_cells, + settings.response.gen_data_file_prefix, + ) + + # Optional output calculate difference between upscaled field and + # and reference upscaled field + if settings.optional.write_obs_pred_diff_field_file: + obs_field_object = read_obs_field_from_file( + settings.response.file_format, + os.path.join(config_path, settings.observation.reference_param_file), + settings.response.grid_file_name, + os.path.join(config_path, settings.observation.reference_field_name), + ) + upscaled_field_object = read_upscaled_field_from_file( + iteration, + settings.response.upscaled_file_name, + settings.response.file_format, + settings.response.name, + settings.response.grid_file_name, + ) + write_obs_pred_diff_field( + upscaled_field_object, obs_field_object, settings.field.file_format + ) + + write_obs_and_predictions( + config_path, + upscaled_values, + settings.observation.selected_grid_cells, + settings.observation.directory, + settings.observation.data_dir, + ) + + +if __name__ == "__main__": + # Command line arguments are iteration real_number test_case_config_file + main(sys.argv) diff --git a/tests/workflows/localisation/example_case/test_full.py b/tests/workflows/localisation/example_case/test_full.py new file mode 100644 index 000000000..aa13b3398 --- /dev/null +++ b/tests/workflows/localisation/example_case/test_full.py @@ -0,0 +1,267 @@ +""" +Test of full workflow using non-adaptive localisation +- Gaussian fields are simulated +- Response variables are upscaled values of simulated gaussian fields +- Some selected positions within the upscaled grid are used to extract + synthetic observations. +- Localisation config file is generated. +- Running ERT using the generated localisation file. +- The ERT forward model (simulating and upscaling gaussian fields + is done by the script 'sim_fields.py') +- For iteration > 0, the updated field parameter is imported from ERT + and upscaled. Predictions of observed values are extracted and + saved to ERT using GEN_DATA keyword. +- The final intial and updated ensemble is used when comparing with + reference values for the field. One selected realization is used + when comparing ERT result with reference result. +- The test depends on test example configurations saved in yml file. + Parameters in this test example configuration is modified by the test functions. +- Reference case realisations are created previously and are data checked + into git as ascii grdecl files. +- Any changes in test example configuration may require a separate file for + the reference file in GRDECL format. +- The reference case when replaced must be visualized ot QC the reference. +""" +import shutil +from argparse import ArgumentParser +from pathlib import Path +from typing import Any, Dict + +import numpy as np +import pytest +import xtgeo +import yaml +from ert import LibresFacade +from ert.__main__ import ert_parser +from ert.cli import ENSEMBLE_SMOOTHER_MODE +from ert.cli.main import run_cli +from ert.shared.plugins.plugin_manager import ErtPluginContext +from ert.storage import open_storage + +from scripts.common_functions import ( + Settings, + initialize_case, + example_cases, +) + +# pylint: disable=invalid-name +# pylint: disable=too-many-locals +# pylint: disable=too-many-arguments +# pylint: disable=missing-function-docstring +# pylint: disable=too-many-statements + + +@pytest.mark.parametrize( + "new_settings", + [ + pytest.param(example_cases("A")), + pytest.param(example_cases("B")), + pytest.param(example_cases("C")), + pytest.param(example_cases("A2")), + pytest.param(example_cases("D")), + pytest.param(example_cases("E")), + pytest.param(example_cases("F")), + pytest.param(example_cases("G")), + ], +) +# pylint: disable=too-many-branches +def test_that_localization_works_with_different_settings( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, new_settings: Dict[str, Any] +): + monkeypatch.chdir(tmp_path) + print(f"Setup test case on tmp_path: {tmp_path}") + settings = Settings() + settings.reset_to_default() + settings.update(new_settings) + + # Write yml file for the sim_fields.py script + main_settings_dict = settings.to_dict() + with open("example_config.yml", "w", encoding="utf-8") as file: + file.write( + yaml.safe_dump(main_settings_dict, indent=4, default_flow_style=False) + ) + + (tmp_path / "init_files").mkdir() + (tmp_path / "reference_files").mkdir() + + # Make available data to generate grid, region parameters and scaling factor + polygon_file = None + if settings.case_name == "A2": + polygon_file = "init_files/polygons.txt" + shutil.copy( + Path(__file__).parent / settings.model_size.polygon_file, + polygon_file, + ) + + if settings.case_name == "E": + region_polygon_file = "init_files/region_polygons.txt" + shutil.copy( + Path(__file__).parent / settings.localisation.region_polygons, + region_polygon_file, + ) + + if settings.case_name == "F": + scaling_factor_param_file = "init_files/scaling_factor.grdecl" + shutil.copy( + Path(__file__).parent / settings.localisation.scaling_file, + scaling_factor_param_file, + ) + + if settings.case_name == "G": + scaling_factor_param_file = "init_files/scaling_factor_rms_origo.grdecl" + shutil.copy( + Path(__file__).parent / settings.localisation.scaling_file, + scaling_factor_param_file, + ) + + # Make ERT template file available + ert_config_template_file = "init_files/sim_field_template.ert" + shutil.copy( + Path(__file__).parent / settings.response.ert_config_template_file, + ert_config_template_file, + ) + + initialize_case(settings) + + parser = ArgumentParser(prog="test_main") + if settings.case_name == "A": + reference_file_initial = "FieldParam_real5_iter0_A_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_A_local.grdecl" + grid_file_name = "GRID_STANDARD.EGRID" + elif settings.case_name == "B": + reference_file_initial = "FieldParam_real5_iter0_A_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_A_local.grdecl" + grid_file_name = "GRID_STANDARD.EGRID" + elif settings.case_name == "C": + reference_file_initial = "FieldParam_real5_iter0_C_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_C_local.grdecl" + grid_file_name = "GRID_RMS_ORIGO.EGRID" + elif settings.case_name == "A2": + reference_file_initial = "FieldParam_real5_iter0_A2_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_A2_local.grdecl" + grid_file_name = "GRID_WITH_ACTNUM.EGRID" + elif settings.case_name == "D": + # Scaling factor =1 and one correlation group + # The result should be identical to not running localisation like + # case A without localisation + reference_file_initial = "FieldParam_real5_iter0_D.grdecl" + reference_file_updated = "FieldParam_real5_iter1_D.grdecl" + grid_file_name = "GRID_STANDARD.EGRID" + elif settings.case_name == "E": + reference_file_initial = "FieldParam_real5_iter0_E_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_E_local.grdecl" + grid_file_name = "GRID_STANDARD.EGRID" + elif settings.case_name == "F": + reference_file_initial = "FieldParam_real5_iter0_F_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_F_local.grdecl" + grid_file_name = "GRID_STANDARD.EGRID" + elif settings.case_name == "G": + reference_file_initial = "FieldParam_real5_iter0_G_local.grdecl" + reference_file_updated = "FieldParam_real5_iter1_G_local.grdecl" + grid_file_name = "GRID_RMS_ORIGO.EGRID" + + reference_path_initial = "reference_files/" + reference_file_initial + reference_path_updated = "reference_files/" + reference_file_updated + shutil.copy( + Path(__file__).parent / "init_files" / reference_file_initial, + reference_path_initial, + ) + shutil.copy( + Path(__file__).parent / "init_files" / reference_file_updated, + reference_path_updated, + ) + shutil.copy(Path(__file__).parent / "localisation.wf", "localisation.wf") + Path("scripts").mkdir(parents=True, exist_ok=True) + shutil.copy( + Path(__file__).parent / "scripts" / "FM_SIM_FIELD", "scripts/FM_SIM_FIELD" + ) + shutil.copy( + Path(__file__).parent / "scripts" / "sim_fields.py", "scripts/sim_fields.py" + ) + shutil.copy( + Path(__file__).parent / "scripts" / "common_functions.py", + "scripts/common_functions.py", + ) + ert_config_file = settings.response.ert_config_file + parsed = ert_parser( + parser, + [ + ENSEMBLE_SMOOTHER_MODE, + "--current-case", + "es_prior", + "--target-case", + "es_posterior", + ert_config_file, + ], + ) + with ErtPluginContext() as _: + run_cli(parsed) + + facade = LibresFacade.from_config_file(ert_config_file) + + grid_file = xtgeo.grid_from_file(grid_file_name, fformat="egrid") + es_prior_expected = xtgeo.gridproperty_from_file( + reference_path_initial, + fformat="grdecl", + name="FIELDPAR", + grid=grid_file, + ) + es_prior_expected.mask_undef() + es_posterior_expected = xtgeo.gridproperty_from_file( + reference_path_updated, + fformat="grdecl", + name="FIELDPAR", + grid=grid_file, + ) + es_posterior_expected.mask_undef() + dims = es_prior_expected.dimensions + with open_storage(facade.enspath) as storage: + realization = 5 + es_prior = storage.get_ensemble_by_name("es_prior") + es_prior_xdata = es_prior.load_parameters("FIELDPAR").sel( + realizations=realization + ) + es_prior_values_from_storage = es_prior_xdata["values"].values + + es_posterior = storage.get_ensemble_by_name("es_posterior") + es_posterior_xdata = es_posterior.load_parameters("FIELDPAR").sel( + realizations=realization + ) + es_posterior_values_from_storage = es_posterior_xdata["values"].values + + # Write to file for easier QC of differences + es_prior_from_storage = xtgeo.GridProperty( + ncol=dims[0], + nrow=dims[1], + nlay=dims[2], + name="prior_storage", + values=es_prior_values_from_storage, + ) + es_prior_from_storage.mask_undef() + es_prior_from_storage.to_file("prior_storage.roff", fformat="roff") + + # Write to file for easier QC of differences + es_posterior_from_storage = xtgeo.GridProperty( + ncol=dims[0], + nrow=dims[1], + nlay=dims[2], + name="posterior_storage", + values=es_posterior_values_from_storage, + ) + es_posterior_from_storage.mask_undef() + es_posterior_from_storage.to_file("posterior_storage.roff", fformat="roff") + + # Check with reference + assert np.allclose( + es_prior_expected.values3d, + np.round(es_prior_values_from_storage, 4), + atol=1e-4, + equal_nan=True, + ) + + assert np.allclose( + es_posterior_expected.values3d, + np.round(es_posterior_values_from_storage, 4), + atol=1e-4, + equal_nan=True, + )