Skip to content

Commit

Permalink
Improvements and additional examples for generic decks
Browse files Browse the repository at this point in the history
daavid00 committed Sep 12, 2024
1 parent cab9cff commit aae2c80
Showing 36 changed files with 896 additions and 318 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -163,8 +163,8 @@ cython_debug/
.DS_Store

# Tests
tests/configs/ert/
tests/generic_deck
tests/configs/ert
tests/decks/coarser
tests/configs/ert
tests/configs/jobs
tests/configs/logs
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
[![Code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![DOI](https://zenodo.org/badge/815649176.svg)](https://zenodo.org/doi/10.5281/zenodo.12740838)
<img src="docs/text/figs/pycopm.gif" width="900" height="200">
<img src="docs/text/figs/pycopm.gif" width="900" height="300">

# pycopm: An open-source coarsening framework for OPM Flow geological models

@@ -52,6 +52,11 @@ Run `pycopm --help` to see all possible command line argument options.
## Getting started
See the [_examples_](https://cssr-tools.github.io/pycopm/examples.html) in the [_documentation_](https://cssr-tools.github.io/pycopm/introduction.html).

## Publications
The following is a list of manuscripts in which _pycopm_ is used:

1. Sandve, T.H., Lorentzen, R.J., Landa-Marbán, D., Fossum, K., 2024. Closed-loop reservoir management using fast data-calibrated coarse models. European Association of Geoscientists & Engineers, ECMOR 2024, Volume 202, ISSN 2214-4609. https://doi.org/10.3997/2214-4609.202437071.

## About pycopm
The _pycopm_ package is being funded by the [_Center for Sustainable Subsurface Resources (CSSR)_](https://cssr.no)
[project no. 331841].
Binary file added docs/_images/hello_world_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_images/hello_world_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_images/norne_vec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/_images/output_generic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/_images/smeia.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/_sources/configuration_file.rst.txt
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ Configuration file
only for the drogon and norne model. To use **pycopm** in any given OPM Flow geological model
to generate the coarser files, this can be achieve without a configuration file, but setting
the parameters via command lines (see the :ref:`overview` or run `pycopm -h` for the definition
of the argument options, and the :doc:`examples <./examples>`.)
of the argument options, as well as the examples in :ref:`generic`.)


Here we use as an example one of the configuration files used in the tests
89 changes: 64 additions & 25 deletions docs/_sources/examples.rst.txt
Original file line number Diff line number Diff line change
@@ -6,11 +6,8 @@ Examples
Via configuration files
=======================

Drogon
------

The `examples <https://github.com/cssr-tools/pycopm/blob/main/examples>`_ folder contains configuration files
to perform HM studies in drogon and norne. For example, by executing inside the `example folder for drogon <https://github.com/cssr-tools/pycopm/blob/main/examples/drogon>`_:
to perform HM studies in drogon and norne using `ERT <https://ert.readthedocs.io/en/latest/>`_. For example, by executing inside the `example folder for drogon <https://github.com/cssr-tools/pycopm/blob/main/examples/drogon>`_:

.. code-block:: bash
@@ -20,17 +17,50 @@ The following are the drogon model from `opm-tests <https://github.com/OPM/opm-t

.. figure:: figs/drogon_coarser.png

For norne:

.. code-block:: bash
pycopm -i input.txt -o norne_coarser
The norne GIF in the :doc:`introduction <./introduction>` was generated using the generated coarse model.

.. _generic:

==================
Via OPM Flow decks
==================

The current development of **pycopm** focuses on only creating coarser models (i.e., all needed input files to run OPM Flow) by using the input deck.

Hello world
-----------
For the `HELLO_WORLD.DATA <https://github.com/cssr-tools/pycopm/blob/main/tests/decks/HELLO_WORLD.DATA>`_ deck, by executing:

.. code-block:: bash
pycopm -i HELLO_WORLD.DATA -c 5,1,5 -m all
This would generated the following:

.. figure:: figs/hello_world_1.png

Dry run from the input cloned deck (left) and (right) coarsed model. Adding the flag -p 1 adds the remove pore volume to the neighbouring cells.

To make active the coarse cell where there is only one active cell, this can be achieve by:

.. code-block:: bash
pycopm -i HELLO_WORLD.DATA -c 5,1,5 -m all -a max
.. figure:: figs/hello_world_2.png

Dry run from the input cloned deck (left) and (right) coarsed model. The region numbers by default are given by the mode, e.g., use the flag -n max to keep the maximum integer.

SPE10
-----

See/run the `test_generic_deck.py <https://github.com/cssr-tools/pycopm/blob/main/tests/test_generic_deck.py>`_
for an example where **pycopm** is used to coarse the
`SPE10_MODEL2 model <https://github.com/OPM/opm-data/tree/master/spe10model2>`_ by downloading the OPM files and running:
By downloading the `SPE10_MODEL2 model <https://github.com/OPM/opm-data/tree/master/spe10model2>`_, then:

.. code-block:: bash
@@ -48,26 +78,20 @@ then:

.. code-block:: bash
pycopm -i Statoil_Feasibility_sim_model_with_depletion_KROSS_INJ_SECTOR_20.DATA -o . -c 5,4,3 -a mode
will generate a coarser model 5 times in the x direction, 4 in the y direction, and 3 in the z direction, where the mode is
used to decide if a coarser cell should be active or inactive.
pycopm -i Statoil_Feasibility_sim_model_with_depletion_KROSS_INJ_SECTOR_20.DATA -o . -c 5,4,3 -a min -m all
We can execute a dry run of OPM Flow to generate the grid and static variables of the coarser model:

.. code-block:: bash
flow STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM.DATA --enable-dry-run=true
will generate a coarser model 5 times in the x direction, 4 in the y direction, and 3 in the z direction, where the coarse cell is
made inactive if at least one cell is inactive (-a min).

We use our `plopm <https://github.com/cssr-tools/plopm>`_ friend to generate PNG figures:

.. code-block:: bash
plopm -i STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM -s ,,0
plopm -i ' STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PREP_PYCOPM_DRYRUN STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM' -s ,,0 -v poro -subfigs 1,2 -save smeaheia -t 'Smeaheia Coarsed smeaheia' -xunits km -xformat .0f -yunits km -yformat .0f -d 5,5.2 -suptitle 0 -c cet_rainbow_bgyrm_35_85_c69 -cbsfax 0.30,0.01,0.4,0.02 -cformat .2f
.. figure:: figs/smeia.png

Porosity values for the (left) original and (right) coarsed model.
Top view of porosity values for the (left) original and (right) coarsed model (note that we also coarse on the z direction).

.. tip::
You can install plopm by executing in the terminal: pip install git+https://github.com/cssr-tools/plopm.git.
@@ -77,16 +101,16 @@ We use our `plopm <https://github.com/cssr-tools/plopm>`_ friend to generate PNG
(e.g., FAULTS, WELLSPECS) are assumed to be define in the main .DATA deck. Then, in order to use **pycopm** for simulation models
where these properties are define via include files, replace those includes in the .DATA deck with the actual content of the include files.

Generic Drogon
--------------
Drogon
------
Following the note above, then by downloading the `DROGON model <https://github.com/OPM/opm-tests/tree/master/drogon>`_, replacing the lines in
`DROGON_HIST.DATA <https://github.com/OPM/opm-tests/blob/master/drogon/model/DROGON_HIST.DATA>`_ for the FAULTS (L127-128) and SCHEDULE (L242-243) with
the actual content of those include files, then by executing:

.. code-block:: bash
pycopm -i DROGON_HIST.DATA -o . -c 1,1,3 -a min -n max -p 1
pycopm -i DROGON_HIST_PYCOPM.DATA -o . -c 1,3,1 -a mode -n mode -p 1 -j 1.9
pycopm -i DROGON_HIST.DATA -c 1,1,3 -p 1
pycopm -i DROGON_HIST_PYCOPM.DATA -c 1,3,1 -p 1 -j 2.5
this would generate the following coarse model:

@@ -95,8 +119,23 @@ this would generate the following coarse model:
Note that the total pore volume is conserved for the coarse model.

Here, we first coarse in the z direction, which reduces the number of cells from 31 to 11, and after we coarse in the y direction.
After trial and error, the jump (-j) is set to 1.9 to avoid generated connections across the faults.
After trial and error, the jump (-j) is set to 2.5 to avoid generated connections across the faults. For geological models with a lot of
inactive cells and faults, this divide and conquer apporach is recommended, i.e., coarsening first in the z directon and after coarsening
in the x and y directions.

.. note::
After genereting the first coarser deck (DROGON_HIST_PYCOPM.DATA), change the path '../include/props/drogon.swatinit' to 'SWATINIT.INC',
which contains the right number of values for the coarse model.
Add to the generated coarse deck the missing include files in the grid section related to the region operations (e.g.,
../include/grid/drogon.multregt for this case).

Norne
-----
By downloading the `Norne model <https://github.com/OPM/opm-tests/tree/master/norne>`_ (and replacing the needed include files as described in the previous
example), then here we create a coarser model by removing certain pilars in order to keep the main features of the geological model:

.. code-block:: bash
pycopm -i NORNE_ATW2013.DATA -x 0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,2,0,2,2,2,2,0 -y 0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,2,2,2,2,2,2,2,2,0 -z 0,0,2,0,0,2,2,2,2,2,02,2,2,2,2,0,0,2,0,2,2,0,0,0,0,0,0,0,0,0,0 -a min -p 1
this would generate the following coarse model:

.. figure:: figs/norne_vec.png
34 changes: 19 additions & 15 deletions docs/_sources/introduction.rst.txt
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ Simplified and flexible framework to create coarser OPM Flow geological models.

Roadmap
-------
In the initial development of the framework, the focus was two available models in `opm-tests <https://github.com/OPM/opm-tests>`_: `norne <https://github.com/OPM/opm-tests/tree/master/norne>`_
and `drogon <https://github.com/OPM/opm-tests/tree/master/drogon>`_, where the coarser models are used to perform history matching studies using
In the initial development of the framework, the focus were two available models in `opm-tests <https://github.com/OPM/opm-tests>`_: `norne <https://github.com/OPM/opm-tests/tree/master/norne>`_
and `drogon <https://github.com/OPM/opm-tests/tree/master/drogon>`_, where the coarser models were used to perform history matching studies using
the Ensemble based reservoir tool `ERT <https://ert.readthedocs.io/en/latest/>`_, via a :doc:`configuration file <./configuration_file>`.

The current development of **pycopm** focuses on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files
@@ -32,16 +32,20 @@ The current implementation supports the following executable with the argument o
where

-i The base name of the :doc:`configuration file <./configuration_file>` or the name of the deck, e.g., `DROGON.DATA`, (`input.txt` by default).
-o The base name of the :doc:`output folder <./output_folder>` ('.'' by default, i.e., the folder where pycopm is executed).
-f OPM Flow full path to executable or just `flow` (`flow` by default).
-c Level of coarsening in the x, y, and z dir (`2,2,2` by default).
-a Use `min`, `max`, or `mode` to scale the actnum, e.g., min makes the new coarser cell inactive it at least one cell is inactive, while max makes it active it at least one cell is active (`max` by default).
-j Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults ('' by default, i.e., nothing corrected; if need it, try with values of the order of 1).
-x Vector of x-coarsening, e.g., if the grid has 6 cells in the x direction, then `0,2,0,2,0,2,0` would generate a coarser model with 3 cells, while `0,2,2,2,2,2,0` would generate a coarser model with 1 cell, i.e., 0 keeps the pilars while 2 removes them ('' by default),
-y Vector of y-coarsening, see the description for -x ('' by default).
-z Vector of z-coarsening, see the description for -x ('' by default).
-e Use `utf8` or `ISO-8859-1` encoding to read the deck (`ISO-8859-1` by default).
-p Add the removed pore volume to the closest coarser cells (`0` by default, `1` to enable).
-n Use `min`, `max`, or `mode` to scale satnum, fipnum, pvtnum, eqlnum, imbnum, and multnum (`mode` by default).
-s Use `min`, `max`, or `mean` to scale permx, permy, permz, and poro ('' by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the porosity).
-i The base name of the :doc:`configuration file <./configuration_file>` or the name of the deck, e.g., `DROGON.DATA`, (`input.txt` by default).
-o The base name of the :doc:`output folder <./output_folder>` ('.'' by default, i.e., the folder where pycopm is executed).
-f OPM Flow full path to executable or just `flow` (`flow` by default).
-c Level of coarsening in the x, y, and z dir (`2,2,2` by default; either use this flag or the -x, -y, and -z ones).
-x Vector of x-coarsening, e.g., if the grid has 6 cells in the x direction, then `0,2,0,2,0,2,0` would generate a coarser model with 3 cells, while `0,2,2,2,2,2,0` would generate a coarser model with 1 cell, i.e., 0 keeps the pilars while 2 removes them ('' by default),
-y Vector of y-coarsening, see the description for -x ('' by default).
-z Vector of z-coarsening, see the description for -x ('' by default).
-a Use `min`, `max`, or `mode` to scale the actnum, e.g., min makes the new coarser cell inactive if at least one cell is inactive, while max makes it active it at least one cell is active (`mode` by default).
-n Use `min`, `max`, or `mode` to scale endnum, eqlnum, fipnum, fluxnum, imbnum, miscnum, multnum, pvtnum, rocknum, and satnum (`mode` by default).
-s Use `min`, `max`, or `mean` to scale permx, permy, permz, poro, swatinit, and all mult(-)xyz ('' by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the rest).
-p Add the removed pore volume to the closest coarser cells (`0` by default, `1` to enable).
-j Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults ('' by default, i.e., nothing corrected; if need it, try with values of the order of 1).
-m Execute a dry run on the input deck to generate the static properties ('prep'), generate only the coarse files ('deck'), only exectute a dry run on the generated coarse model ('dry'), 'prep_deck', 'deck_dry', or do all ('all') (`prep_deck` by default).
-w Name of the generated deck ('' by default, i.e., the name of the input deck plus _PYCOPM.DATA).
-l Added text before each generated .INC (`PYCOPM_` by default, i.e., the coarse porv is saved in PYCOPM_PORV.INC; set to '' to generate PORV.INC, PERMX.INC, etc).
-e Use `utf8` or `ISO-8859-1` encoding to read the deck (`ISO-8859-1` by default).
-ijk Given i,j,k indices in the input model, return the coarse i,j,k corresponding positions ('' by default; if not empty, e.g., 1,2,3 then the -m is set to deck and there will not be generation of coarse files, only the i,j,k coarse indices in the terminal).
10 changes: 8 additions & 2 deletions docs/_sources/output_folder.rst.txt
Original file line number Diff line number Diff line change
@@ -21,12 +21,18 @@ are generated in the postprocessing folder. The OPM simulation results can be vi

Via an OPM Flow input deck
--------------------------
The current development of **pycopm** focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files.
The current development of **pycopm** focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by using the input deck.

The following screenshot shows the input deck and generated files in the selected output folder (coarser for this example) after executing **pycopm** on the SPE10 model (see the
`test_generic_deck.py <https://github.com/cssr-tools/pycopm/blob/main/tests/test_generic_deck.py>`_) file.

.. figure:: figs/output_generic.png

Then, after running **pycopm**, one could adapt the generated files with the coarser geological model in your
favourite history matching/optimization tool (e.g., `ERT <https://ert.readthedocs.io/en/latest/>`_, `PET <https://python-ensemble-toolbox.github.io/PET/>`_, `everest <https://github.com/equinor/everest>`_).
favourite history matching/optimization tool (e.g., `ERT <https://ert.readthedocs.io/en/latest/>`_, `PET <https://python-ensemble-toolbox.github.io/PET/>`_, `everest <https://github.com/equinor/everest>`_).

.. Note::
For input decks that include other files without giving the full path (e.g., './include/summary...'), then we recommend
to use the default output folder (-o .), i.e., the generated deck and coarse files would be generated in the same location as
the input deck and no errors would appear for not finding the include files; otherwise, you might need to copy all needed folders
with the include files to the output folder or setting the correct path to the include files in the generated coarse deck.
2 changes: 1 addition & 1 deletion docs/configuration_file.html
Original file line number Diff line number Diff line change
@@ -89,7 +89,7 @@ <h1>Configuration file<a class="headerlink" href="#configuration-file" title="Li
only for the drogon and norne model. To use <strong>pycopm</strong> in any given OPM Flow geological model
to generate the coarser files, this can be achieve without a configuration file, but setting
the parameters via command lines (see the <a class="reference internal" href="introduction.html#overview"><span class="std std-ref">Overview</span></a> or run <cite>pycopm -h</cite> for the definition
of the argument options, and the <a class="reference internal" href="examples.html"><span class="doc">examples</span></a>.)</p>
of the argument options, as well as the examples in <a class="reference internal" href="examples.html#generic"><span class="std std-ref">Via OPM Flow decks</span></a>.)</p>
</div>
<p>Here we use as an example one of the configuration files used in the tests
(see <a class="reference external" href="https://github.com/crrs-tools/pycopm/blob/main/tests/configs/ert.txt">ert.txt</a>).
102 changes: 68 additions & 34 deletions docs/examples.html

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions docs/genindex.html
Original file line number Diff line number Diff line change
@@ -180,13 +180,17 @@ <h2 id="H">H</h2>
</li>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_fault">handle_fault() (in module pycopm.utils.generate_coarser_files)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="pycopm.utils.grid_builder.html#pycopm.utils.grid_builder.handle_faults">handle_faults() (in module pycopm.utils.grid_builder)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_grid_props">handle_grid_props() (in module pycopm.utils.generate_coarser_files)</a>
</li>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_mapaxes">handle_mapaxes() (in module pycopm.utils.generate_coarser_files)</a>
</li>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_oper">handle_oper() (in module pycopm.utils.generate_coarser_files)</a>
</li>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_props">handle_props() (in module pycopm.utils.generate_coarser_files)</a>
</li>
<li><a href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_pv">handle_pv() (in module pycopm.utils.generate_coarser_files)</a>
</li>
9 changes: 4 additions & 5 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -101,14 +101,13 @@ <h1>Welcome to pycopm’s documentation!<a class="headerlink" href="#welcome-to-
</li>
<li class="toctree-l1"><a class="reference internal" href="configuration_file.html">Configuration file</a></li>
<li class="toctree-l1"><a class="reference internal" href="examples.html">Examples</a><ul>
<li class="toctree-l2"><a class="reference internal" href="examples.html#via-configuration-files">Via configuration files</a><ul>
<li class="toctree-l3"><a class="reference internal" href="examples.html#drogon">Drogon</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="examples.html#via-configuration-files">Via configuration files</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples.html#via-opm-flow-decks">Via OPM Flow decks</a><ul>
<li class="toctree-l3"><a class="reference internal" href="examples.html#hello-world">Hello world</a></li>
<li class="toctree-l3"><a class="reference internal" href="examples.html#spe10">SPE10</a></li>
<li class="toctree-l3"><a class="reference internal" href="examples.html#smeaheia">Smeaheia</a></li>
<li class="toctree-l3"><a class="reference internal" href="examples.html#generic-drogon">Generic Drogon</a></li>
<li class="toctree-l3"><a class="reference internal" href="examples.html#drogon">Drogon</a></li>
<li class="toctree-l3"><a class="reference internal" href="examples.html#norne">Norne</a></li>
</ul>
</li>
</ul>
42 changes: 27 additions & 15 deletions docs/introduction.html
Original file line number Diff line number Diff line change
@@ -96,8 +96,8 @@ <h2>Concept<a class="headerlink" href="#concept" title="Link to this heading">
</section>
<section id="roadmap">
<h2>Roadmap<a class="headerlink" href="#roadmap" title="Link to this heading"></a></h2>
<p>In the initial development of the framework, the focus was two available models in <a class="reference external" href="https://github.com/OPM/opm-tests">opm-tests</a>: <a class="reference external" href="https://github.com/OPM/opm-tests/tree/master/norne">norne</a>
and <a class="reference external" href="https://github.com/OPM/opm-tests/tree/master/drogon">drogon</a>, where the coarser models are used to perform history matching studies using
<p>In the initial development of the framework, the focus were two available models in <a class="reference external" href="https://github.com/OPM/opm-tests">opm-tests</a>: <a class="reference external" href="https://github.com/OPM/opm-tests/tree/master/norne">norne</a>
and <a class="reference external" href="https://github.com/OPM/opm-tests/tree/master/drogon">drogon</a>, where the coarser models were used to perform history matching studies using
the Ensemble based reservoir tool <a class="reference external" href="https://ert.readthedocs.io/en/latest/">ERT</a>, via a <a class="reference internal" href="configuration_file.html"><span class="doc">configuration file</span></a>.</p>
<p>The current development of <strong>pycopm</strong> focuses on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files
(i.e., avoiding the manual work to create templates as it was done for drogon and norne). This allows for flexibility to adapt the generated coarser decks in your
@@ -121,13 +121,7 @@ <h2>Roadmap<a class="headerlink" href="#roadmap" title="Link to this heading">
<dd><p>OPM Flow full path to executable or just <cite>flow</cite> (<cite>flow</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-c</span></kbd></dt>
<dd><p>Level of coarsening in the x, y, and z dir (<cite>2,2,2</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-a</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mode</cite> to scale the actnum, e.g., min makes the new coarser cell inactive it at least one cell is inactive, while max makes it active it at least one cell is active (<cite>max</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-j</span></kbd></dt>
<dd><p>Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults (’’ by default, i.e., nothing corrected; if need it, try with values of the order of 1).</p>
<dd><p>Level of coarsening in the x, y, and z dir (<cite>2,2,2</cite> by default; either use this flag or the -x, -y, and -z ones).</p>
</dd>
<dt><kbd><span class="option">-x</span></kbd></dt>
<dd><p>Vector of x-coarsening, e.g., if the grid has 6 cells in the x direction, then <cite>0,2,0,2,0,2,0</cite> would generate a coarser model with 3 cells, while <cite>0,2,2,2,2,2,0</cite> would generate a coarser model with 1 cell, i.e., 0 keeps the pilars while 2 removes them (’’ by default),</p>
@@ -138,17 +132,35 @@ <h2>Roadmap<a class="headerlink" href="#roadmap" title="Link to this heading">
<dt><kbd><span class="option">-z</span></kbd></dt>
<dd><p>Vector of z-coarsening, see the description for -x (’’ by default).</p>
</dd>
<dt><kbd><span class="option">-e</span></kbd></dt>
<dd><p>Use <cite>utf8</cite> or <cite>ISO-8859-1</cite> encoding to read the deck (<cite>ISO-8859-1</cite> by default).</p>
<dt><kbd><span class="option">-a</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mode</cite> to scale the actnum, e.g., min makes the new coarser cell inactive if at least one cell is inactive, while max makes it active it at least one cell is active (<cite>mode</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-n</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mode</cite> to scale endnum, eqlnum, fipnum, fluxnum, imbnum, miscnum, multnum, pvtnum, rocknum, and satnum (<cite>mode</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-s</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mean</cite> to scale permx, permy, permz, poro, swatinit, and all mult(-)xyz (’’ by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the rest).</p>
</dd>
<dt><kbd><span class="option">-p</span></kbd></dt>
<dd><p>Add the removed pore volume to the closest coarser cells (<cite>0</cite> by default, <cite>1</cite> to enable).</p>
</dd>
<dt><kbd><span class="option">-n</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mode</cite> to scale satnum, fipnum, pvtnum, eqlnum, imbnum, and multnum (<cite>mode</cite> by default).</p>
<dt><kbd><span class="option">-j</span></kbd></dt>
<dd><p>Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults (’’ by default, i.e., nothing corrected; if need it, try with values of the order of 1).</p>
</dd>
<dt><kbd><span class="option">-s</span></kbd></dt>
<dd><p>Use <cite>min</cite>, <cite>max</cite>, or <cite>mean</cite> to scale permx, permy, permz, and poro (’’ by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the porosity).</p>
<dt><kbd><span class="option">-m</span></kbd></dt>
<dd><p>Execute a dry run on the input deck to generate the static properties (‘prep’), generate only the coarse files (‘deck’), only exectute a dry run on the generated coarse model (‘dry’), ‘prep_deck’, ‘deck_dry’, or do all (‘all’) (<cite>prep_deck</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-w</span></kbd></dt>
<dd><p>Name of the generated deck (’’ by default, i.e., the name of the input deck plus _PYCOPM.DATA).</p>
</dd>
<dt><kbd><span class="option">-l</span></kbd></dt>
<dd><p>Added text before each generated .INC (<cite>PYCOPM_</cite> by default, i.e., the coarse porv is saved in PYCOPM_PORV.INC; set to ‘’ to generate PORV.INC, PERMX.INC, etc).</p>
</dd>
<dt><kbd><span class="option">-e</span></kbd></dt>
<dd><p>Use <cite>utf8</cite> or <cite>ISO-8859-1</cite> encoding to read the deck (<cite>ISO-8859-1</cite> by default).</p>
</dd>
<dt><kbd><span class="option">-i<var>jk</var></span></kbd></dt>
<dd><p>Given i,j,k indices in the input model, return the coarse i,j,k corresponding positions (’’ by default; if not empty, e.g., 1,2,3 then the -m is set to deck and there will not be generation of coarse files, only the i,j,k coarse indices in the terminal).</p>
</dd>
</dl>
</section>
Binary file modified docs/objects.inv
Binary file not shown.
9 changes: 8 additions & 1 deletion docs/output_folder.html
Original file line number Diff line number Diff line change
@@ -106,14 +106,21 @@ <h2>Via configuration files<a class="headerlink" href="#via-configuration-files"
</section>
<section id="via-an-opm-flow-input-deck">
<h2>Via an OPM Flow input deck<a class="headerlink" href="#via-an-opm-flow-input-deck" title="Link to this heading"></a></h2>
<p>The current development of <strong>pycopm</strong> focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files.</p>
<p>The current development of <strong>pycopm</strong> focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by using the input deck.</p>
<p>The following screenshot shows the input deck and generated files in the selected output folder (coarser for this example) after executing <strong>pycopm</strong> on the SPE10 model (see the
<a class="reference external" href="https://github.com/cssr-tools/pycopm/blob/main/tests/test_generic_deck.py">test_generic_deck.py</a>) file.</p>
<figure class="align-default">
<img alt="_images/output_generic.png" src="_images/output_generic.png" />
</figure>
<p>Then, after running <strong>pycopm</strong>, one could adapt the generated files with the coarser geological model in your
favourite history matching/optimization tool (e.g., <a class="reference external" href="https://ert.readthedocs.io/en/latest/">ERT</a>, <a class="reference external" href="https://python-ensemble-toolbox.github.io/PET/">PET</a>, <a class="reference external" href="https://github.com/equinor/everest">everest</a>).</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>For input decks that include other files without giving the full path (e.g., ‘./include/summary…’), then we recommend
to use the default output folder (-o .), i.e., the generated deck and coarse files would be generated in the same location as
the input deck and no errors would appear for not finding the include files; otherwise, you might need to copy all needed folders
with the include files to the output folder or setting the correct path to the include files in the generated coarse deck.</p>
</div>
</section>
</section>

2 changes: 2 additions & 0 deletions docs/pycopm.html
Original file line number Diff line number Diff line change
@@ -120,6 +120,8 @@ <h2>Subpackages<a class="headerlink" href="#subpackages" title="Link to this hea
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_fault"><code class="docutils literal notranslate"><span class="pre">handle_fault()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_grid_props"><code class="docutils literal notranslate"><span class="pre">handle_grid_props()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_mapaxes"><code class="docutils literal notranslate"><span class="pre">handle_mapaxes()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_oper"><code class="docutils literal notranslate"><span class="pre">handle_oper()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_props"><code class="docutils literal notranslate"><span class="pre">handle_props()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_pv"><code class="docutils literal notranslate"><span class="pre">handle_pv()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_regions"><code class="docutils literal notranslate"><span class="pre">handle_regions()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_segmented_wells"><code class="docutils literal notranslate"><span class="pre">handle_segmented_wells()</span></code></a></li>
26 changes: 26 additions & 0 deletions docs/pycopm.utils.generate_coarser_files.html
Original file line number Diff line number Diff line change
@@ -192,6 +192,32 @@
</dl>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="pycopm.utils.generate_coarser_files.handle_oper">
<span class="sig-prename descclassname"><span class="pre">pycopm.utils.generate_coarser_files.</span></span><span class="sig-name descname"><span class="pre">handle_oper</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dic</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">nrwo</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pycopm.utils.generate_coarser_files.handle_oper" title="Link to this definition"></a></dt>
<dd><p>We also support operations</p>
<dl>
<dt>Args:</dt><dd><p>dic (dict): Global dictionary</p>
<p>nrwo (list): Splited row from the input deck</p>
</dd>
<dt>Returns:</dt><dd><p>dic (dict): Modified global dictionary</p>
</dd>
</dl>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="pycopm.utils.generate_coarser_files.handle_props">
<span class="sig-prename descclassname"><span class="pre">pycopm.utils.generate_coarser_files.</span></span><span class="sig-name descname"><span class="pre">handle_props</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dic</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">nrwo</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pycopm.utils.generate_coarser_files.handle_props" title="Link to this definition"></a></dt>
<dd><p>Handle the props sections</p>
<dl>
<dt>Args:</dt><dd><p>dic (dict): Global dictionary</p>
<p>nrwo (list): Splited row from the input deck</p>
</dd>
<dt>Returns:</dt><dd><p>dic (dict): Modified global dictionary</p>
</dd>
</dl>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="pycopm.utils.generate_coarser_files.handle_pv">
<span class="sig-prename descclassname"><span class="pre">pycopm.utils.generate_coarser_files.</span></span><span class="sig-name descname"><span class="pre">handle_pv</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dic</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">clusmin</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">clusmax</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rmv</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pycopm.utils.generate_coarser_files.handle_pv" title="Link to this definition"></a></dt>
2 changes: 2 additions & 0 deletions docs/pycopm.utils.html
Original file line number Diff line number Diff line change
@@ -106,6 +106,8 @@ <h2>Submodules<a class="headerlink" href="#submodules" title="Link to this headi
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_fault"><code class="docutils literal notranslate"><span class="pre">handle_fault()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_grid_props"><code class="docutils literal notranslate"><span class="pre">handle_grid_props()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_mapaxes"><code class="docutils literal notranslate"><span class="pre">handle_mapaxes()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_oper"><code class="docutils literal notranslate"><span class="pre">handle_oper()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_props"><code class="docutils literal notranslate"><span class="pre">handle_props()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_pv"><code class="docutils literal notranslate"><span class="pre">handle_pv()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_regions"><code class="docutils literal notranslate"><span class="pre">handle_regions()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="pycopm.utils.generate_coarser_files.html#pycopm.utils.generate_coarser_files.handle_segmented_wells"><code class="docutils literal notranslate"><span class="pre">handle_segmented_wells()</span></code></a></li>
2 changes: 1 addition & 1 deletion docs/searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/text/configuration_file.rst
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ Configuration file
only for the drogon and norne model. To use **pycopm** in any given OPM Flow geological model
to generate the coarser files, this can be achieve without a configuration file, but setting
the parameters via command lines (see the :ref:`overview` or run `pycopm -h` for the definition
of the argument options, and the :doc:`examples <./examples>`.)
of the argument options, as well as the examples in :ref:`generic`.)


Here we use as an example one of the configuration files used in the tests
89 changes: 64 additions & 25 deletions docs/text/examples.rst
Original file line number Diff line number Diff line change
@@ -6,11 +6,8 @@ Examples
Via configuration files
=======================

Drogon
------

The `examples <https://github.com/cssr-tools/pycopm/blob/main/examples>`_ folder contains configuration files
to perform HM studies in drogon and norne. For example, by executing inside the `example folder for drogon <https://github.com/cssr-tools/pycopm/blob/main/examples/drogon>`_:
to perform HM studies in drogon and norne using `ERT <https://ert.readthedocs.io/en/latest/>`_. For example, by executing inside the `example folder for drogon <https://github.com/cssr-tools/pycopm/blob/main/examples/drogon>`_:

.. code-block:: bash
@@ -20,17 +17,50 @@ The following are the drogon model from `opm-tests <https://github.com/OPM/opm-t

.. figure:: figs/drogon_coarser.png

For norne:

.. code-block:: bash
pycopm -i input.txt -o norne_coarser
The norne GIF in the :doc:`introduction <./introduction>` was generated using the generated coarse model.

.. _generic:

==================
Via OPM Flow decks
==================

The current development of **pycopm** focuses on only creating coarser models (i.e., all needed input files to run OPM Flow) by using the input deck.

Hello world
-----------
For the `HELLO_WORLD.DATA <https://github.com/cssr-tools/pycopm/blob/main/tests/decks/HELLO_WORLD.DATA>`_ deck, by executing:

.. code-block:: bash
pycopm -i HELLO_WORLD.DATA -c 5,1,5 -m all
This would generated the following:

.. figure:: figs/hello_world_1.png

Dry run from the input cloned deck (left) and (right) coarsed model. Adding the flag -p 1 adds the remove pore volume to the neighbouring cells.

To make active the coarse cell where there is only one active cell, this can be achieve by:

.. code-block:: bash
pycopm -i HELLO_WORLD.DATA -c 5,1,5 -m all -a max
.. figure:: figs/hello_world_2.png

Dry run from the input cloned deck (left) and (right) coarsed model. The region numbers by default are given by the mode, e.g., use the flag -n max to keep the maximum integer.

SPE10
-----

See/run the `test_generic_deck.py <https://github.com/cssr-tools/pycopm/blob/main/tests/test_generic_deck.py>`_
for an example where **pycopm** is used to coarse the
`SPE10_MODEL2 model <https://github.com/OPM/opm-data/tree/master/spe10model2>`_ by downloading the OPM files and running:
By downloading the `SPE10_MODEL2 model <https://github.com/OPM/opm-data/tree/master/spe10model2>`_, then:

.. code-block:: bash
@@ -48,26 +78,20 @@ then:

.. code-block:: bash
pycopm -i Statoil_Feasibility_sim_model_with_depletion_KROSS_INJ_SECTOR_20.DATA -o . -c 5,4,3 -a mode
will generate a coarser model 5 times in the x direction, 4 in the y direction, and 3 in the z direction, where the mode is
used to decide if a coarser cell should be active or inactive.
pycopm -i Statoil_Feasibility_sim_model_with_depletion_KROSS_INJ_SECTOR_20.DATA -o . -c 5,4,3 -a min -m all
We can execute a dry run of OPM Flow to generate the grid and static variables of the coarser model:

.. code-block:: bash
flow STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM.DATA --enable-dry-run=true
will generate a coarser model 5 times in the x direction, 4 in the y direction, and 3 in the z direction, where the coarse cell is
made inactive if at least one cell is inactive (-a min).

We use our `plopm <https://github.com/cssr-tools/plopm>`_ friend to generate PNG figures:

.. code-block:: bash
plopm -i STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM -s ,,0
plopm -i ' STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PREP_PYCOPM_DRYRUN STATOIL_FEASIBILITY_SIM_MODEL_WITH_DEPLETION_KROSS_INJ_SECTOR_20_PYCOPM' -s ,,0 -v poro -subfigs 1,2 -save smeaheia -t 'Smeaheia Coarsed smeaheia' -xunits km -xformat .0f -yunits km -yformat .0f -d 5,5.2 -suptitle 0 -c cet_rainbow_bgyrm_35_85_c69 -cbsfax 0.30,0.01,0.4,0.02 -cformat .2f
.. figure:: figs/smeia.png

Porosity values for the (left) original and (right) coarsed model.
Top view of porosity values for the (left) original and (right) coarsed model (note that we also coarse on the z direction).

.. tip::
You can install plopm by executing in the terminal: pip install git+https://github.com/cssr-tools/plopm.git.
@@ -77,16 +101,16 @@ We use our `plopm <https://github.com/cssr-tools/plopm>`_ friend to generate PNG
(e.g., FAULTS, WELLSPECS) are assumed to be define in the main .DATA deck. Then, in order to use **pycopm** for simulation models
where these properties are define via include files, replace those includes in the .DATA deck with the actual content of the include files.

Generic Drogon
--------------
Drogon
------
Following the note above, then by downloading the `DROGON model <https://github.com/OPM/opm-tests/tree/master/drogon>`_, replacing the lines in
`DROGON_HIST.DATA <https://github.com/OPM/opm-tests/blob/master/drogon/model/DROGON_HIST.DATA>`_ for the FAULTS (L127-128) and SCHEDULE (L242-243) with
the actual content of those include files, then by executing:

.. code-block:: bash
pycopm -i DROGON_HIST.DATA -o . -c 1,1,3 -a min -n max -p 1
pycopm -i DROGON_HIST_PYCOPM.DATA -o . -c 1,3,1 -a mode -n mode -p 1 -j 1.9
pycopm -i DROGON_HIST.DATA -c 1,1,3 -p 1
pycopm -i DROGON_HIST_PYCOPM.DATA -c 1,3,1 -p 1 -j 2.5
this would generate the following coarse model:

@@ -95,8 +119,23 @@ this would generate the following coarse model:
Note that the total pore volume is conserved for the coarse model.

Here, we first coarse in the z direction, which reduces the number of cells from 31 to 11, and after we coarse in the y direction.
After trial and error, the jump (-j) is set to 1.9 to avoid generated connections across the faults.
After trial and error, the jump (-j) is set to 2.5 to avoid generated connections across the faults. For geological models with a lot of
inactive cells and faults, this divide and conquer apporach is recommended, i.e., coarsening first in the z directon and after coarsening
in the x and y directions.

.. note::
After genereting the first coarser deck (DROGON_HIST_PYCOPM.DATA), change the path '../include/props/drogon.swatinit' to 'SWATINIT.INC',
which contains the right number of values for the coarse model.
Add to the generated coarse deck the missing include files in the grid section related to the region operations (e.g.,
../include/grid/drogon.multregt for this case).

Norne
-----
By downloading the `Norne model <https://github.com/OPM/opm-tests/tree/master/norne>`_ (and replacing the needed include files as described in the previous
example), then here we create a coarser model by removing certain pilars in order to keep the main features of the geological model:

.. code-block:: bash
pycopm -i NORNE_ATW2013.DATA -x 0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,2,0,2,2,2,2,0 -y 0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,2,2,2,2,2,2,2,2,0 -z 0,0,2,0,0,2,2,2,2,2,02,2,2,2,2,0,0,2,0,2,2,0,0,0,0,0,0,0,0,0,0 -a min -p 1
this would generate the following coarse model:

.. figure:: figs/norne_vec.png
Binary file added docs/text/figs/hello_world_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/text/figs/hello_world_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/text/figs/norne_vec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/text/figs/output_generic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/text/figs/smeia.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 19 additions & 15 deletions docs/text/introduction.rst
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ Simplified and flexible framework to create coarser OPM Flow geological models.

Roadmap
-------
In the initial development of the framework, the focus was two available models in `opm-tests <https://github.com/OPM/opm-tests>`_: `norne <https://github.com/OPM/opm-tests/tree/master/norne>`_
and `drogon <https://github.com/OPM/opm-tests/tree/master/drogon>`_, where the coarser models are used to perform history matching studies using
In the initial development of the framework, the focus were two available models in `opm-tests <https://github.com/OPM/opm-tests>`_: `norne <https://github.com/OPM/opm-tests/tree/master/norne>`_
and `drogon <https://github.com/OPM/opm-tests/tree/master/drogon>`_, where the coarser models were used to perform history matching studies using
the Ensemble based reservoir tool `ERT <https://ert.readthedocs.io/en/latest/>`_, via a :doc:`configuration file <./configuration_file>`.

The current development of **pycopm** focuses on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files
@@ -32,16 +32,20 @@ The current implementation supports the following executable with the argument o
where

-i The base name of the :doc:`configuration file <./configuration_file>` or the name of the deck, e.g., `DROGON.DATA`, (`input.txt` by default).
-o The base name of the :doc:`output folder <./output_folder>` ('.'' by default, i.e., the folder where pycopm is executed).
-f OPM Flow full path to executable or just `flow` (`flow` by default).
-c Level of coarsening in the x, y, and z dir (`2,2,2` by default).
-a Use `min`, `max`, or `mode` to scale the actnum, e.g., min makes the new coarser cell inactive it at least one cell is inactive, while max makes it active it at least one cell is active (`max` by default).
-j Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults ('' by default, i.e., nothing corrected; if need it, try with values of the order of 1).
-x Vector of x-coarsening, e.g., if the grid has 6 cells in the x direction, then `0,2,0,2,0,2,0` would generate a coarser model with 3 cells, while `0,2,2,2,2,2,0` would generate a coarser model with 1 cell, i.e., 0 keeps the pilars while 2 removes them ('' by default),
-y Vector of y-coarsening, see the description for -x ('' by default).
-z Vector of z-coarsening, see the description for -x ('' by default).
-e Use `utf8` or `ISO-8859-1` encoding to read the deck (`ISO-8859-1` by default).
-p Add the removed pore volume to the closest coarser cells (`0` by default, `1` to enable).
-n Use `min`, `max`, or `mode` to scale satnum, fipnum, pvtnum, eqlnum, imbnum, and multnum (`mode` by default).
-s Use `min`, `max`, or `mean` to scale permx, permy, permz, and poro ('' by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the porosity).
-i The base name of the :doc:`configuration file <./configuration_file>` or the name of the deck, e.g., `DROGON.DATA`, (`input.txt` by default).
-o The base name of the :doc:`output folder <./output_folder>` ('.'' by default, i.e., the folder where pycopm is executed).
-f OPM Flow full path to executable or just `flow` (`flow` by default).
-c Level of coarsening in the x, y, and z dir (`2,2,2` by default; either use this flag or the -x, -y, and -z ones).
-x Vector of x-coarsening, e.g., if the grid has 6 cells in the x direction, then `0,2,0,2,0,2,0` would generate a coarser model with 3 cells, while `0,2,2,2,2,2,0` would generate a coarser model with 1 cell, i.e., 0 keeps the pilars while 2 removes them ('' by default),
-y Vector of y-coarsening, see the description for -x ('' by default).
-z Vector of z-coarsening, see the description for -x ('' by default).
-a Use `min`, `max`, or `mode` to scale the actnum, e.g., min makes the new coarser cell inactive if at least one cell is inactive, while max makes it active it at least one cell is active (`mode` by default).
-n Use `min`, `max`, or `mode` to scale endnum, eqlnum, fipnum, fluxnum, imbnum, miscnum, multnum, pvtnum, rocknum, and satnum (`mode` by default).
-s Use `min`, `max`, or `mean` to scale permx, permy, permz, poro, swatinit, and all mult(-)xyz ('' by default, i.e., using the arithmetic average for permx/permy, harmonic average for permz, and the mean for the rest).
-p Add the removed pore volume to the closest coarser cells (`0` by default, `1` to enable).
-j Tuning parameter to avoid creation of neighbouring connections in the coarser model where there are discontinuities between cells along the z direction, e.g., around faults ('' by default, i.e., nothing corrected; if need it, try with values of the order of 1).
-m Execute a dry run on the input deck to generate the static properties ('prep'), generate only the coarse files ('deck'), only exectute a dry run on the generated coarse model ('dry'), 'prep_deck', 'deck_dry', or do all ('all') (`prep_deck` by default).
-w Name of the generated deck ('' by default, i.e., the name of the input deck plus _PYCOPM.DATA).
-l Added text before each generated .INC (`PYCOPM_` by default, i.e., the coarse porv is saved in PYCOPM_PORV.INC; set to '' to generate PORV.INC, PERMX.INC, etc).
-e Use `utf8` or `ISO-8859-1` encoding to read the deck (`ISO-8859-1` by default).
-ijk Given i,j,k indices in the input model, return the coarse i,j,k corresponding positions ('' by default; if not empty, e.g., 1,2,3 then the -m is set to deck and there will not be generation of coarse files, only the i,j,k coarse indices in the terminal).
10 changes: 8 additions & 2 deletions docs/text/output_folder.rst
Original file line number Diff line number Diff line change
@@ -21,12 +21,18 @@ are generated in the postprocessing folder. The OPM simulation results can be vi

Via an OPM Flow input deck
--------------------------
The current development of **pycopm** focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by only giving the OPM Flow input files.
The current development of **pycopm** focuces on only creating coarser models (i.e., all needed input files to run OPM Flow) by using the input deck.

The following screenshot shows the input deck and generated files in the selected output folder (coarser for this example) after executing **pycopm** on the SPE10 model (see the
`test_generic_deck.py <https://github.com/cssr-tools/pycopm/blob/main/tests/test_generic_deck.py>`_) file.

.. figure:: figs/output_generic.png

Then, after running **pycopm**, one could adapt the generated files with the coarser geological model in your
favourite history matching/optimization tool (e.g., `ERT <https://ert.readthedocs.io/en/latest/>`_, `PET <https://python-ensemble-toolbox.github.io/PET/>`_, `everest <https://github.com/equinor/everest>`_).
favourite history matching/optimization tool (e.g., `ERT <https://ert.readthedocs.io/en/latest/>`_, `PET <https://python-ensemble-toolbox.github.io/PET/>`_, `everest <https://github.com/equinor/everest>`_).

.. Note::
For input decks that include other files without giving the full path (e.g., './include/summary...'), then we recommend
to use the default output folder (-o .), i.e., the generated deck and coarse files would be generated in the same location as
the input deck and no errors would appear for not finding the include files; otherwise, you might need to copy all needed folders
with the include files to the output folder or setting the correct path to the include files in the generated coarse deck.
111 changes: 74 additions & 37 deletions src/pycopm/core/pycopm.py
Original file line number Diff line number Diff line change
@@ -29,6 +29,10 @@ def pycopm():
dic["nhow"] = cmdargs["nhow"].strip() # Max, min, or mode for other nums
dic["show"] = cmdargs["show"].strip() # Max, min, or mean for static props
dic["jump"] = cmdargs["jump"].strip() # Tuning parameter to remove nnc
dic["write"] = cmdargs["write"].strip() # Name of the generated deck
dic["mode"] = cmdargs["mode"].strip() # What to run
dic["label"] = cmdargs["label"].strip() # Prefix to the generted inc files
dic["ijk"] = cmdargs["ijk"].strip() # ijk indices to map to the coarse model
dic["encoding"] = cmdargs["encoding"].strip()
dic["pvcorr"] = int(cmdargs["pvcorr"])
dic["cijk"] = "yes"
@@ -122,30 +126,14 @@ def load_parser():
"-f",
"--flow",
default="flow",
help="OPM Flow path to executable or just 'flow' ('flow' by default)",
help="OPM Flow path to executable or just 'flow' ('flow' by default).",
)
parser.add_argument(
"-c",
"--coarsening",
default="2,2,2",
help="Level of coarsening in the x, y, and z dir ('2,2,2' by default)",
)
parser.add_argument(
"-a",
"--how",
default="max",
help="Use 'min', 'max', or 'mode' to scale the actnum, e.g., min makes "
"the new coarser cell inactive it at least one cell is inactive, while "
" max makes it active it at least one cell is active ('max' by default)",
)
parser.add_argument(
"-j",
"--jump",
default="",
help="Tuning parameter to avoid creation of neighbouring connections in "
"the coarser model where there are discontinuities between cells along "
"the z direction, e.g., around faults ('' by default, i.e., nothing "
"corrected; if need it, try with values of the order of 1)",
help="Level of coarsening in the x, y, and z dir ('2,2,2' by default; "
"either use this flag or the -x, -y, and -z ones).",
)
parser.add_argument(
"-x",
@@ -154,46 +142,95 @@ def load_parser():
help="Vector of x-coarsening, e.g., if the grid has 6 cells in the x "
"direction, then 0,2,0,2,0,2,0 would generate a coarser model with 3 "
"cells, while 0,2,2,2,2,2,0 would generate a coarser model with 1 cell, "
"i.e., 0 keeps the pilars while 2 removes them ('' by default)",
"i.e., 0 keeps the pilars while 2 removes them ('' by default).",
)
parser.add_argument(
"-y",
"--ycoar",
default="",
help="Vector of y-coarsening, see the description for -x ('' by default)",
help="Vector of y-coarsening, see the description for -x ('' by default).",
)
parser.add_argument(
"-z",
"--zcoar",
default="",
help="Vector of z-coarsening, see the description for -x ('' by default)",
help="Vector of z-coarsening, see the description for -x ('' by default).",
)
parser.add_argument(
"-e",
"--encoding",
default="ISO-8859-1",
help="Use 'utf8' or 'ISO-8859-1' encoding to read the deck ('ISO-8859-1' by default)",
)
parser.add_argument(
"-p",
"--pvcorr",
default=0,
help="Add the removed pore volume to the closest coarser cells ('0' by default)",
"-a",
"--how",
default="mode",
help="Use 'min', 'max', or 'mode' to scale the actnum, e.g., min makes "
"the new coarser cell inactive if at least one cell is inactive, while "
" max makes it active it at least one cell is active ('mode' by default).",
)
parser.add_argument(
"-n",
"--nhow",
default="mode",
help="Use 'min', 'max', or 'mode' to scale satnum, fipnum, pvtnum, eqlnum, imbnum, and "
"multnum ('mode' by default)",
help="Use 'min', 'max', or 'mode' to scale endnum, eqlnum, fipnum, fluxnum, imbnum, "
"miscnum, multnum, pvtnum, rocknum, and satnum ('mode' by default).",
)
parser.add_argument(
"-s",
"--show",
default="",
help="Use 'min', 'max', or 'mean' to scale permx, permy, permz, and poro ('' by default,"
" i.e., using the arithmetic average for permx/permy, harmonic average for permz, and "
"the mean for the porosity).",
help="Use 'min', 'max', or 'mean' to scale permx, permy, permz, poro, swatinit, and all "
"mult(-)xyz ('' by default, i.e., using the arithmetic average for permx/permy, harmonic"
" average for permz, and the mean for the rest).",
)
parser.add_argument(
"-p",
"--pvcorr",
default=0,
help="Add the removed pore volume to the closest coarser cells ('0' by default).",
)
parser.add_argument(
"-j",
"--jump",
default="",
help="Tuning parameter to avoid creation of neighbouring connections in "
"the coarser model where there are discontinuities between cells along "
"the z direction, e.g., around faults ('' by default, i.e., nothing "
"corrected; if need it, try with values of the order of 1).",
)
parser.add_argument(
"-m",
"--mode",
default="prep_deck",
help="Execute a dry run on the input deck to generate the static properties ('prep'), "
"generate only the coarse files ('deck'), only exectute a dry run on the generated "
"coarse model ('dry'), 'prep_deck', 'deck_dry', or do all ('all') ('prep_deck' by "
"default).",
)
parser.add_argument(
"-w",
"--write",
default="",
help="Name of the generated deck ('' by default, i.e., the name of the input deck plus "
"_PYCOPM.DATA).",
)
parser.add_argument(
"-l",
"--label",
default="PYCOPM_",
help="Added text before each generated .INC ('PYCOPM_' by default, i.e., the coarse porv "
"is saved in PYCOPM_PORV.INC; set to '' to generate PORV.INC, PERMX.INC, etc).",
)
parser.add_argument(
"-e",
"--encoding",
default="ISO-8859-1",
help="Use 'utf8' or 'ISO-8859-1' encoding to read the deck ('ISO-8859-1' by default).",
)
parser.add_argument(
"-ijk",
"--ijk",
default="",
help="Given i,j,k indices in the input model, return the coarse i,j,k corresponding "
"positions ('' by default; if not empty, e.g., 1,2,3 then the -mode is set to deck and "
"there will not be generation of coarse files, only the i,j,k coarse indices in the "
"terminal).",
)
return vars(parser.parse_known_args()[0])

9 changes: 0 additions & 9 deletions src/pycopm/template_scripts/common/grid.mako
Original file line number Diff line number Diff line change
@@ -23,15 +23,6 @@ ${f"{dic['zc'][i] : .3f}"}
/

% if dic['field']=='generic':
INIT
INCLUDE
'PORO.INC' /
INCLUDE
'PERMX.INC' /
INCLUDE
'PERMY.INC' /
INCLUDE
'PERMZ.INC' /
ACTNUM
% for i in range(len(dic['actnum_c'])):
${f"{dic['actnum_c'][i]}"}
358 changes: 256 additions & 102 deletions src/pycopm/utils/generate_coarser_files.py

Large diffs are not rendered by default.

168 changes: 168 additions & 0 deletions tests/decks/HELLO_WORLD.DATA
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
-- This reservoir simulation deck is made available under the Open Database
-- License: http://opendatacommons.org/licenses/odbl/1.0/. Any rights in
-- individual contents of the database are licensed under the Database Contents
-- License: http://opendatacommons.org/licenses/dbcl/1.0/

-- Copyright (C) 2024 NORCE
---------------------------------------------------------------------------
RUNSPEC
---------------------------------------------------------------------------
DIMENS
20 1 20 /

EQLDIMS
/

TABDIMS
/

GAS
WATER
CO2STORE

METRIC

START
18 'JAN' 1991 /

UNIFOUT
---------------------------------------------------------------------------
GRID
---------------------------------------------------------------------------
INIT

DX
400*1 /

DY
400*1 /

DZ
400*1 /

TOPS
20*0 /

PORO
20*0.01
20*0.02
20*0.03
20*0.04
20*0.05
20*0.06
20*0.07
20*0.08
20*0.09
20*0.10
20*0.11
20*0.12
20*0.13
20*0.14
20*0.15
20*0.16
20*0.17
20*0.18
20*0.19
20*0.20
/

PERMX
20*100
20*200
20*300
20*400
20*500
20*600
20*700
20*800
20*900
20*1000
20*1100
20*1200
20*1300
20*1400
20*1500
20*1600
20*1700
20*1800
20*1900
20*2000
/

PERMY
400*1/

PERMZ
20*100
20*200
20*300
20*400
20*500
20*600
20*700
20*800
20*900
20*1000
20*1100
20*1200
20*1300
20*1400
20*1500
20*1600
20*1700
20*1800
20*1900
20*2000
/

EQUALS
PORO 0 6 10 1* 1* 6 10 /
PORO 0.08 8 8 1* 1* 8 8 /
/
---------------------------------------------------------------------------
PROPS
---------------------------------------------------------------------------
SGWFN
0 0 1 0
1 1 0 0 /
---------------------------------------------------------------------------
REGIONS
---------------------------------------------------------------------------
FIPNUM
20*1
20*2
20*3
20*4
20*5
20*6
20*7
20*8
20*9
20*10
20*11
20*12
20*13
20*14
20*15
20*16
20*17
20*18
20*19
20*20
/
---------------------------------------------------------------------------
SOLUTION
---------------------------------------------------------------------------
EQUIL
0 1 0 0 0 0 1 1 0 /

RPTRST
BASIC=2 /
---------------------------------------------------------------------------
SCHEDULE
---------------------------------------------------------------------------
RPTRST
BASIC=2 /

TSTEP
1 /
83 changes: 61 additions & 22 deletions tests/test_generic_deck.py
Original file line number Diff line number Diff line change
@@ -10,35 +10,74 @@
def test_generic_deck():
"""pycopm application to coarser a geological model given an input deck"""
cwd = os.getcwd()
os.chdir(f"{cwd}/tests")
os.system("mkdir generic_deck")
os.chdir(f"{cwd}/tests/generic_deck")
for name in ["PERM", "PHI", "TOPS"]:
subprocess.run(
[
"curl",
"-o",
f"./SPE10MODEL2_{name}.INC",
"https://raw.githubusercontent.com/OPM/opm-data/master/spe10model2/"
+ f"SPE10MODEL2_{name}.INC",
],
check=True,
)
os.chdir(f"{os.getcwd()}/tests/decks")
subprocess.run(
[
"curl",
"pycopm",
"-i",
"HELLO_WORLD.DATA",
"-o",
"./SPE10_MODEL2.DATA",
"https://raw.githubusercontent.com/OPM/opm-data/master/spe10model2/"
+ "SPE10_MODEL2.DATA",
"coarser",
"-c",
"5,1,5",
"-m",
"prep",
],
check=True,
)
assert os.path.exists(
f"{cwd}/tests/decks/coarser/HELLO_WORLD_PREP_PYCOPM_DRYRUN.INIT"
)
assert os.path.exists(
f"{cwd}/tests/decks/coarser/HELLO_WORLD_PREP_PYCOPM_DRYRUN.EGRID"
)
for ahow in ["max", "min", "mode"]:
for nhow in ["max", "min", "mode"]:
for show in ["max", "min", "mean"]:
subprocess.run(
[
"pycopm",
"-i",
"HELLO_WORLD.DATA",
"-o",
"coarser",
"-c",
"5,1,5",
"-m",
"deck",
"-a",
ahow,
"-n",
nhow,
"-s",
show,
],
check=True,
)
assert os.path.exists(
f"{cwd}/tests/decks/coarser/HELLO_WORLD_PYCOPM.DATA"
)
os.system(f"rm {cwd}/tests/decks/coarser/HELLO_WORLD_PYCOPM.DATA")
subprocess.run(
["pycopm", "-i", "SPE10_MODEL2.DATA", "-o", "coarser", "-c", "4,8,2"],
[
"pycopm",
"-i",
"HELLO_WORLD.DATA",
"-o",
"coarser",
"-m",
"deck_dry",
"p",
"1",
"-n",
"mode",
"-x",
"0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0",
"-z",
"0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0",
],
check=True,
)
os.chdir(f"{cwd}/tests/generic_deck/coarser")
os.system("flow SPE10_MODEL2_PYCOPM.DATA --parsing-strictness=low & wait\n")
assert os.path.exists(f"{cwd}/tests/generic_deck/coarser/SPE10_MODEL2_PYCOPM.UNRST")
assert os.path.exists(f"{cwd}/tests/decks/coarser/HELLO_WORLD_PYCOPM.INIT")
assert os.path.exists(f"{cwd}/tests/decks/coarser/HELLO_WORLD_PYCOPM.EGRID")
os.chdir(cwd)

0 comments on commit aae2c80

Please sign in to comment.