From e2dd9984cd01807d49ec98874becc187d5822b7c Mon Sep 17 00:00:00 2001 From: David Landa Marban Date: Wed, 27 Nov 2024 22:55:21 +0100 Subject: [PATCH] Updates before the v2024.10 release --- CONTRIBUTING.md | 35 ++- README.md | 16 +- docs/_images/theory.png | Bin 0 -> 58010 bytes docs/_sources/about.rst.txt | 6 +- docs/_sources/contributing.rst.txt | 52 +++++ docs/_sources/examples.rst.txt | 6 +- docs/_sources/index.rst.txt | 2 + docs/_sources/installation.rst.txt | 23 +- docs/_sources/related.rst.txt | 2 +- docs/_sources/theory.rst.txt | 99 +++++++++ docs/about.html | 9 +- docs/api.html | 2 + docs/configuration_file.html | 2 + docs/contributing.html | 178 ++++++++++++++++ docs/examples.html | 36 ++-- docs/genindex.html | 8 +- docs/index.html | 15 ++ docs/installation.html | 28 ++- docs/introduction.html | 6 +- docs/modules.html | 2 + docs/objects.inv | Bin 1156 -> 1191 bytes docs/output_folder.html | 6 +- docs/py-modindex.html | 2 + docs/pycopm.core.html | 2 + docs/pycopm.core.pycopm.html | 2 + docs/pycopm.html | 4 + docs/pycopm.utils.files_writer.html | 2 + docs/pycopm.utils.generate_coarser_files.html | 14 ++ docs/pycopm.utils.grid_builder.html | 2 + docs/pycopm.utils.html | 3 + docs/pycopm.utils.input_values.html | 2 + docs/pycopm.utils.properties_builder.html | 2 + docs/pycopm.utils.runs_executer.html | 2 + docs/related.html | 8 +- docs/search.html | 2 + docs/searchindex.js | 2 +- docs/text/about.rst | 6 +- docs/text/contributing.rst | 52 +++++ docs/text/examples.rst | 6 +- docs/text/figs/theory.png | Bin 0 -> 58010 bytes docs/text/index.rst | 2 + docs/text/installation.rst | 23 +- docs/text/related.rst | 2 +- docs/text/theory.rst | 99 +++++++++ docs/theory.html | 200 ++++++++++++++++++ pyproject.toml | 5 +- src/pycopm/__init__.py | 5 + src/pycopm/utils/generate_coarser_files.py | 170 +++++++++++++-- tests/test_ert.py | 9 +- tests/test_generic_deck.py | 27 +-- tests/test_single_run.py | 9 +- 51 files changed, 1085 insertions(+), 112 deletions(-) create mode 100644 docs/_images/theory.png create mode 100644 docs/_sources/contributing.rst.txt create mode 100644 docs/_sources/theory.rst.txt create mode 100644 docs/contributing.html create mode 100644 docs/text/contributing.rst create mode 100644 docs/text/figs/theory.png create mode 100644 docs/text/theory.rst create mode 100644 docs/theory.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8bcf557..d954776 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,16 +1,35 @@ # Contributing -Hola hola 🙂. -The following is a set of guidelines for contributing to pycopm. +Contributions are more than welcome using the fork and pull request approach 🙂 (if you are not familiar with this approach, please visit [_GitHub Docs PRs_](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests) for an extended documentation about collaborating with pull request; also, looking at previous merged pull requests helps to get familiar with this). ## Ground Rules -1. We use Black code formatting -1. We use Pylint -1. We document our code +- We use Black code formatting +- We use Pylint +- We document our code -## Pull Request Process +## Contribute to the software 1. Work on your own fork of the main repo -1. Push your commits and make a pull request -1. The changes are merged when your code has been approved +1. In the main repo execute: + 1. **pip install -r dev-requirements.txt** (this installs the [_dev-requirements.txt_](https://github.com/cssr-tools/pycopm/blob/main/dev-requirements.txt)) + 1. **black src/ tests/** (this formats the code) + 1. **pylint src/ tests/** (this analyses the code, and might rise issues that need to be fixed before the pull request) + 1. **mypy --ignore-missing-imports src/ tests/** (this is a static checker, and might rise issues that need to be fixed before the pull request) + 1. **pytest --cov=pycopm --cov-report term-missing tests/** (this runs locally the tests, and might rise issues that need to be fixed before the pull request) + 1. **pushd docs & make html** (this generates the documentation, and might rise issues that need to be fixed before the pull request; if the build succeeds and if the contribution changes the documentation, then copy all content from the docs/_build/html/ folder and replace the files in the [_docs_](https://github.com/cssr-tools/pycopm/tree/main/docs) folder) + * Tip: See the [_CI.yml_](https://github.com/cssr-tools/pycopm/blob/main/.github/workflows/CI.yml) script and the [_Actions_](https://github.com/cssr-tools/pycopm/actions) for installation of pycopm, OPM Flow (binary packages), and dependencies, as well as the execution of the six previous steps in Ubuntu 24.10. +1. Squash your commits into a single commit (see this [_nice tutorial_](https://gist.github.com/lpranam/4ae996b0a4bc37448dc80356efbca7fa) if you are not familiar with this) +1. Push your commit and make a pull request +1. The maintainers will review the pull request, and if the contribution is accepted, then it will be merge to the main repo + +## Reporting issues or problems + +1. Issues or problems can be raised by creating a [_new issue_](https://github.com/cssr-tools/pycopm/issues) in the repository GitHub page (if you are not familiar with this approach, please visit [_GitHub Docs Issues_](https://docs.github.com/en/issues/tracking-your-work-with-issues)). +1. We will try to answer as soon as possible, but also any user is more than welcome to answer. + +## Seek support + +1. The preferred approach to seek support is to raise an Issue as described in the previous lines. +1. We will try to answer as soon as possible, but also any user is more than welcome to answer. +- An alternative approach is to send an email to any of the [_mantainers_](https://github.com/cssr-tools/pycopm/blob/main/pyproject.toml). \ No newline at end of file diff --git a/README.md b/README.md index 706890d..c071fd5 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,24 @@ Creation of coarser models from given input decks. ## Installation You will first need to install -* OPM Flow (https://opm-project.org, Release 2024.04 or current master branches) +* OPM Flow (https://opm-project.org, Release 2024.10 or current master branches) -To install the _pycopm_ executable in an existing Python environment: +To install the _pycopm_ executable from the development version: ```bash pip install git+https://github.com/cssr-tools/pycopm.git ``` -If you are interested in modifying the source code, then you can clone the repository and -install the Python requirements in a virtual environment with the following commands: +If you are interested in a specific version (e.g., v2024.10) or in modifying the source code, then you can clone the repository and install the Python requirements in a virtual environment with the following commands: ```bash # Clone the repo git clone https://github.com/cssr-tools/pycopm.git # Get inside the folder cd pycopm -# Create virtual environment (for higher versions of Python than the default one, e.g., python3.12 -m venv vpycopm) +# For a specific version (e.g., v2024.10), or skip this step (i.e., edge version) +git checkout v2024.10 +# Create virtual environment (to specific Python, python3.12 -m venv vpycopm) python3 -m venv vpycopm # Activate virtual environment source vpycopm/bin/activate @@ -40,7 +41,7 @@ pip install -e . pip install -r dev-requirements.txt ``` -See the [_installation_](https://cssr-tools.github.io/pycopm/installation.html) for further details on building OPM Flow from the master branches in Linux, Windows, and macOS, as well as the opm Python package. +See the [_installation_](https://cssr-tools.github.io/pycopm/installation.html) for further details on building OPM Flow from the master branches in Linux, Windows, and macOS. ## Running pycopm You can run _pycopm_ as a single command line: @@ -65,4 +66,5 @@ The following is a list of manuscripts in which _pycopm_ is used: The _pycopm_ package is being funded by the [_Center for Sustainable Subsurface Resources (CSSR)_](https://cssr.no) [project no. 331841] and by [_Expansion of Resources for CO2 Storage on the Horda Platform (ExpReCCS)_](https://www.norceresearch.no/en/projects/expansion-of-resources-for-co2-storage-on-the-horda-platform-expreccs) [project no. 336294]. This is work in progress. -Contributions are more than welcome using the fork and pull request approach. \ No newline at end of file +Contributions are more than welcome using the fork and pull request approach. +For a new feature, please request this by raising an issue. \ No newline at end of file diff --git a/docs/_images/theory.png b/docs/_images/theory.png new file mode 100644 index 0000000000000000000000000000000000000000..a078acc7d90282fdffdcaf0ae8465a93ca7bb4d8 GIT binary patch literal 58010 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 literal 0 HcmV?d00001 diff --git a/docs/_sources/about.rst.txt b/docs/_sources/about.rst.txt index a66ddfc..2f1288e 100644 --- a/docs/_sources/about.rst.txt +++ b/docs/_sources/about.rst.txt @@ -7,5 +7,9 @@ About pycopm **pycopm**, a tool for coarsening OPM Flow geological models, is being funded by the `Center for Sustainable Subsurface Resources (CSSR) `_ [project no. 331841] and by `Expansion of Resources for CO2 Storage on the Horda Platform (ExpReCCS) `_ [project no. 336294]. + This is work in progress. -Contributions are more than welcome using the fork and pull request approach. \ No newline at end of file + +Contributions are more than welcome using the fork and pull request approach. + +For a new feature, please request this raising an issue. \ No newline at end of file diff --git a/docs/_sources/contributing.rst.txt b/docs/_sources/contributing.rst.txt new file mode 100644 index 0000000..4a336a9 --- /dev/null +++ b/docs/_sources/contributing.rst.txt @@ -0,0 +1,52 @@ +************ +Contributing +************ + +Contributions are more than welcome using the fork and pull request approach 🙂 (if you are not familiar with this approach, +please visit `GitHub Docs PRs `_ for an extended +documentation about collaborating with pull request; also, looking at previous merged pull requests helps to get familiar with this). + +============ +Ground Rules +============ + +- We use Black code formatting +- We use Pylint +- We document our code + +========================== +Contribute to the software +========================== + +#. Work on your own fork of the main repo +#. In the main repo execute: + + #. **pip install -r dev-requirements.txt** (this installs the `dev-requirements.txt `_) + #. **black src/ tests/** (this formats the code) + #. **pylint src/ tests/** (this analyses the code, and might rise issues that need to be fixed before the pull request) + #. **mypy --ignore-missing-imports src/ tests/** (this is a static checker, and might rise issues that need to be fixed before the pull request) + #. **pytest --cov=pycopm --cov-report term-missing tests/** (this runs locally the tests, and might rise issues that need to be fixed before the pull request) + #. **pushd docs & make html** (this generates the documentation, and might rise issues that need to be fixed before the pull request; if the build succeeds and if the contribution changes the documentation, then copy all content from the docs/_build/html/ folder and replace the files in the `docs `_ folder) + + .. tip:: + See the `CI.yml `_ script and the `Actions `_ for installation of pycopm, OPM Flow (binary packages), and dependencies, as well as the execution of the six previous steps in Ubuntu 24.10. + +#. Squash your commits into a single commit (see this `nice tutorial `_ if you are not familiar with this) +#. Push your commit and make a pull request +#. The maintainers will review the pull request, and if the contribution is accepted, then it will be merge to the main repo + +============================ +Reporting issues or problems +============================ + +#. Issues or problems can be raised by creating a `new issue `_ in the repository GitHub page (if you are not familiar with this approach, please visit `GitHub Docs Issues `_). +#. We will try to answer as soon as possible, but also any user is more than welcome to answer. + +============ +Seek support +============ + +#. The preferred approach to seek support is to raise an Issue as described in the previous lines. +#. We will try to answer as soon as possible, but also any user is more than welcome to answer. + +- An alternative approach is to send an email to any of the `mantainers `_. \ No newline at end of file diff --git a/docs/_sources/examples.rst.txt b/docs/_sources/examples.rst.txt index 0549740..7a8fcb1 100644 --- a/docs/_sources/examples.rst.txt +++ b/docs/_sources/examples.rst.txt @@ -94,7 +94,7 @@ We use our `plopm `_ friend to generate PNG 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. + You can install `plopm `_ by executing in the terminal: pip install git+https://github.com/cssr-tools/plopm.git. Drogon ------ @@ -152,7 +152,7 @@ If we run these three models using OPM Flow, then we can compare the summary vec .. code-block:: bash - plopm -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -v 'FOIP,FOPR,TCPU' -tunits y -f 14 -subfigs 2,2 -delax 1 -loc empty,empty,empty,center -d 10,5 -xformat '.1f' -xlnum 6 -ylabel 'sm$^3$ sm$^3$/day seconds' -t 'Field oil in place Field oil production rate Simulation time' -labels 'DROGON DROGON 3XZ COARSER DROGON 2XYZ COARSER' -save drogon_pycopm_comparison -yformat '.2e,.0f,.0f' + plopm -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -v 'FOIP,FOPR,TCPU' -tunits y -f 14 -subfigs 2,2 -delax 1 -loc empty,empty,empty,center -d 10,5 -xformat '.1f' -xlnum 6 -ylabel 'sm$^3$ sm$^3$/day seconds' -t 'Field oil in place Field oil production rate Simulation time' -labels 'DROGON DROGON 3XZ COARSER DROGON 2XYZ COARSER' -save drogon_pycopm_comparison -yformat '.2e,.0f,.0f' .. figure:: figs/drogon_pycopm_comparison.png @@ -164,7 +164,7 @@ We can also make a nice GIF by executing: .. code-block:: bash - plopm -v sgas -subfigs 1,3 -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -d 16,10.5 -r 0,3 -m gif -dpi 1000 -t "DROGON DROGON 3XZ COARSER DROGON 2XYZ COARSER" -f 16 -interval 2000 -loop 1 -cformat .2f -cbsfax 0.30,0.01,0.4,0.02 -s ,,1 -rotate -30 -xunits km -yunits km -xformat .0f -yformat .0f -c cet_rainbow_bgyrm_35_85_c69 + plopm -v sgas -subfigs 1,3 -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -d 16,10.5 -r 0,3 -m gif -dpi 300 -t "DROGON DROGON 3XZ COARSER DROGON 2XYZ COARSER" -f 16 -interval 2000 -loop 1 -cformat .2f -cbsfax 0.30,0.01,0.4,0.02 -s ,,1 -rotate -30 -xunits km -yunits km -xformat .0f -yformat .0f -c cet_rainbow_bgyrm_35_85_c69 .. figure:: figs/sgas.gif diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt index 1dcc9d1..4b046b9 100644 --- a/docs/_sources/index.rst.txt +++ b/docs/_sources/index.rst.txt @@ -7,11 +7,13 @@ Welcome to pycopm's documentation! :maxdepth: 4 introduction + theory installation configuration_file examples api output_folder + contributing related about diff --git a/docs/_sources/installation.rst.txt b/docs/_sources/installation.rst.txt index 8697a84..ece37dd 100644 --- a/docs/_sources/installation.rst.txt +++ b/docs/_sources/installation.rst.txt @@ -2,16 +2,19 @@ Installation ============ +The following steps work installing the dependencies in Linux via apt-get or in macOS using brew or macports. +While using package managers such as Anaconda, Miniforge, or Mamba might work, these are not tested. + Python package -------------- -To install the **pycopm** executable in an existing Python environment: +To install the **pycopm** executable from the development version: .. code-block:: bash pip install git+https://github.com/cssr-tools/pycopm.git -If you are interested in modifying the source code, then you can clone the repository and +If you are interested in a specific version (e.g., v2024.10) or in modifying the source code, then you can clone the repository and install the Python requirements in a virtual environment with the following commands: .. code-block:: console @@ -20,7 +23,9 @@ install the Python requirements in a virtual environment with the following comm git clone https://github.com/cssr-tools/pycopm.git # Get inside the folder cd pycopm - # Create virtual environment + # For a specific version (e.g., v2024.10), or skip this step (i.e., edge version) + git checkout v2024.10 + # Create virtual environment (to specific Python, python3.12 -m venv vpycopm) python3 -m venv vpycopm # Activate virtual environment source vpycopm/bin/activate @@ -31,21 +36,25 @@ install the Python requirements in a virtual environment with the following comm # For contributions/testing/linting, install the dev-requirements pip install -r dev-requirements.txt +.. tip:: + + Typing **git tag -l** writes all available specific versions. + OPM Flow -------- You also need to install: -* OPM Flow (https://opm-project.org, Release 2024.04 or current master branches) +* OPM Flow (https://opm-project.org, Release 2024.10 or current master branches) .. tip:: See the `CI.yml `_ script - for installation of OPM Flow (binary packages) and the pycopm package in Linux. + for installation of OPM Flow (binary packages) and the pycopm package in Ubuntu. Source build in Linux/Windows +++++++++++++++++++++++++++++ If you are a Linux user (including the Windows subsystem for Linux), then you could try to build Flow (after installing the `prerequisites `_) from the master branches with mpi support by running -in the terminal the following lines (which in turn should build flow in the folder ./build/opm-simulators/bin/flow.): +in the terminal the following lines (which in turn should build flow in the folder ./build/opm-simulators/bin/flow): .. code-block:: console @@ -106,7 +115,7 @@ For macOS, there are no available binary packages, so OPM Flow needs to be built do mkdir build/opm-$repo cd build/opm-$repo - cmake -DPYTHON_EXECUTABLE=$(which python) -DWITH_NDEBUG=1 -DUSE_MPI=0 -DOPM_ENABLE_PYTHON=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$CURRENT_DIRECTORY/dune-common/build-cmake;$CURRENT_DIRECTORY/dune-grid/build-cmake;$CURRENT_DIRECTORY/dune-geometry/build-cmake;$CURRENT_DIRECTORY/dune-istl/build-cmake;$CURRENT_DIRECTORY/build/opm-common" $CURRENT_DIRECTORY/opm-$repo + cmake -DUSE_MPI=0 -DWITH_NDEBUG=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$CURRENT_DIRECTORY/dune-common/build-cmake;$CURRENT_DIRECTORY/dune-grid/build-cmake;$CURRENT_DIRECTORY/dune-geometry/build-cmake;$CURRENT_DIRECTORY/dune-istl/build-cmake;$CURRENT_DIRECTORY/build/opm-common" $CURRENT_DIRECTORY/opm-$repo make -j5 opm$repo cd ../.. done diff --git a/docs/_sources/related.rst.txt b/docs/_sources/related.rst.txt index a35bb61..6a6a54c 100644 --- a/docs/_sources/related.rst.txt +++ b/docs/_sources/related.rst.txt @@ -37,7 +37,7 @@ expreccs .. image:: ./figs/expreccs.gif :scale: 50% -`Expansion of ResourCes for CO2 Storage on the Horda Platform `_. +`A Python framework using OPM Flow to simulate regional and site reservoirs for CO2 storage `_. ******* ad-micp diff --git a/docs/_sources/theory.rst.txt b/docs/_sources/theory.rst.txt new file mode 100644 index 0000000..d392a93 --- /dev/null +++ b/docs/_sources/theory.rst.txt @@ -0,0 +1,99 @@ +****** +Theory +****** + +The coarsening approach implemented in **pycopm** is based on industry standard grid formats which is preserved during coarsening. +This allows for direct application in standard reservoir simulators. +In coarsening accuracy is traded for speed. +This is often appropriate, but care must be taken to assure that the coarse solution preserve the key properties of the model. +The `Lie 2019 textbook `_ +gives an excellent introduction to grid coarsening and upscaling geological properties, and the methods implemented in **pycopm** follow similar techniques. + +=============== +Grid coarsening +=============== + +Corner-point grids are commonly use in subsurface simulations, due to its flexibility to handle complex geometries such as faults. +The grid is defined by vertical pillars and horizontal lines connecting the pillars, resulting in cells that can have up to six faces (hexahedrons), +but also these grids allow to define connections between non-neighboring cells (NNC). A special case of corner-point grids are Cartesian regular grids. +These grids also feature inactive cells, which are cells with zero pore volume and no connected to the active cells. + +We define the grid coarsening operator :math:`\Xi_{xyz}^C`, which creates from an input grid :math:`\Omega` a coarser grid :math:`\Omega^*` (we adopt the notation * for +coarser quantities, while :math:`{}^C` in the coarsening operator emphasize the different approaches for the cell clustering) by removing +vertical pillars and horizontal lines: + +.. math:: + \Xi_{xyz}^C(\Omega)\rightarrow\Omega^* + +To give flexibility in the coarsening, the cell clustering can be given as x, y, and z arrays to define the pillars/lines to be removed. +One natural question is how to handle the inactive cells in a cluster, and for this, three options to define the coarser cells are implemented: +min, max, and mode (mode is the default, i.e., the coarser cells is active if the number of active cells is the most common value in the cluster). +Figure 1 shows a simple 2D corner-point grid with different coarsening using min, max, and mode. + +.. figure:: figs/theory.png + + Figure 1: Example of coarser models from a grid with 18 cells, where the cell #11 is inactive. + One example where the max option could be useful is for models where there are a lot of + inactive cells in the z direction, while the min option could be useful for models applying + coarsening in the xy plane, since using min results in coarser models that do not generate + new connections across inactive cells. + +================================ +Upscaling geophysical properties +================================ + +Naturally, the pore volume in a coarser cell :math:`\Phi_{i^*,j^*,k^*}^*` (:math:`i^*`, :math:`j^*`, and :math:`k^*` referring to the cell +coarse indices in the x, y, and z direction respectively) are equal to the sum of pore volume from the corresponding cells +:math:`\Phi_{i,j,k}` in the input model, which are part of the cluster :math:`\mathbb{C}_{i^*,j^*,k^*}`: + +.. math:: + \Phi_{i^*,j^*,k^*}^* = \sum_{(i,j,k)\in\mathbb{C}_{i^*,j^*,k^*}}\Phi_{i,j,k} + +For example, in Figure 1 when coarsening into two cells using mode/max resulted in two coarse cells, where: + +.. math:: + + \mathbb{C}_{1^*,1^*,1^*}=\{ (1,1,1),(2,1,1),(3,1,1),(1,1,2),(2,1,2),(3,1,2),(1,1,3),(2,1,3),(3,1,3) \}. + +From this definition, the porosity in the coarse model :math:`\phi_{i^*,j^*,k^*}^*` can be simply computed by: + +.. math:: + \phi_{i^*,j^*,k^*}^* = \frac{\Phi_{i^*,j^*,k^*}^*}{\mathbb{V}_{i^*,j^*,k^*}^*} + +where :math:`\mathbb{V}_{i^*,j^*,k^*}^*` is the geometric volume of the coarser cell. + +For the rock permeability, there are different upscaling methods (e.g., arithmetic or harmonic average) that are case dependent and perform different, +see the `Lie 2019 textbook `_ +for comparison of these methods. In **pycopm**, by default the permeability in the x and y directions are computed using the arithmetic average, while +the permeability in the z direction by the harmonic average. As additional options, the permeabilities in the coarser cells :math:`\mathbb{K}_{i^*,j^*,k^*}^*` can +be set to equal the min, max, and mean values from the permeabilities in the corresponding cluster :math:`\mathbb{K}_{i,j,k}`. For example, using the max for +permeabilities could be useful for history matching studies, where the parameters to history match are saturation functions +(relative permeabilities and capillary pressure). + +The above line mentions the initial application to develop **pycopm** (coarsening to history match saturation functions), as such there are no upscaling +methods implemented in **pycopm** for saturation functions. In a geological model, it is common to define different regions (referred as satnum) to assign +different saturation function tables. Then, if a cluster :math:`\mathbb{C}_{i^*,j^*,k^*}` involves different values for satnum, the mode (the most frequent value) is used +to assign the value in the coarser cell (this is also used to assign additional discrete coarser values such as fluid-in-place regions (fipnum)). + +For grids with large number of non-neighboring connections (faults) and inactive cells, then a better approach is to upscale transmisibilities. +A drawback of upscaling transmissibilities is that permeabilities cannot be used in history matching, but instead, transmissibilities multipliers, +which increases the number of parameters to history match and might break history match workflows where different permeability fields are generated +from spatial correlations. To this end, two approaches to upscale transmissibilities are implemented in **pycopm**. The former computes the coarser +transmissibility + +.. math:: + \scriptsize\mathbb{T}_{i^*,j^*,k^*}^*=\left[ T_{i^*,j^*,k^*\rightarrow i^*+1,j^*,k^*}^*,T_{i^*-1,j^*,k^*\rightarrow i^*,j^*,k^*}^*,T_{i^*,j^*,k^*\rightarrow i^*,j^*+1,k^*}^*,T_{i^*,j^*-1,k^*\rightarrow i^*,j^*,k^*}^*,T_{i^*,j^*,k^*\rightarrow i^*,j^*,k^*+1}^*,T_{i^*,j^*,k^*-1\rightarrow i^*,j^*,k^*}^* \right] + +using the armonic averaging along the transsmissibility direction and summing over these values over the cell coarser face. For example, +for the transmissibility in the z+ direction: + +.. math:: + T_{i^*,j^*,k^*\rightarrow i^*,j^*,k^*+1}^*=\sum_{(i,j)\in\mathbb{C}_{i^*,j^*,k^*}}\left( \sum_{(i,j,k)\rightarrow(i,j,k+1)\in\mathbb{C}_{i^*,j^*,k^*}} \frac{1}{T_{i,j,k\rightarrow i,j,k+1}} \right)^{-1} + +For cases where the coarsening is only along one direction (e.g., the z direction), the second method sets the transmissibility on the coarse cell +faces in that direction equal to the overlapping cell face values in the corresponding cluster (instead of computing the armonic average). For input +models with a large number of inactive cells, this approach has resulted in better results with respect to the input model simulations than using the +armonic average. For both approaches, the transmissibilities are scaled with the ratio of the cell +face effective areas (input model) to the coarse cell area. For non-neighbouring connections, this approach is also implemented, i.e., +the non-neighbouring connections in the coarser model sum the values from the non-neighbouring connections in the input model, which is important in +order to honor the pressure connections along open faults communicating different formations. \ No newline at end of file diff --git a/docs/about.html b/docs/about.html index 856af75..f42197d 100644 --- a/docs/about.html +++ b/docs/about.html @@ -45,11 +45,13 @@ -
+
_images/spe10_model2_coarser.png
-

Porosity values for the (left) original and (right) coarsed SPE10 model.

+

Porosity values for the (left) original and (right) coarsed SPE10 model.

@@ -162,15 +164,15 @@

Smeaheia
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
 
-
+
_images/smeia.png
-

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

+

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.

+

You can install plopm by executing in the terminal: pip install git+https://github.com/cssr-tools/plopm.git.

@@ -195,10 +197,10 @@

Drogon<

this would generate the following coarse model:

-
+
_images/drogon_generic.png
-

Note that the total pore volume is conserved for the 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. @@ -220,25 +222,25 @@

Drogon<

Here, we use the -w flag to give a specific name to the generated coarser deck, as well as using a higher value of -j to avoid generated connections across the faults. If we run these three models using OPM Flow, then we can compare the summary vectors. To this end, we use our good old friend plopm:

-
plopm -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -v 'FOIP,FOPR,TCPU' -tunits y -f 14 -subfigs 2,2 -delax 1 -loc empty,empty,empty,center -d 10,5 -xformat '.1f' -xlnum 6 -ylabel 'sm$^3$ sm$^3$/day seconds' -t 'Field oil in place  Field oil production rate  Simulation time' -labels 'DROGON  DROGON 3XZ COARSER  DROGON 2XYZ COARSER' -save drogon_pycopm_comparison -yformat '.2e,.0f,.0f'
+
plopm -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -v 'FOIP,FOPR,TCPU' -tunits y -f 14 -subfigs 2,2 -delax 1 -loc empty,empty,empty,center -d 10,5 -xformat '.1f' -xlnum 6 -ylabel 'sm$^3$  sm$^3$/day  seconds' -t 'Field oil in place  Field oil production rate  Simulation time' -labels 'DROGON  DROGON 3XZ COARSER  DROGON 2XYZ COARSER' -save drogon_pycopm_comparison -yformat '.2e,.0f,.0f'
 
-
+
_images/drogon_pycopm_comparison.png

Note that the coarse models have the same initial field oil in place as the input model. It seems the coarse properties (e.g., permeabilities) are good initial inputs to use in a history matching framework (e.g., to history match saturation function parameters), and the lower simulation -time for the coarse models allow for more ensemble members and more iterations.

+time for the coarse models allow for more ensemble members and more iterations.

We can also make a nice GIF by executing:

-
plopm -v sgas -subfigs 1,3 -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -d 16,10.5 -r 0,3 -m gif -dpi 1000 -t "DROGON  DROGON 3XZ COARSER  DROGON 2XYZ COARSER" -f 16 -interval 2000 -loop 1 -cformat .2f -cbsfax 0.30,0.01,0.4,0.02 -s ,,1 -rotate -30 -xunits km -yunits km -xformat .0f -yformat .0f -c cet_rainbow_bgyrm_35_85_c69
+
plopm -v sgas -subfigs 1,3 -i 'DROGON_HIST DROGON_HIST_PYCOPM_PYCOPM DROGON_2TIMES_COARSER' -d 16,10.5 -r 0,3 -m gif -dpi 300 -t "DROGON  DROGON 3XZ COARSER  DROGON 2XYZ COARSER" -f 16 -interval 2000 -loop 1 -cformat .2f -cbsfax 0.30,0.01,0.4,0.02 -s ,,1 -rotate -30 -xunits km -yunits km -xformat .0f -yformat .0f -c cet_rainbow_bgyrm_35_85_c69
 
-
+
_images/sgas.gif
-

Top view of the Drogon and the two coarse models

+

Top view of the Drogon and the two coarse models

diff --git a/docs/genindex.html b/docs/genindex.html index d26a2b9..8bf9424 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -43,11 +43,13 @@