diff --git a/.gitignore b/.gitignore index 8d05456..68b039a 100644 --- a/.gitignore +++ b/.gitignore @@ -170,6 +170,7 @@ examples/poro_*,1,*.png examples/porv_*,1,*.png examples/satnum_*,1,*.png examples/sgas_*,1,*.png +examples/rsw_*,1,*.png examples/fgip.png tests/generic_deck diff --git a/docs/_images/sgas_diff.png b/docs/_images/sgas_diff.png new file mode 100644 index 0000000..df68c1a Binary files /dev/null and b/docs/_images/sgas_diff.png differ diff --git a/docs/_images/sgas_diff_edit.png b/docs/_images/sgas_diff_edit.png new file mode 100644 index 0000000..e0e11dd Binary files /dev/null and b/docs/_images/sgas_diff_edit.png differ diff --git a/docs/_images/tcpu.png b/docs/_images/tcpu.png new file mode 100644 index 0000000..f735d80 Binary files /dev/null and b/docs/_images/tcpu.png differ diff --git a/docs/_sources/api.rst.txt b/docs/_sources/api.rst.txt index e2d407c..a256c62 100644 --- a/docs/_sources/api.rst.txt +++ b/docs/_sources/api.rst.txt @@ -2,6 +2,8 @@ plopm Python API ================ -The main script (and the only one by now) for the **plopm** executable is located in the `core `_ folder. +The main script for the **plopm** executable is located in the `core `_ folder. +The `utils `_ folder contains all different methods to handle the plotting. + .. include:: modules.rst \ No newline at end of file diff --git a/docs/_sources/examples.rst.txt b/docs/_sources/examples.rst.txt index 88f13aa..b6f0d5b 100644 --- a/docs/_sources/examples.rst.txt +++ b/docs/_sources/examples.rst.txt @@ -82,4 +82,38 @@ To plot the location of the wells from the top view, then: plopm -i SPE10_MODEL2 -w 1 .. image:: ./figs/wells.png - :scale: 20% \ No newline at end of file + :scale: 20% + +===================== +Different input files +===================== +Let us assume we have two different runs in different folders for the spe11b case, where the firsts results are save +in a folder called spe11b, and simulation results where the injection rate has been increased are saved in a folder +called spe11b_larger_inj. Then, to plot the summary vector for both runs we can execute: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,/Users/dmar/spe11b_larger_inj/SPE11B -v tcpu -d 5,5 -c r,b -e 'solid;:' -t 'Comparing the simulation times' -f 10 + +.. image:: ./figs/tcpu.png + +Here, we have lower the size of the figure to 5,5 inches, set to use red and blue colors with solid and dotted lines, as well as settting the title and lower the font size to 10. + +.. tip:: + For any summary variable, one can give the path to more than two different simulation cases, just by separating the folder paths by commas in the -i. + +To look at the difference between these two simulations for the dynamic variable sgas at the restar step 3, this can be achieved by executing: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3 + +.. image:: ./figs/sgas_diff.png + +To changue the colormap and setting the clorbar limits manually, this can be achieved by: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3 -c tab20c -b '[-0.8,0]' + +.. image:: ./figs/sgas_diff_edit.png diff --git a/docs/_sources/introduction.rst.txt b/docs/_sources/introduction.rst.txt index 80553e3..4bccd16 100644 --- a/docs/_sources/introduction.rst.txt +++ b/docs/_sources/introduction.rst.txt @@ -14,7 +14,8 @@ and dynamic (e.g., pressure, fluid saturations) properties given any 2D slide (e as well as plotting any given summary vector (e.g., field gas in place a.k.a fgip). The **plopm** tool can be useful for quick inspection of geological models, as well as for generation of nice -figures for papers/presentations. +figures for papers/presentations. In addition, **plopm** can plot summary results from different simulation cases in the same figure, +as well as the difference between given dynamic variables (e.g., pressure) for two different simulations cases. .. _overview: @@ -28,20 +29,26 @@ The current implementation supports the following executable with the argument o where -- \-i: The base name of the input deck and output files (`SPE11B` by default). -- \-o: The base name of the output folder (`output` by default). +- \-i: The base name of the input files; if more than one is given, separate them by ',' (e.g, 'SPE11B,SPE11B_TUNED') (`SPE11B` by default). +- \-o: The base name of the output folder (`.` by default). - \-f: The font size (`14` by default). - \-s: The slide for the 2D maps of the static variables, e.g, `10,,` to plot the xz plane on all cells with i=10 (`,1,` by default, i.e., the xz surface at j=1). - \-x: Option to set the lower and upper bounds in the 2D map along x ('' by default). - \-y: Option to set the lower and upper bounds in the 2D map along y ('' by default). -- \-z: The option to scale the axis in the 2d maps (`yes` by default). +- \-z: The option to scale the axis in the 2D maps (`yes` by default). - \-u: Use resdata or opm Python libraries (`resdata` by default). - \-v: Specify the name of the static vairable to plot (e.g., `depth`) ('' by default, i.e., plotting: porv, permx, permz, poro, fipnum, and satnum). -- \-c: Specify the colormap (e.g., `jet`) (' by default, i.e., set by plopm). +- \-c: Specify the colormap (e.g., `jet`) ('' by default, i.e., set by plopm). - \-n: Specify the format for the numbers in the colormap (e.g., "lambda x, _: f'{x:.0f}'") ('' by default, i.e., set by plopm). -- \-l: Specify the units (e.g., \"[m\\$^2\\$]\") (`` by default, i.e., set by plopm). +- \-l: Specify the units (e.g., \"[m\\$^2\\$]\") ('' by default, i.e., set by plopm). +- \-r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one ('-1' by default, i.e., the last restart file). +- \-w: Plot the positions of the wells or sources ('0' by default). +- \-g: Plot information about the number of cells in the x, y, and z directions and number of active grid cells ('0' by default). +- \-e: Specify the linestyles separated by ';' (e.g., 'solid;:') ('' by default, i.e., set by plopm). +- \-b: Specify the upper and lower bounds for the color map (e.g., '[-0.1,11]') ('' by default, i.e., set by matplotlib). +- \-d: Specify the dimensions of the Figure (e.g., '5,5') ('8,16' by default). +- \-t: Specify the figure title (e.g., 'Final saturation map') ('' by default, i.e., set by plopm). - \-r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one ('-1' by default, i.e., the last restart file). -- \-w: Plot the xz-position of the wells or sources ('0' by default). Installation ------------ diff --git a/docs/api.html b/docs/api.html index 9e72c40..98133d7 100644 --- a/docs/api.html +++ b/docs/api.html @@ -86,7 +86,8 @@

plopm Python API

-

The main script (and the only one by now) for the plopm executable is located in the core folder.

+

The main script for the plopm executable is located in the core folder. +The utils folder contains all different methods to handle the plotting.

plopm

diff --git a/docs/examples.html b/docs/examples.html index 6963c2c..45f8f4f 100644 --- a/docs/examples.html +++ b/docs/examples.html @@ -52,6 +52,7 @@
  • SPE11B
  • Norne
  • Generic deck
  • +
  • Different input files
  • plopm Python API
  • @@ -144,6 +145,31 @@

    Generic deck_images/wells.png

    +
    +

    Different input files

    +

    Let us assume we have two different runs in different folders for the spe11b case, where the firsts results are save +in a folder called spe11b, and simulation results where the injection rate has been increased are saved in a folder +called spe11b_larger_inj. Then, to plot the summary vector for both runs we can execute:

    +
    plopm -i spe11b/SPE11B,/Users/dmar/spe11b_larger_inj/SPE11B -v tcpu -d 5,5 -c r,b -e 'solid;:' -t 'Comparing the simulation times' -f 10
    +
    +
    +_images/tcpu.png +

    Here, we have lower the size of the figure to 5,5 inches, set to use red and blue colors with solid and dotted lines, as well as settting the title and lower the font size to 10.

    +
    +

    Tip

    +

    For any summary variable, one can give the path to more than two different simulation cases, just by separating the folder paths by commas in the -i.

    +
    +

    To look at the difference between these two simulations for the dynamic variable sgas at the restar step 3, this can be achieved by executing:

    +
    plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3
    +
    +
    +_images/sgas_diff.png +

    To changue the colormap and setting the clorbar limits manually, this can be achieved by:

    +
    plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3 -c tab20c -b '[-0.8,0]'
    +
    +
    +_images/sgas_diff_edit.png +
    diff --git a/docs/genindex.html b/docs/genindex.html index a579737..f861c63 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -78,45 +78,22 @@

    Index

    - G - | I + H | L | M | P
    -

    G

    +

    H

    - -
    - -

    I

    - -
    @@ -133,20 +110,6 @@

    M

    -
  • plopm Python API
      diff --git a/docs/introduction.html b/docs/introduction.html index d2eb0e2..d23d33d 100644 --- a/docs/introduction.html +++ b/docs/introduction.html @@ -95,7 +95,8 @@

      Concept and dynamic (e.g., pressure, fluid saturations) properties given any 2D slide (e.g., the middle part of a reservoir in the xy plane), as well as plotting any given summary vector (e.g., field gas in place a.k.a fgip).

      The plopm tool can be useful for quick inspection of geological models, as well as for generation of nice -figures for papers/presentations.

      +figures for papers/presentations. In addition, plopm can plot summary results from different simulation cases in the same figure, +as well as the difference between given dynamic variables (e.g., pressure) for two different simulations cases.

      Overview

      @@ -105,20 +106,26 @@

      Concept

      where

        -
      • -i: The base name of the input deck and output files (SPE11B by default).

      • -
      • -o: The base name of the output folder (output by default).

      • +
      • -i: The base name of the input files; if more than one is given, separate them by ‘,’ (e.g, ‘SPE11B,SPE11B_TUNED’) (SPE11B by default).

      • +
      • -o: The base name of the output folder (. by default).

      • -f: The font size (14 by default).

      • -s: The slide for the 2D maps of the static variables, e.g, 10,, to plot the xz plane on all cells with i=10 (,1, by default, i.e., the xz surface at j=1).

      • -x: Option to set the lower and upper bounds in the 2D map along x (’’ by default).

      • -y: Option to set the lower and upper bounds in the 2D map along y (’’ by default).

      • -
      • -z: The option to scale the axis in the 2d maps (yes by default).

      • +
      • -z: The option to scale the axis in the 2D maps (yes by default).

      • -u: Use resdata or opm Python libraries (resdata by default).

      • -v: Specify the name of the static vairable to plot (e.g., depth) (’’ by default, i.e., plotting: porv, permx, permz, poro, fipnum, and satnum).

      • -
      • -c: Specify the colormap (e.g., jet) (’ by default, i.e., set by plopm).

      • +
      • -c: Specify the colormap (e.g., jet) (’’ by default, i.e., set by plopm).

      • -n: Specify the format for the numbers in the colormap (e.g., “lambda x, _: f’{x:.0f}’”) (’’ by default, i.e., set by plopm).

      • -
      • -l: Specify the units (e.g., "[m\$^2\$]") (`` by default, i.e., set by plopm).

      • +
      • -l: Specify the units (e.g., "[m\$^2\$]") (’’ by default, i.e., set by plopm).

      • +
      • -r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one (‘-1’ by default, i.e., the last restart file).

      • +
      • -w: Plot the positions of the wells or sources (‘0’ by default).

      • +
      • -g: Plot information about the number of cells in the x, y, and z directions and number of active grid cells (‘0’ by default).

      • +
      • -e: Specify the linestyles separated by ‘;’ (e.g., ‘solid;:’) (’’ by default, i.e., set by plopm).

      • +
      • -b: Specify the upper and lower bounds for the color map (e.g., ‘[-0.1,11]’) (’’ by default, i.e., set by matplotlib).

      • +
      • -d: Specify the dimensions of the Figure (e.g., ‘5,5’) (‘8,16’ by default).

      • +
      • -t: Specify the figure title (e.g., ‘Final saturation map’) (’’ by default, i.e., set by plopm).

      • -r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one (‘-1’ by default, i.e., the last restart file).

      • -
      • -w: Plot the xz-position of the wells or sources (‘0’ by default).

      diff --git a/docs/objects.inv b/docs/objects.inv index e1786fd..94d5210 100644 Binary files a/docs/objects.inv and b/docs/objects.inv differ diff --git a/docs/plopm.core.html b/docs/plopm.core.html index f2a1a79..b12c2f7 100644 --- a/docs/plopm.core.html +++ b/docs/plopm.core.html @@ -87,24 +87,11 @@

      Submodules
      • plopm.core.plopm module
      • diff --git a/docs/plopm.core.plopm.html b/docs/plopm.core.plopm.html index 7bed2c1..4581302 100644 --- a/docs/plopm.core.plopm.html +++ b/docs/plopm.core.plopm.html @@ -85,9 +85,9 @@

        plopm.core.plopm module

        Script to plot 2D maps of OPM Flow geological models.

        -
        -plopm.core.plopm.get_kws(dic)
        -

        Get the static properties from the INIT file using ResdataFile

        +
        +plopm.core.plopm.handle_slide_x(dic)
        +

        Processing the selected yz slide to obtain the grid properties

        Args:

        dic (dict): Global dictionary

        @@ -97,9 +97,9 @@
        -
        -plopm.core.plopm.get_mesh(dic)
        -

        Read the coordinates using either opm or resdata

        +
        +plopm.core.plopm.handle_slide_y(dic)
        +

        Processing the selected xz slide to obtain the grid properties

        Args:

        dic (dict): Global dictionary

        @@ -109,93 +109,9 @@
        -
        -plopm.core.plopm.get_wells(dic)
        -

        Using the input deck (.DATA) to read the i,j well locations

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.get_xy_wells(dic)
        -

        Get the top x,y coordinates from the geological model for the well figure

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.get_xycoords(dic)
        -

        Handle the coordinates from the OPM Grid to the 2D xy-mesh

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.get_xzcoords(dic)
        -

        Handle the coordinates from the OPM Grid to the 2D xz-mesh

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.get_yzcoords(dic)
        -

        Handle the coordinates from the OPM Grid to the 2D yz-mesh

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.ini_dic(cmdargs)
        -

        Initialize the global dictionary

        -
        -
        Args:

        cmdargs (dict): Command arguments

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.ini_properties(dic)
        -

        Define the properties to plot

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.ini_readers(dic)
        -

        Set the classes for reading the properties

        +
        +plopm.core.plopm.handle_slide_z(dic)
        +

        Processing the selected xy slide to obtain the grid properties

        Args:

        dic (dict): Global dictionary

        @@ -216,80 +132,6 @@

        Main function

        -
        -
        -plopm.core.plopm.make_2dmaps(dic)
        -

        Method to create the 2d maps using pcolormesh

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.make_summary(dic)
        -

        Plot the summary variable

        -
        -
        Args:

        cmdargs (dict): Command arguments

        -
        -
        Returns:

        None

        -
        -
        -
        - -
        -
        -plopm.core.plopm.make_wells(dic)
        -

        If there are any well, we only plot them on the top xy view

        -
        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        -
        - -
        -
        -plopm.core.plopm.map_xycoords(dic)
        -

        Map the properties from the simulations to the 2D slide

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.map_xzcoords(dic)
        -

        Map the properties from the simulations to the 2D slide

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        - -
        -
        -plopm.core.plopm.map_yzcoords(dic)
        -

        Map the properties from the simulations to the 2D slide

        -
        -
        Args:

        dic (dict): Global dictionary

        -
        -
        Returns:

        dic (dict): Modified global dictionary

        -
        -
        -
        -
        plopm.core.plopm.plopm()
        diff --git a/docs/plopm.html b/docs/plopm.html index 201c954..e6b5f3a 100644 --- a/docs/plopm.html +++ b/docs/plopm.html @@ -88,24 +88,11 @@

        Subpackagesplopm.core package
        • Submodules
          • plopm.core.plopm module
          • diff --git a/docs/searchindex.js b/docs/searchindex.js index b355fe7..351ab3c 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({"alltitles": {"About plopm": [[0, "about-plopm"]], "Concept": [[4, "concept"]], "Examples": [[2, "examples"]], "Generic deck": [[2, "generic-deck"]], "Getting started": [[4, "getting-started"]], "Indices and tables": [[3, "indices-and-tables"]], "Installation": [[4, "installation"]], "Introduction": [[4, "introduction"]], "Module contents": [[6, "module-plopm"], [7, "module-plopm.core"]], "Norne": [[2, "norne"]], "Overview": [[4, "overview"]], "Related": [[9, "related"]], "SPE11B": [[2, "spe11b"]], "Submodules": [[7, "submodules"]], "Subpackages": [[6, "subpackages"]], "Welcome to plopm\u2019s documentation!": [[3, "welcome-to-plopm-s-documentation"]], "ad-micp": [[9, "ad-micp"]], "expreccs": [[9, "expreccs"]], "plopm": [[1, "plopm"], [5, "plopm"]], "plopm Python API": [[1, "plopm-python-api"]], "plopm package": [[6, "plopm-package"]], "plopm.core package": [[7, "plopm-core-package"]], "plopm.core.plopm module": [[8, "module-plopm.core.plopm"]], "pycopm": [[9, "pycopm"]], "pymm": [[9, "pymm"]], "pyopmnearwell": [[9, "pyopmnearwell"]], "pyopmspe11": [[9, "pyopmspe11"]]}, "docnames": ["about", "api", "examples", "index", "introduction", "modules", "plopm", "plopm.core", "plopm.core.plopm", "related"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["about.rst", "api.rst", "examples.rst", "index.rst", "introduction.rst", "modules.rst", "plopm.rst", "plopm.core.rst", "plopm.core.plopm.rst", "related.rst"], "indexentries": {}, "objects": {"": [[6, 0, 0, "-", "plopm"]], "plopm": [[7, 0, 0, "-", "core"]], "plopm.core": [[8, 0, 0, "-", "plopm"]], "plopm.core.plopm": [[8, 1, 1, "", "get_kws"], [8, 1, 1, "", "get_mesh"], [8, 1, 1, "", "get_wells"], [8, 1, 1, "", "get_xy_wells"], [8, 1, 1, "", "get_xycoords"], [8, 1, 1, "", "get_xzcoords"], [8, 1, 1, "", "get_yzcoords"], [8, 1, 1, "", "ini_dic"], [8, 1, 1, "", "ini_properties"], [8, 1, 1, "", "ini_readers"], [8, 1, 1, "", "load_parser"], [8, 1, 1, "", "main"], [8, 1, 1, "", "make_2dmaps"], [8, 1, 1, "", "make_summary"], [8, 1, 1, "", "make_wells"], [8, 1, 1, "", "map_xycoords"], [8, 1, 1, "", "map_xzcoords"], [8, 1, 1, "", "map_yzcoords"], [8, 1, 1, "", "plopm"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"]}, "objtypes": {"0": "py:module", "1": "py:function"}, "terms": {"": [2, 4], "0": [2, 4], "0f": 4, "1": [2, 4], "10": 4, "14": [2, 4], "2": 4, "2d": [4, 8], "2f": 2, "331841": 0, "4": 2, "455600": 2, "462200": 2, "50": [], "7319500": 2, "7327100": 2, "A": 9, "For": 2, "If": [2, 8], "The": [0, 1, 2, 4], "Then": 2, "To": 2, "_": [2, 4], "about": 3, "activ": 2, "ad": 3, "add": [], "all": 4, "along": 4, "an": [2, 9], "ani": [4, 8], "api": 3, "approach": [0, 4], "ar": [0, 2, 8, 9], "arg": 8, "argument": [2, 4, 8], "axi": [2, 4], "base": [4, 9], "being": 0, "below": 9, "benchmark": 9, "bound": 4, "c": [2, 4], "calcit": 9, "can": 4, "cell": [2, 4], "center": 0, "cfd": 9, "check": [4, 9], "ci": 4, "class": 8, "cmdarg": 8, "co2": 9, "coarsen": 9, "colormap": 4, "command": 8, "concept": 3, "configur": 2, "content": [1, 3, 4, 5], "contribut": 0, "coordin": 8, "core": [1, 5, 6], "correspond": 4, "creat": 8, "csp": 9, "cssr": 0, "cubehelix": 2, "current": 4, "data": 8, "deck": [3, 4, 8], "default": [2, 4], "defin": 8, "definit": 2, "depth": 4, "describ": 4, "dic": 8, "dict": 8, "dictionari": 8, "document": 4, "download": 2, "dynam": [4, 9], "e": 4, "either": 8, "exampl": [3, 4], "execut": [1, 4, 8], "expans": 9, "exprecc": 3, "f": [2, 4], "fgip": [2, 4], "field": 4, "figur": [2, 4, 8], "file": [2, 4, 8], "fipnum": 4, "flexibl": [4, 9], "flow": [0, 2, 4, 8, 9], "fluid": 4, "folder": [1, 2, 4], "follow": [2, 4], "font": 4, "fork": 0, "format": 4, "framework": [4, 9], "from": [2, 4, 8], "function": 8, "fund": 0, "g": 4, "ga": [2, 4], "gener": [3, 4], "geolog": [0, 4, 8, 9], "get": [3, 8], "get_kw": [6, 7, 8], "get_mesh": [6, 7, 8], "get_wel": [6, 7, 8], "get_xy_wel": [6, 7, 8], "get_xycoord": [6, 7, 8], "get_xzcoord": [6, 7, 8], "get_yzcoord": [6, 7, 8], "github": 4, "given": 4, "global": 8, "grid": 8, "h": 2, "handl": 8, "here": 2, "horda": 9, "i": [0, 1, 2, 4, 8], "imag": 9, "implement": 4, "index": 3, "induc": 9, "ini_d": [6, 7, 8], "ini_properti": [6, 7, 8], "ini_read": [6, 7, 8], "init": 8, "initi": [4, 8], "input": [4, 8], "insid": 2, "inspect": 4, "instal": [2, 3], "interest": 9, "introduct": 3, "j": [4, 8], "jet": 4, "k": [2, 4], "l": [2, 4], "lambda": [2, 4], "last": 4, "leakag": 9, "librari": 4, "load_pars": [6, 7, 8], "locat": [1, 2, 8], "lower": 4, "m": 4, "main": [1, 6, 7, 8], "make_2dmap": [6, 7, 8], "make_summari": [6, 7, 8], "make_wel": [6, 7, 8], "map": [4, 8], "map_xycoord": [6, 7, 8], "map_xzcoord": [6, 7, 8], "map_yzcoord": [6, 7, 8], "mesh": 8, "method": 8, "micp": 3, "microbi": 9, "microsystem": 9, "middl": 4, "might": 9, "model": [0, 2, 4, 8, 9], "modifi": 8, "modul": [1, 3, 5, 9], "more": 0, "n": [2, 4], "name": 4, "nice": 4, "none": 8, "norn": 3, "norne_atw2013": 2, "now": 1, "number": [2, 4], "o": [2, 4], "one": [1, 4], "onli": [1, 8], "open": 9, "opm": [0, 2, 4, 8, 9], "option": [2, 4, 8], "order": 2, "out": 9, "output": 4, "outsid": 2, "overview": [2, 3], "packag": [1, 3, 5], "page": [3, 4], "paper": 4, "part": 4, "pcolormesh": 8, "permx": 4, "permz": 4, "place": [2, 4], "plane": 4, "platform": 9, "plopm": [2, 4], "plot": [0, 2, 4, 8], "png": 4, "pore": 4, "poro": 4, "poros": 4, "porv": 4, "posit": 4, "precipit": 9, "present": 4, "pressur": 4, "progress": 0, "project": [0, 9], "properti": [4, 8], "pull": 0, "py": 2, "pycopm": 3, "pymm": 3, "pyopmnearwel": 3, "pyopmspe11": [2, 3], "python": [3, 4, 9], "quick": 4, "r": [2, 4], "read": 8, "reduc": 2, "relat": 3, "reli": 2, "remedi": 9, "report": 2, "request": 0, "resdata": [2, 4, 8], "resdatafil": 8, "reservoir": 4, "resourc": [0, 9], "restart": 4, "result": 2, "return": 8, "run": 2, "same": [], "satnum": 4, "satur": [2, 4], "scale": 4, "script": [1, 8], "search": 3, "see": [2, 4], "set": [2, 4, 8], "sga": 2, "should": 2, "simplifi": [4, 9], "simul": [2, 8, 9], "size": 4, "slide": [4, 8], "some": [2, 9], "some_input": 4, "some_output_fold": 4, "sourc": [4, 9], "space": 2, "spe10_model2": 2, "spe11": 9, "spe11b": [3, 4], "specifi": 4, "start": 3, "static": [4, 8], "step": 2, "storag": 9, "studi": 9, "submodul": [1, 5, 6], "subpackag": [1, 3, 5], "subsurfac": 0, "succe": 2, "summari": [2, 4, 8], "support": 4, "surfac": 4, "sustain": 0, "termin": 2, "test": [2, 4], "test_generic_deck": 2, "than": 0, "them": [8, 9], "thi": [0, 2, 4], "tool": [0, 2, 4, 9], "top": [2, 8], "type": 2, "u": [2, 4], "unit": 4, "upper": 4, "us": [0, 2, 4, 8, 9], "v": [2, 4], "vairabl": 4, "variabl": [4, 8], "vector": [2, 4], "view": [2, 8], "visual": 4, "volum": 4, "w": [2, 4], "we": [2, 8], "welcom": 0, "well": [2, 4, 8, 9], "were": 2, "where": [2, 4], "white": 2, "work": 0, "x": [2, 4, 8], "xlim": 2, "xy": [2, 4, 8], "xz": [4, 8], "y": [2, 4, 8], "ye": [2, 4], "ylim": 2, "yml": 4, "you": 2, "yz": 8, "z": [2, 4]}, "titles": ["About plopm", "plopm Python API", "Examples", "Welcome to plopm\u2019s documentation!", "Introduction", "plopm", "plopm package", "plopm.core package", "plopm.core.plopm module", "Related"], "titleterms": {"": 3, "about": 0, "ad": 9, "api": 1, "concept": 4, "content": [6, 7], "core": [7, 8], "deck": 2, "document": 3, "exampl": 2, "exprecc": 9, "gener": 2, "get": 4, "indic": 3, "instal": 4, "introduct": 4, "micp": 9, "modul": [6, 7, 8], "norn": 2, "overview": 4, "packag": [6, 7], "plopm": [0, 1, 3, 5, 6, 7, 8], "pycopm": 9, "pymm": 9, "pyopmnearwel": 9, "pyopmspe11": 9, "python": 1, "relat": 9, "spe11b": 2, "start": 4, "submodul": 7, "subpackag": 6, "tabl": 3, "welcom": 3}}) \ No newline at end of file +Search.setIndex({"alltitles": {"About plopm": [[0, "about-plopm"]], "Concept": [[4, "concept"]], "Different input files": [[2, "different-input-files"]], "Examples": [[2, "examples"]], "Generic deck": [[2, "generic-deck"]], "Getting started": [[4, "getting-started"]], "Indices and tables": [[3, "indices-and-tables"]], "Installation": [[4, "installation"]], "Introduction": [[4, "introduction"]], "Module contents": [[6, "module-plopm"], [7, "module-plopm.core"]], "Norne": [[2, "norne"]], "Overview": [[4, "overview"]], "Related": [[9, "related"]], "SPE11B": [[2, "spe11b"]], "Submodules": [[7, "submodules"]], "Subpackages": [[6, "subpackages"]], "Welcome to plopm\u2019s documentation!": [[3, "welcome-to-plopm-s-documentation"]], "ad-micp": [[9, "ad-micp"]], "expreccs": [[9, "expreccs"]], "plopm": [[1, "plopm"], [5, "plopm"]], "plopm Python API": [[1, "plopm-python-api"]], "plopm package": [[6, "plopm-package"]], "plopm.core package": [[7, "plopm-core-package"]], "plopm.core.plopm module": [[8, "module-plopm.core.plopm"]], "pycopm": [[9, "pycopm"]], "pymm": [[9, "pymm"]], "pyopmnearwell": [[9, "pyopmnearwell"]], "pyopmspe11": [[9, "pyopmspe11"]]}, "docnames": ["about", "api", "examples", "index", "introduction", "modules", "plopm", "plopm.core", "plopm.core.plopm", "related"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["about.rst", "api.rst", "examples.rst", "index.rst", "introduction.rst", "modules.rst", "plopm.rst", "plopm.core.rst", "plopm.core.plopm.rst", "related.rst"], "indexentries": {"handle_slide_x() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.handle_slide_x", false]], "handle_slide_y() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.handle_slide_y", false]], "handle_slide_z() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.handle_slide_z", false]], "load_parser() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.load_parser", false]], "main() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.main", false]], "module": [[6, "module-plopm", false], [7, "module-plopm.core", false], [8, "module-plopm.core.plopm", false]], "plopm": [[6, "module-plopm", false]], "plopm() (in module plopm.core.plopm)": [[8, "plopm.core.plopm.plopm", false]], "plopm.core": [[7, "module-plopm.core", false]], "plopm.core.plopm": [[8, "module-plopm.core.plopm", false]]}, "objects": {"": [[6, 0, 0, "-", "plopm"]], "plopm": [[7, 0, 0, "-", "core"]], "plopm.core": [[8, 0, 0, "-", "plopm"]], "plopm.core.plopm": [[8, 1, 1, "", "handle_slide_x"], [8, 1, 1, "", "handle_slide_y"], [8, 1, 1, "", "handle_slide_z"], [8, 1, 1, "", "load_parser"], [8, 1, 1, "", "main"], [8, 1, 1, "", "plopm"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"]}, "objtypes": {"0": "py:module", "1": "py:function"}, "terms": {"": [2, 4], "0": [2, 4], "0f": 4, "1": [2, 4], "10": [2, 4], "11": 4, "14": [2, 4], "16": 4, "2": 4, "2d": [4, 8], "2f": 2, "3": 2, "331841": 0, "4": 2, "455600": 2, "462200": 2, "5": [2, 4], "7319500": 2, "7327100": 2, "8": [2, 4], "A": 9, "For": 2, "If": 2, "In": 4, "The": [0, 1, 2, 4], "Then": 2, "To": 2, "_": [2, 4], "about": [3, 4], "achiev": 2, "activ": [2, 4], "ad": 3, "addit": 4, "all": [1, 4], "along": 4, "an": [2, 9], "ani": [2, 4], "api": 3, "approach": [0, 4], "ar": [0, 2, 9], "arg": 8, "argument": [2, 4, 8], "assum": 2, "axi": [2, 4], "b": [2, 4], "base": [4, 9], "been": 2, "being": 0, "below": 9, "benchmark": 9, "between": [2, 4], "blue": 2, "both": 2, "bound": 4, "c": [2, 4], "calcit": 9, "call": 2, "can": [2, 4], "case": [2, 4], "cell": [2, 4], "center": 0, "cfd": 9, "changu": 2, "check": [4, 9], "ci": 4, "clorbar": 2, "co2": 9, "coarsen": 9, "color": [2, 4], "colormap": [2, 4], "comma": 2, "compar": 2, "concept": 3, "configur": 2, "contain": 1, "content": [1, 3, 4, 5], "contribut": 0, "core": [1, 5, 6], "correspond": 4, "csp": 9, "cssr": 0, "cubehelix": 2, "current": 4, "d": [2, 4], "deck": 3, "default": [2, 4], "definit": 2, "depth": 4, "describ": 4, "dic": 8, "dict": 8, "dictionari": 8, "differ": [1, 3, 4], "dimens": 4, "direct": 4, "dmar": 2, "document": 4, "dot": 2, "download": 2, "dynam": [2, 4, 9], "e": [2, 4], "exampl": [3, 4], "execut": [1, 2, 4, 8], "expans": 9, "exprecc": 3, "f": [2, 4], "fgip": [2, 4], "field": 4, "figur": [2, 4], "file": [3, 4], "final": 4, "fipnum": 4, "first": 2, "flexibl": [4, 9], "flow": [0, 2, 4, 8, 9], "fluid": 4, "folder": [1, 2, 4], "follow": [2, 4], "font": [2, 4], "fork": 0, "format": 4, "framework": [4, 9], "from": [2, 4], "function": 8, "fund": 0, "g": 4, "ga": [2, 4], "gener": [3, 4], "geolog": [0, 4, 8, 9], "get": 3, "github": 4, "give": 2, "given": 4, "global": 8, "grid": [4, 8], "h": 2, "ha": 2, "handl": 1, "handle_slide_i": [6, 7, 8], "handle_slide_x": [6, 7, 8], "handle_slide_z": [6, 7, 8], "have": 2, "here": 2, "horda": 9, "i": [0, 1, 2, 4], "imag": 9, "implement": 4, "inch": 2, "increas": 2, "index": 3, "induc": 9, "inform": 4, "initi": 4, "inject": 2, "input": [3, 4], "insid": 2, "inspect": 4, "instal": [2, 3], "interest": 9, "introduct": 3, "j": 4, "jet": 4, "just": 2, "k": [2, 4], "l": [2, 4], "lambda": [2, 4], "last": 4, "leakag": 9, "let": 2, "librari": 4, "limit": 2, "line": 2, "linestyl": 4, "load_pars": [6, 7, 8], "locat": [1, 2], "look": 2, "lower": [2, 4], "m": 4, "main": [1, 6, 7, 8], "manual": 2, "map": [4, 8], "matplotlib": 4, "method": 1, "micp": 3, "microbi": 9, "microsystem": 9, "middl": 4, "might": 9, "model": [0, 2, 4, 8, 9], "modifi": 8, "modul": [1, 3, 5, 9], "more": [0, 2, 4], "n": [2, 4], "name": 4, "nice": 4, "norn": 3, "norne_atw2013": 2, "number": [2, 4], "o": [2, 4], "obtain": 8, "one": [2, 4], "open": 9, "opm": [0, 2, 4, 8, 9], "option": [2, 4, 8], "order": 2, "out": 9, "output": 4, "outsid": 2, "overview": [2, 3], "packag": [1, 3, 5], "page": [3, 4], "paper": 4, "part": 4, "path": 2, "permx": 4, "permz": 4, "place": [2, 4], "plane": 4, "platform": 9, "plopm": [2, 4], "plot": [0, 1, 2, 4, 8], "png": 4, "pore": 4, "poro": 4, "poros": 4, "porv": 4, "posit": 4, "precipit": 9, "present": 4, "pressur": 4, "process": 8, "progress": 0, "project": [0, 9], "properti": [4, 8], "pull": 0, "py": 2, "pycopm": 3, "pymm": 3, "pyopmnearwel": 3, "pyopmspe11": [2, 3], "python": [3, 4, 9], "quick": 4, "r": [2, 4], "rate": 2, "red": 2, "reduc": 2, "relat": 3, "reli": 2, "remedi": 9, "report": 2, "request": 0, "resdata": [2, 4], "reservoir": 4, "resourc": [0, 9], "restar": 2, "restart": 4, "result": [2, 4], "return": 8, "run": 2, "same": 4, "satnum": 4, "satur": [2, 4], "save": 2, "scale": 4, "script": [1, 8], "search": 3, "see": [2, 4], "select": 8, "separ": [2, 4], "set": [2, 4], "sett": 2, "sga": 2, "should": 2, "simplifi": [4, 9], "simul": [2, 4, 9], "size": [2, 4], "slide": [4, 8], "solid": [2, 4], "some": [2, 9], "some_input": 4, "some_output_fold": 4, "sourc": [4, 9], "space": 2, "spe10_model2": 2, "spe11": 9, "spe11b": [3, 4], "spe11b_larger_inj": 2, "spe11b_tun": 4, "specifi": 4, "start": 3, "static": 4, "step": 2, "storag": 9, "studi": 9, "submodul": [1, 5, 6], "subpackag": [1, 3, 5], "subsurfac": 0, "succe": 2, "summari": [2, 4], "support": 4, "surfac": 4, "sustain": 0, "t": [2, 4], "tab20c": 2, "tcpu": 2, "termin": 2, "test": [2, 4], "test_generic_deck": 2, "than": [0, 2, 4], "them": [4, 9], "thi": [0, 2, 4], "time": 2, "titl": [2, 4], "tool": [0, 2, 4, 9], "top": 2, "two": [2, 4], "type": 2, "u": [2, 4], "unit": 4, "upper": 4, "us": [0, 2, 4, 9], "user": 2, "util": 1, "v": [2, 4], "vairabl": 4, "variabl": [2, 4], "vector": [2, 4], "view": 2, "visual": 4, "volum": 4, "w": [2, 4], "we": 2, "welcom": 0, "well": [2, 4, 9], "were": 2, "where": [2, 4], "white": 2, "work": 0, "x": [2, 4], "xlim": 2, "xy": [2, 4, 8], "xz": [4, 8], "y": [2, 4], "ye": [2, 4], "ylim": 2, "yml": 4, "you": 2, "yz": 8, "z": [2, 4]}, "titles": ["About plopm", "plopm Python API", "Examples", "Welcome to plopm\u2019s documentation!", "Introduction", "plopm", "plopm package", "plopm.core package", "plopm.core.plopm module", "Related"], "titleterms": {"": 3, "about": 0, "ad": 9, "api": 1, "concept": 4, "content": [6, 7], "core": [7, 8], "deck": 2, "differ": 2, "document": 3, "exampl": 2, "exprecc": 9, "file": 2, "gener": 2, "get": 4, "indic": 3, "input": 2, "instal": 4, "introduct": 4, "micp": 9, "modul": [6, 7, 8], "norn": 2, "overview": 4, "packag": [6, 7], "plopm": [0, 1, 3, 5, 6, 7, 8], "pycopm": 9, "pymm": 9, "pyopmnearwel": 9, "pyopmspe11": 9, "python": 1, "relat": 9, "spe11b": 2, "start": 4, "submodul": 7, "subpackag": 6, "tabl": 3, "welcom": 3}}) \ No newline at end of file diff --git a/docs/text/api.rst b/docs/text/api.rst index e2d407c..a256c62 100644 --- a/docs/text/api.rst +++ b/docs/text/api.rst @@ -2,6 +2,8 @@ plopm Python API ================ -The main script (and the only one by now) for the **plopm** executable is located in the `core `_ folder. +The main script for the **plopm** executable is located in the `core `_ folder. +The `utils `_ folder contains all different methods to handle the plotting. + .. include:: modules.rst \ No newline at end of file diff --git a/docs/text/examples.rst b/docs/text/examples.rst index 88f13aa..b6f0d5b 100644 --- a/docs/text/examples.rst +++ b/docs/text/examples.rst @@ -82,4 +82,38 @@ To plot the location of the wells from the top view, then: plopm -i SPE10_MODEL2 -w 1 .. image:: ./figs/wells.png - :scale: 20% \ No newline at end of file + :scale: 20% + +===================== +Different input files +===================== +Let us assume we have two different runs in different folders for the spe11b case, where the firsts results are save +in a folder called spe11b, and simulation results where the injection rate has been increased are saved in a folder +called spe11b_larger_inj. Then, to plot the summary vector for both runs we can execute: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,/Users/dmar/spe11b_larger_inj/SPE11B -v tcpu -d 5,5 -c r,b -e 'solid;:' -t 'Comparing the simulation times' -f 10 + +.. image:: ./figs/tcpu.png + +Here, we have lower the size of the figure to 5,5 inches, set to use red and blue colors with solid and dotted lines, as well as settting the title and lower the font size to 10. + +.. tip:: + For any summary variable, one can give the path to more than two different simulation cases, just by separating the folder paths by commas in the -i. + +To look at the difference between these two simulations for the dynamic variable sgas at the restar step 3, this can be achieved by executing: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3 + +.. image:: ./figs/sgas_diff.png + +To changue the colormap and setting the clorbar limits manually, this can be achieved by: + +.. code-block:: bash + + plopm -i spe11b/SPE11B,spe11b_larger_inj/SPE11B -v sgas -r 3 -c tab20c -b '[-0.8,0]' + +.. image:: ./figs/sgas_diff_edit.png diff --git a/docs/text/figs/sgas_diff.png b/docs/text/figs/sgas_diff.png new file mode 100644 index 0000000..df68c1a Binary files /dev/null and b/docs/text/figs/sgas_diff.png differ diff --git a/docs/text/figs/sgas_diff_edit.png b/docs/text/figs/sgas_diff_edit.png new file mode 100644 index 0000000..e0e11dd Binary files /dev/null and b/docs/text/figs/sgas_diff_edit.png differ diff --git a/docs/text/figs/tcpu.png b/docs/text/figs/tcpu.png new file mode 100644 index 0000000..f735d80 Binary files /dev/null and b/docs/text/figs/tcpu.png differ diff --git a/docs/text/introduction.rst b/docs/text/introduction.rst index 80553e3..4bccd16 100644 --- a/docs/text/introduction.rst +++ b/docs/text/introduction.rst @@ -14,7 +14,8 @@ and dynamic (e.g., pressure, fluid saturations) properties given any 2D slide (e as well as plotting any given summary vector (e.g., field gas in place a.k.a fgip). The **plopm** tool can be useful for quick inspection of geological models, as well as for generation of nice -figures for papers/presentations. +figures for papers/presentations. In addition, **plopm** can plot summary results from different simulation cases in the same figure, +as well as the difference between given dynamic variables (e.g., pressure) for two different simulations cases. .. _overview: @@ -28,20 +29,26 @@ The current implementation supports the following executable with the argument o where -- \-i: The base name of the input deck and output files (`SPE11B` by default). -- \-o: The base name of the output folder (`output` by default). +- \-i: The base name of the input files; if more than one is given, separate them by ',' (e.g, 'SPE11B,SPE11B_TUNED') (`SPE11B` by default). +- \-o: The base name of the output folder (`.` by default). - \-f: The font size (`14` by default). - \-s: The slide for the 2D maps of the static variables, e.g, `10,,` to plot the xz plane on all cells with i=10 (`,1,` by default, i.e., the xz surface at j=1). - \-x: Option to set the lower and upper bounds in the 2D map along x ('' by default). - \-y: Option to set the lower and upper bounds in the 2D map along y ('' by default). -- \-z: The option to scale the axis in the 2d maps (`yes` by default). +- \-z: The option to scale the axis in the 2D maps (`yes` by default). - \-u: Use resdata or opm Python libraries (`resdata` by default). - \-v: Specify the name of the static vairable to plot (e.g., `depth`) ('' by default, i.e., plotting: porv, permx, permz, poro, fipnum, and satnum). -- \-c: Specify the colormap (e.g., `jet`) (' by default, i.e., set by plopm). +- \-c: Specify the colormap (e.g., `jet`) ('' by default, i.e., set by plopm). - \-n: Specify the format for the numbers in the colormap (e.g., "lambda x, _: f'{x:.0f}'") ('' by default, i.e., set by plopm). -- \-l: Specify the units (e.g., \"[m\\$^2\\$]\") (`` by default, i.e., set by plopm). +- \-l: Specify the units (e.g., \"[m\\$^2\\$]\") ('' by default, i.e., set by plopm). +- \-r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one ('-1' by default, i.e., the last restart file). +- \-w: Plot the positions of the wells or sources ('0' by default). +- \-g: Plot information about the number of cells in the x, y, and z directions and number of active grid cells ('0' by default). +- \-e: Specify the linestyles separated by ';' (e.g., 'solid;:') ('' by default, i.e., set by plopm). +- \-b: Specify the upper and lower bounds for the color map (e.g., '[-0.1,11]') ('' by default, i.e., set by matplotlib). +- \-d: Specify the dimensions of the Figure (e.g., '5,5') ('8,16' by default). +- \-t: Specify the figure title (e.g., 'Final saturation map') ('' by default, i.e., set by plopm). - \-r: Restart number to plot the dynamic variable, where 1 corresponds to the initial one ('-1' by default, i.e., the last restart file). -- \-w: Plot the xz-position of the wells or sources ('0' by default). Installation ------------ diff --git a/src/plopm/core/plopm.py b/src/plopm/core/plopm.py index b2ea3c5..6929ca7 100755 --- a/src/plopm/core/plopm.py +++ b/src/plopm/core/plopm.py @@ -10,7 +10,8 @@ import numpy as np from plopm.utils.initialization import ini_dic, ini_properties, ini_readers from plopm.utils.readers import ( - get_kws, + get_kws_resdata, + get_kws_opm, get_wells, get_xycoords_resdata, get_xycoords_opm, @@ -29,7 +30,10 @@ def plopm(): dic = ini_dic(cmdargs) ini_properties(dic) ini_readers(dic) - get_kws(dic) + if dic["use"] == "resdata": + get_kws_resdata(dic) + else: + get_kws_opm(dic) if len(dic["vsum"]) > 0: make_summary(dic) return @@ -118,13 +122,15 @@ def handle_slide_z(dic): def load_parser(): """Argument options""" parser = argparse.ArgumentParser( - description="plopm, a Python tool to plot 2D surfaces" " from OPM simulations.", + description="plopm: Simplified and flexible Python tool for quick " + "visualization of OPM Flow geological models.", ) parser.add_argument( "-i", "--input", default="SPE11B", - help="The base name of the deck ('SPE11B' by default).", + help="The base name of the input files; if more than one is given, separate " + "them by ',' (e.g, 'SPE11B,SPE11B_TUNED') ('SPE11B' by default).", ) parser.add_argument( "-o", @@ -181,8 +187,15 @@ def load_parser(): "-c", "--colormap", default="", - help="Specify the colormap (e.g., 'jet') ('' by default, i.e., set by " - " plopm).", + help="Specify the colormap (e.g., 'jet') or color(s) for the summary " + "(e.g., 'b,r') ('' by default, i.e., set by plopm).", + ) + parser.add_argument( + "-e", + "--linsty", + default="", + help="Specify the linestyles separated by ';' (e.g., 'solid;:') ('' by default, " + "i.e., set by plopm).", ) parser.add_argument( "-n", @@ -191,6 +204,20 @@ def load_parser(): help="Specify the format for the numbers in the colormap (e.g., " "\"lambda x, _: f'{x:.0f}'\") ('' by default, i.e., set by plopm).", ) + parser.add_argument( + "-b", + "--bounds", + default="", + help="Specify the upper and lower bounds for the colormap (e.g., " + " '[-0.1,11]') ('' by default, i.e., set by matplotlib).", + ) + parser.add_argument( + "-d", + "--dimensions", + default="8,16", + help="Specify the dimensions of the Figure (e.g., " + " '5,5') ('8,16' by default).", + ) parser.add_argument( "-l", "--legend", @@ -198,6 +225,13 @@ def load_parser(): help="Specify the units (e.g., \"[m\$^2\$]\") ('' by " "default, i.e., set by plopm).", ) + parser.add_argument( + "-t", + "--title", + default="", + help="Specify the figure title (e.g., 'Final saturation map') ('' by " + "default, i.e., set by plopm).", + ) parser.add_argument( "-r", "--restart", diff --git a/src/plopm/utils/initialization.py b/src/plopm/utils/initialization.py index 69438e6..d3bcd9d 100755 --- a/src/plopm/utils/initialization.py +++ b/src/plopm/utils/initialization.py @@ -37,18 +37,26 @@ def ini_dic(cmdargs): dic (dict): Modified global dictionary """ - dic = {"name": cmdargs["input"].strip()} + dic = {"output": cmdargs["output"].strip()} + names = (cmdargs["input"].strip()).split(",") + dic["names"], dic["name"] = names, names[0] + if len(names) > 1: + dic["names"] = names dic["coords"] = ["x", "y", "z"] dic["scale"] = cmdargs["scale"].strip() dic["use"] = cmdargs["use"].strip() dic["variable"] = cmdargs["variable"].strip() dic["size"] = float(cmdargs["size"]) dic["legend"] = cmdargs["legend"].strip() + dic["titles"] = cmdargs["title"].strip() + dic["bounds"] = (cmdargs["bounds"].strip()).split(",") + dic["dims"] = (cmdargs["dimensions"].strip()).split(",") dic["numbers"] = cmdargs["numbers"].strip() + dic["linsty"] = cmdargs["linsty"].strip() dic["colormap"] = cmdargs["colormap"].strip() - dic["output"] = cmdargs["output"].strip() dic["xlim"], dic["ylim"], dic["wells"], dic["vsum"] = [], [], [], [] - dic["grid"] = [] + dic["grid"], dic["summary"], dic["vsum"], dic["time"] = [], [], [], [] + dic["unrst"] = [] dic["dtitle"] = "" dic["restart"] = int(cmdargs["restart"]) dic["well"] = int(cmdargs["wells"]) @@ -87,9 +95,11 @@ def ini_readers(dic): dic["ny"] = dic["egrid"].ny dic["nz"] = dic["egrid"].nz if os.path.isfile(f"{dic['name']}.UNRST"): - dic["unrst"] = ResdataFile(f"{dic['name']}.UNRST") + for name in dic["names"]: + dic["unrst"].append(ResdataFile(f"{name}.UNRST")) if os.path.isfile(f"{dic['name']}.SMSPEC"): - dic["summary"] = Summary(f"{dic['name']}.SMSPEC") + for name in dic["names"]: + dic["summary"].append(Summary(f"{name}.SMSPEC")) else: dic["egrid"] = OpmGrid(f"{dic['name']}.EGRID") dic["init"] = OpmFile(f"{dic['name']}.INIT") @@ -97,11 +107,27 @@ def ini_readers(dic): dic["ny"] = dic["egrid"].dimension[1] dic["nz"] = dic["egrid"].dimension[2] if os.path.isfile(f"{dic['name']}.UNRST"): - dic["unrst"] = OpmFile(f"{dic['name']}.UNRST") + for name in dic["names"]: + dic["unrst"].append(OpmFile(f"{name}.UNRST")) if os.path.isfile(f"{dic['name']}.SMSPEC"): - dic["summary"] = OpmSummary(f"{dic['name']}.SMSPEC") + for name in dic["names"]: + dic["summary"].append(OpmSummary(f"{name}.SMSPEC")) if not os.path.exists(dic["output"]): os.system(f"mkdir {dic['output']}") + ini_slides(dic) + + +def ini_slides(dic): + """ + Initialize dictionary entries used for the 2D maps + + Args: + dic (dict): Global dictionary + + Returns: + dic (dict): Modified global dictionary + + """ if dic["slide"][0] > -1: dic["mx"], dic["my"] = 2 * dic["ny"] - 1, 2 * dic["nz"] - 1 dic["xmeaning"], dic["ymeaning"] = "y", "z" @@ -124,34 +150,40 @@ def ini_properties(dic): dic (dict): Modified global dictionary """ + dic["colors"] = [ + "#ff7f0e", + "#2ca02c", + "#d62728", + "#9467bd", + "#8c564b", + "#e377c2", + "#7f7f7f", + "#bcbd22", + "#17becf", + "#1f77b4", + "r", + ] + dic["linestyle"] = [ + "-", + "--", + (0, (1, 1)), + "-.", + (0, (1, 10)), + (0, (1, 1)), + (5, (10, 3)), + (0, (5, 10)), + (0, (5, 5)), + (0, (5, 1)), + (0, (3, 10, 1, 10)), + (0, (3, 5, 1, 5)), + (0, (3, 1, 1, 1)), + (0, (3, 5, 1, 5, 1, 5)), + (0, (3, 10, 1, 10, 1, 10)), + (0, (3, 1, 1, 1, 1, 1)), + (0, ()), + ] if dic["variable"]: - dic["props"] = [dic["variable"]] - if dic["variable"].lower() in ["disperc", "depth", "dx", "dy", "dz"]: - dic["units"] = [" [m]"] - dic["cmaps"] = ["jet"] - dic["format"] = [lambda x, _: f"{x:.2e}"] - elif dic["variable"].lower() in ["porv"]: - dic["units"] = [r" [m$^3$]"] - dic["cmaps"] = ["terrain"] - dic["format"] = [lambda x, _: f"{x:.2e}"] - elif dic["variable"].lower() in ["permx", "permy", "permz"]: - dic["units"] = [" [mD]"] - dic["cmaps"] = ["turbo"] - dic["format"] = [lambda x, _: f"{x:.0f}"] - elif "num" in dic["variable"].lower(): - dic["units"] = [" [-]"] - dic["cmaps"] = ["tab20b"] - dic["format"] = [lambda x, _: f"{x:.2f}"] - else: - dic["units"] = [" [-]"] - dic["cmaps"] = ["gnuplot"] - dic["format"] = [lambda x, _: f"{x:.0f}"] - if dic["legend"]: - dic["units"] = [f" {dic['legend']}"] - if dic["numbers"]: - dic["format"] = [eval(dic["numbers"])] - if dic["colormap"]: - dic["cmaps"] = [dic["colormap"]] + initialize_variable(dic) else: dic["props"] = [ "porv", @@ -203,7 +235,55 @@ def ini_properties(dic): "lines.linewidth": 4, "axes.titlesize": dic["size"], "axes.grid": False, - "figure.figsize": (8, 16), + "figure.figsize": (int(dic["dims"][0]), int(dic["dims"][1])), } ) dic["xc"], dic["yc"] = [], [] + + +def initialize_variable(dic): + """ + Initialize the properties according to the given variable + + Args: + dic (dict): Global dictionary + + Returns: + dic (dict): Modified global dictionary + + """ + dic["props"] = [dic["variable"]] + if dic["variable"].lower() in ["disperc", "depth", "dx", "dy", "dz"]: + dic["units"] = [" [m]"] + dic["cmaps"] = ["jet"] + dic["format"] = [lambda x, _: f"{x:.2e}"] + elif dic["variable"].lower() in ["porv"]: + dic["units"] = [r" [m$^3$]"] + dic["cmaps"] = ["terrain"] + dic["format"] = [lambda x, _: f"{x:.2e}"] + elif dic["variable"].lower() in ["permx", "permy", "permz"]: + dic["units"] = [" [mD]"] + dic["cmaps"] = ["turbo"] + dic["format"] = [lambda x, _: f"{x:.0f}"] + elif "num" in dic["variable"].lower(): + dic["units"] = [" [-]"] + dic["cmaps"] = ["tab20b"] + dic["format"] = [lambda x, _: f"{x:.2f}"] + else: + dic["units"] = [" [-]"] + dic["cmaps"] = ["gnuplot"] + dic["format"] = [lambda x, _: f"{x:.0f}"] + if dic["legend"]: + dic["units"] = [f" {dic['legend']}"] + if len(dic["names"]) == 2: + dic["cmaps"] = ["seismic"] + if dic["variable"].lower() in ["pressure"]: + dic["units"] = [" [bar]"] + if dic["variable"].lower() in ["sgas", "rsw"]: + dic["format"] = [lambda x, _: f"{x:.2f}"] + if dic["variable"].lower() in ["rvw"]: + dic["format"] = [lambda x, _: f"{x:.2e}"] + if dic["colormap"]: + dic["cmaps"] = [dic["colormap"]] + if dic["numbers"]: + dic["format"] = [eval(dic["numbers"])] diff --git a/src/plopm/utils/readers.py b/src/plopm/utils/readers.py index 316cef7..5c0de47 100644 --- a/src/plopm/utils/readers.py +++ b/src/plopm/utils/readers.py @@ -243,7 +243,7 @@ def get_xycoords_opm(dic): ) -def get_kws(dic): +def get_kws_resdata(dic): """ Get the static properties from the INIT file using ResdataFile @@ -255,44 +255,69 @@ def get_kws(dic): """ for name in dic["props"]: - if dic["use"] == "resdata": - if dic["init"].has_kw(name.upper()): - dic[name] = np.array(dic["init"].iget_kw(name.upper())[0]) - elif dic["unrst"].has_kw(name.upper()): + if dic["init"].has_kw(name.upper()): + dic[name] = np.array(dic["init"].iget_kw(name.upper())[0]) + elif dic["unrst"][0].has_kw(name.upper()): + if len(dic["names"]) == 1: dic[name] = np.array( - dic["unrst"].iget_kw(name.upper())[dic["restart"] - 1] + dic["unrst"][0].iget_kw(name.upper())[dic["restart"] - 1] ) - ntot = len(dic["unrst"].iget_kw(name.upper())) - dic["dtitle"] = ( - f", rst {ntot if dic['restart']==0 else dic['restart']} out of {ntot}" - ) - elif dic["summary"].has_key(name.upper()): - dic["vsum"] = dic["summary"][name.upper()].values - dic["time"] = dic["summary"]["TIME"].values - return - else: - if dic["init"].count(name.upper()): - dic[name] = np.array(dic["init"][name.upper()]) - elif dic["unrst"].count(name.upper()): - nrst = ( - dic["restart"] - 1 - if dic["restart"] > 0 - else dic["unrst"].count(name.upper()) - 1 - ) - dic[name] = np.array(dic["unrst"][name.upper(), nrst]) - ntot = dic["unrst"].count(name.upper()) - dic["dtitle"] = ( - f", rst {ntot if dic['restart']==0 else dic['restart']} out of {ntot}" + else: + dic[name] = np.array( + dic["unrst"][0].iget_kw(name.upper())[dic["restart"] - 1] + ) - np.array(dic["unrst"][1].iget_kw(name.upper())[dic["restart"] - 1]) + ntot = len(dic["unrst"][0].iget_kw(name.upper())) + dic["dtitle"] = ( + f", rst {ntot if dic['restart']==0 else dic['restart']} out of {ntot}" + ) + elif dic["summary"][0].has_key(name.upper()): + for i, _ in enumerate(dic["names"]): + dic["vsum"].append(dic["summary"][i][name.upper()].values) + dic["time"].append(dic["summary"][i]["TIME"].values) + return + dic[name + "a"] = np.ones(dic["mx"] * dic["my"]) * np.nan + dic["porv"] = np.array(dic["init"].iget_kw("PORV")[0]) + dic["porva"] = np.ones(dic["mx"] * dic["my"]) * np.nan + dic["actind"] = np.cumsum([1 if porv > 0 else 0 for porv in dic["porv"]]) - 1 + + +def get_kws_opm(dic): + """ + Get the static properties from the INIT file using Opm + + Args: + dic (dict): Global dictionary + + Returns: + dic (dict): Modified global dictionary + + """ + for name in dic["props"]: + if dic["init"].count(name.upper()): + dic[name] = np.array(dic["init"][name.upper()]) + elif dic["unrst"][0].count(name.upper()): + nrst = ( + dic["restart"] - 1 + if dic["restart"] > 0 + else dic["unrst"][0].count(name.upper()) - 1 + ) + if len(dic["names"]) == 1: + dic[name] = np.array(dic["unrst"][0][name.upper(), nrst]) + else: + dic[name] = np.array(dic["unrst"][0][name.upper(), nrst]) - np.array( + dic["unrst"][1][name.upper(), nrst] ) - elif name.upper() in dic["summary"].keys(): - dic["vsum"] = dic["summary"][name.upper()] - dic["time"] = dic["summary"]["TIME"] - return + ntot = dic["unrst"][0].count(name.upper()) + dic["dtitle"] = ( + f", rst {ntot if dic['restart']==0 else dic['restart']} out of {ntot}" + ) + elif name.upper() in dic["summary"][0].keys(): + for i, _ in enumerate(dic["names"]): + dic["vsum"].append(dic["summary"][i][name.upper()]) + dic["time"].append(dic["summary"][i]["TIME"]) + return dic[name + "a"] = np.ones(dic["mx"] * dic["my"]) * np.nan - if dic["use"] == "opm": - dic["porv"] = np.array(dic["init"]["PORV"]) - else: - dic["porv"] = np.array(dic["init"].iget_kw("PORV")[0]) + dic["porv"] = np.array(dic["init"]["PORV"]) dic["porva"] = np.ones(dic["mx"] * dic["my"]) * np.nan dic["actind"] = np.cumsum([1 if porv > 0 else 0 for porv in dic["porv"]]) - 1 diff --git a/src/plopm/utils/write.py b/src/plopm/utils/write.py index 45d05bb..4e5b05b 100644 --- a/src/plopm/utils/write.py +++ b/src/plopm/utils/write.py @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2024 NORCE # SPDX-License-Identifier: GPL-3.0 +# pylint: disable=W3301 """ Utiliy functions to write the PNGs figures. @@ -22,30 +23,53 @@ def make_summary(dic): None """ + if ( + len(dic["cmaps"][0].split(",")) == len(dic["names"]) + and dic["cmaps"][0] != "gnuplot" + ): + dic["colors"] = dic["cmaps"][0].split(",") + if len(dic["linsty"].split(";")) == len(dic["names"]) and dic["linsty"]: + dic["linestyle"] = dic["linsty"].split(";") plt.rcParams.update({"axes.grid": True}) fig, axis = plt.subplots() - if len(dic["cmaps"]) == 1: - axis.step(dic["time"], dic["vsum"], color=dic["cmaps"][0]) - else: - axis.step(dic["time"], dic["vsum"], color="b") + min_t, min_v = min(dic["time"][0]), min(dic["vsum"][0]) + max_t, max_v = max(dic["time"][0]), max(dic["vsum"][0]) + for i, name in enumerate(dic["names"]): + label = name + if len(name.split("/")) > 1: + label = name.split("/")[-2] + "/" + name.split("/")[-1] + axis.step( + dic["time"][i], + dic["vsum"][i], + color=dic["colors"][i], + ls=dic["linestyle"][i], + label=label, + ) + min_t = min(min_t, min(dic["time"][i])) + min_v = min(min_v, min(dic["vsum"][i])) + max_t = max(max_t, max(dic["time"][i])) + max_v = max(max_v, max(dic["vsum"][i])) axis.set_ylabel(dic["props"][0]) axis.set_xlabel("Time [s]") - axis.set_xlim([min(dic["time"]), max(dic["time"])]) - axis.set_ylim([min(dic["vsum"]), max(dic["vsum"])]) + axis.set_xlim([min_t, max_t]) + axis.set_ylim([min_v, max_v]) axis.set_xticks( np.linspace( - min(dic["time"]), - max(dic["time"]), + min_t, + max_t, 4, ) ) axis.set_yticks( np.linspace( - min(dic["vsum"]), - max(dic["vsum"]), + min_v, + max_v, 4, ) ) + axis.legend() + if dic["titles"] != "": + axis.set_title(dic["titles"]) fig.savefig(f"{dic['output']}/{dic['variable']}.png", bbox_inches="tight", dpi=300) plt.close() @@ -81,6 +105,13 @@ def make_2dmaps(dic): if dic["well"] != 1 and dic["grid"] != 1: minc = dic[name][~np.isnan(dic[name])].min() maxc = dic[name][~np.isnan(dic[name])].max() + if len(dic["bounds"]) == 2: + minc = float(dic["bounds"][0][1:]) + maxc = float(dic["bounds"][1][:-1]) + elif len(dic["names"]) == 2: + minmax = max(abs(maxc), abs(minc)) + minc = -minmax + maxc = minmax if maxc == minc: ntick = 1 elif name in ["fipnum", "satnum"]: @@ -143,6 +174,8 @@ def handle_axis(dic, axis, name): f"Grid = [{dic['nx']},{dic['ny']},{dic['nz']}], " + f"Total no. active cells = {max(dic['actind'])+1}" ) + if dic["titles"] != "": + axis.set_title(dic["titles"]) if dic["slide"][2] == -2: axis.invert_yaxis() axis.set_xticks( diff --git a/tests/test_difference.py b/tests/test_difference.py new file mode 100644 index 0000000..b174dba --- /dev/null +++ b/tests/test_difference.py @@ -0,0 +1,16 @@ +"""Test the difference functionality""" + +import os +import subprocess + + +def test_difference(): + """See examples/SPE11B""" + cwd = os.getcwd() + os.chdir(f"{os.getcwd()}/examples") + subprocess.run( + ["plopm", "-i", "SPE11B,SPE11B", "-o", ".", "-v", "rsw"], + check=True, + ) + assert os.path.exists(f"{cwd}/examples/rsw_*,1,*.png") + os.chdir(cwd)