TNO Intern

Commit 23e40f76 authored by Florian Knappers's avatar Florian Knappers
Browse files

docs examples to new usage

parent 92d37617
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@ from pathlib import Path

import typer

from pytg3.aquifer import Aquifer
from pytg3.doublet import ThermoGISDoublet
from pythermogis.pytg3.aquifer import Aquifer
from pythermogis.pytg3.doublet import ThermoGISDoublet
from pythermogis.potential import calculate_potential
from pythermogis.properties import instantiate_thermogis_parameters

+11 −0
Original line number Diff line number Diff line
@@ -48,12 +48,23 @@ class BaseAquifer(BaseModel):
    ) -> None:
        raise NotImplementedError

    def to_dataset(self) -> xr.Dataset:
        return xr.Dataset(
            {
                field_name: value
                for field_name, value in self
                if isinstance(value, xr.DataArray)
            }
        )



class Aquifer(BaseAquifer):
    thickness: FloatOrArray
    permeability: FloatOrArray | None = None
    transmissivity: FloatOrArray | None = None


    @model_validator(mode="after")
    def check_permeability_or_transmissivity(self) -> Aquifer:
        has_perm = self.permeability is not None
+120 −107
Original line number Diff line number Diff line
@@ -6,29 +6,23 @@ import xarray as xr
from matplotlib import pyplot as plt
from pygridsio import plot_grid, read_grid, resample_grid

from pythermogis.doublet import (
    calculate_doublet_performance,
    calculate_doublet_performance_stochastic,
)
from pythermogis.pytg3.aquifer import Aquifer, StochasticAquifer
from pythermogis.pytg3.settings import Settings
from pythermogis.pytg3.doublet import ThermoGISDoublet
from pythermogis.plot import plot_exceedance
from pythermogis.postprocess import calculate_pos
from pythermogis.properties import instantiate_thermogis_parameters


def test_example_1():
    import xarray as xr

    input_data = xr.Dataset(
        {
            "thickness": 300,
            "ntg": 0.5,
            "porosity": 0.2,
            "depth": 2000,
            "permeability": 300,
        }
    aquifer = Aquifer(
        thickness=300,
        ntg=0.5,
        porosity=0.2,
        depth=2000,
        permeability=300
    )

    results = calculate_doublet_performance(input_data)
    results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset()
    print(results)


@@ -44,42 +38,38 @@ def test_example_2():
        coords={"x": [0, 1], "y": [10, 20]},
    )

    results = calculate_doublet_performance(input_data)
    aquifer = Aquifer(
        thickness=input_data["thickness"],
        ntg=input_data["ntg"],
        porosity=input_data["porosity"],
        depth=input_data["depth"],
        permeability=input_data["permeability"],
    )


    results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset()
    print(results)


def test_example_3():
    input_data = xr.Dataset(
        {
            "thickness": 300,
            "ntg": 0.5,
            "porosity": 0.2,
            "depth": 2000,
            "permeability": 300,
        }
    )

    tg_properties = instantiate_thermogis_parameters()
    tg_properties.setUseHeatpump(True)
    utc_properties = tg_properties.setupUTCParameters()
    results = calculate_doublet_performance(input_data, utc_properties=utc_properties)
    aquifer = Aquifer(
        thickness=300, ntg=0.5, porosity=0.2, depth=2000, permeability=300
    )

    settings = Settings()
    settings.set_use_heatpump(True)

    results = ThermoGISDoublet(aquifer=aquifer, settings=settings).simulate().to_dataset()

    print(results)


def test_example_4():
    input_data = xr.Dataset(
        {
            "thickness_mean": 300,
            "thickness_sd": 50,
            "ntg": 0.5,
            "porosity": 0.2,
            "depth": 2000,
            "ln_permeability_mean": 4,
            "ln_permeability_sd": 0.5,
        }
    aquifer = StochasticAquifer(
        thickness_mean=300, thickness_sd=50, ntg=0.5, porosity=0.2, depth=2000, ln_permeability_mean=4, ln_permeability_sd=0.5
    )
    results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[50]).to_dataset()

    results = calculate_doublet_performance_stochastic(input_data)
    print(results)


@@ -89,25 +79,24 @@ def test_example_5():
    )
    output_data_path.mkdir(parents=True, exist_ok=True)

    input_data = xr.Dataset(
        {
            "thickness_mean": 300,
            "thickness_sd": 50,
            "ntg": 0.5,
            "porosity": 0.2,
            "depth": 2000,
            "ln_permeability_mean": 5,
            "ln_permeability_sd": 0.5,
        }
    )
    results = calculate_doublet_performance_stochastic(
        input_data, p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99]
    aquifer = StochasticAquifer(
        thickness_mean=300,
        thickness_sd=50,
        ntg=0.5,
        porosity=0.2,
        depth=2000,
        ln_permeability_mean=5,
        ln_permeability_sd=0.5,
    )

    results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99]).to_dataset()


    fig, axe = plt.subplots(figsize=(10, 5))
    kh = results.transmissivity_with_ntg * 1.0
    kh.plot(y="p_value", ax=axe)
    axe.set_title("Aquifer Net transmissivity\n kH")
    temp = input_data.temperature
    temp = aquifer.temperature
    inj_temp = results.inj_temp.sel(p_value=50, method="nearest")
    prd_temp = results.prd_temp.sel(p_value=50, method="nearest")
    axe.axhline(
@@ -129,12 +118,12 @@ def test_example_6():
    # the location of the input data:
    # the data can be found in the resources/example_data directory of the repo
    input_data_path = (
        Path(__file__).parent.parent / "resources" / "test_input" / "example_data"
        Path(__file__).parent / "resources" / "test_input" / "example_data"
    )

    # create a directory to write the output files to
    output_data_path = (
        Path(__file__).parent.parent / "resources" / "test_output" / "example6"
        Path(__file__).parent / "resources" / "test_output" / "example6"
    )
    output_data_path.mkdir(parents=True, exist_ok=True)

@@ -145,37 +134,47 @@ def test_example_6():
    # grids can be in .nc, .asc, .zmap or .tif format: see pygridsio package
    new_cellsize = 5000  # in m, this sets the resolution of the model;
    # to speed up calcualtions you can increase the cellsize
    reservoir_properties = resample_grid(
    thickness_mean = resample_grid(
        read_grid(input_data_path / "ROSL_ROSLU__thick.zmap"), new_cellsize=new_cellsize
    ).to_dataset(name="thickness_mean")
    reservoir_properties["thickness_sd"] = resample_grid(
    )
    thickness_sd = resample_grid(
        read_grid(input_data_path / "ROSL_ROSLU__thick_sd.zmap"),
        new_cellsize=new_cellsize,
    )
    reservoir_properties["ntg"] = resample_grid(
    ntg = resample_grid(
        read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap"), new_cellsize=new_cellsize
    )
    reservoir_properties["porosity"] = (
    porosity = (
        resample_grid(
            read_grid(input_data_path / "ROSL_ROSLU__poro.zmap"),
            new_cellsize=new_cellsize,
        )
        / 100
    )
    reservoir_properties["depth"] = resample_grid(
    depth = resample_grid(
        read_grid(input_data_path / "ROSL_ROSLU__top.zmap"), new_cellsize=new_cellsize
    )
    reservoir_properties["ln_permeability_mean"] = np.log(
    ln_permeability_mean = np.log(
        resample_grid(
            read_grid(input_data_path / "ROSL_ROSLU__perm.zmap"),
            new_cellsize=new_cellsize,
        )
    )
    reservoir_properties["ln_permeability_sd"] = resample_grid(
    ln_permeability_sd = resample_grid(
        read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap"),
        new_cellsize=new_cellsize,
    )

    aquifer = StochasticAquifer(
        thickness_mean=thickness_mean,
        thickness_sd=thickness_sd,
        ntg=ntg,
        porosity=porosity,
        depth=depth,
        ln_permeability_mean=ln_permeability_mean,
        ln_permeability_sd=ln_permeability_sd,
    )

    # output inputs
    variables_to_plot = ["depth", "thickness_mean", "thickness_sd"]
    fig, axes = plt.subplots(
@@ -187,7 +186,7 @@ def test_example_6():
    )
    for i, variable in enumerate(variables_to_plot):
        plot_grid(
            reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True
            getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True
        )  # See documentation on plot_grid in pygridsio,
        # you can also provide your own shapefile
    plt.tight_layout()  # ensure there is enough spacing
@@ -203,7 +202,7 @@ def test_example_6():
    )
    for i, variable in enumerate(variables_to_plot):
        plot_grid(
            reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True
            getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True
        )  # See documentation on plot_grid in pygridsio,
        # you can also provide your own shapefile
    plt.tight_layout()  # ensure there is enough spacing
@@ -215,9 +214,8 @@ def test_example_6():
    if (output_data_path / "output_results.nc").exists and not run_simulation:
        results = xr.load_dataset(output_data_path / "output_results.nc")
    else:
        results = calculate_doublet_performance_stochastic(
            reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]
        )

        results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset()
        results.to_netcdf(
            output_data_path / "output_results.nc"
        )  # write doublet simulation results to file
@@ -284,22 +282,28 @@ def test_example_7():
    output_data_path.mkdir(parents=True, exist_ok=True)

    # read in reservoir property maps
    reservoir_properties = read_grid(
    thickness_mean = read_grid(
        input_data_path / "ROSL_ROSLU__thick.zmap"
    ).to_dataset(name="thickness_mean")
    reservoir_properties["thickness_sd"] = read_grid(
    )
    thickness_sd = read_grid(
        input_data_path / "ROSL_ROSLU__thick_sd.zmap"
    )
    reservoir_properties["ntg"] = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap")
    reservoir_properties["porosity"] = 0.01 * read_grid(
    ntg = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap")
    porosity = 0.01 * read_grid(
        input_data_path / "ROSL_ROSLU__poro.zmap"
    )
    reservoir_properties["depth"] = read_grid(input_data_path / "ROSL_ROSLU__top.zmap")
    reservoir_properties["ln_permeability_mean"] = np.log(
        read_grid(input_data_path / "ROSL_ROSLU__perm.zmap")
    )
    reservoir_properties["ln_permeability_sd"] = read_grid(
        input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap"
    depth = read_grid(input_data_path / "ROSL_ROSLU__top.zmap")
    ln_permeability_mean = np.log(read_grid(input_data_path / "ROSL_ROSLU__perm.zmap"))
    ln_permeability_sd = read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap")

    aquifer = StochasticAquifer(
        thickness_mean=thickness_mean,
        thickness_sd=thickness_sd,
        ntg=ntg,
        porosity=porosity,
        depth=depth,
        ln_permeability_mean=ln_permeability_mean,
        ln_permeability_sd=ln_permeability_sd,
    )

    # Select locations of interest from the reservoir
@@ -313,16 +317,18 @@ def test_example_7():
    ]

    # Collect selected locations, create a new Dataset with the coordinate 'location'
    aquifer_ds = aquifer.to_dataset()

    locations = []
    for i, (x, y) in enumerate(portfolio_coords):
        point = reservoir_properties.sel(x=x, y=y, method="nearest")
        point = point.expand_dims(location=[i])  # Add new dim for stacking
        point = aquifer_ds.sel(x=x, y=y, method="nearest")
        point = point.expand_dims(location=[i])
        locations.append(point)
    portfolio_reservoir_properties = xr.concat(locations, dim="location")

    results_portfolio = calculate_doublet_performance_stochastic(
        portfolio_reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]
    )
    portfolio_aquifer = StochasticAquifer(**portfolio_reservoir_properties.data_vars)

    results_portfolio = ThermoGISDoublet(aquifer=portfolio_aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset()

    # post process: clip the npv and calculate the probability of success
    AEC = -3.5
@@ -357,7 +363,7 @@ def test_example_7():
        kh = results_loc.transmissivity_with_ntg
        kh.plot(y="p_value", ax=ax, color=colors[i_loc])
        ax.set_title("Aquifer: ROSL_ROSLU\n kH")
        temp = results_loc.temperature.sel(p_value=50)
        temp = results_loc.temperature
        inj_temp = results_loc.inj_temp.sel(p_value=50)
        prd_temp = results_loc.prd_temp.sel(p_value=50)
        ax.axhline(
@@ -409,7 +415,7 @@ def test_example_7():
def test_example_8():
    # output directory to write output to
    output_data_path = (
        Path(__file__).parent.parent / "resources" / "test_output" / "example8"
        Path(__file__).parent / "resources" / "test_output" / "example8"
    )
    output_data_path.mkdir(parents=True, exist_ok=True)

@@ -432,9 +438,14 @@ def test_example_8():
    )

    # For every sample, run a doublet simulation store the output values
    simulations = calculate_doublet_performance(
        reservoir_properties, print_execution_duration=True
    aquifer = Aquifer(
        thickness=reservoir_properties["thickness"],
        porosity=reservoir_properties["porosity"],
        ntg=reservoir_properties["ntg"],
        depth=reservoir_properties["depth"],
        permeability=reservoir_properties["permeability"],
    )
    simulations = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset()

    # post process the samples to calculate the percentiles of each variable
    percentiles = np.arange(1, 99)
@@ -484,7 +495,7 @@ def test_example_8():
def test_example_9():
    # output directory to write output to
    output_data_path = (
        Path(__file__).parent.parent / "resources" / "test_output" / "example9"
        Path(__file__).parent / "resources" / "test_output" / "example9"
    )
    output_data_path.mkdir(parents=True, exist_ok=True)

@@ -522,25 +533,27 @@ def test_example_9():
    # clip to minimum transmissivity of 1Dm
    permeability = np.clip(permeability, 1000 / thickness, 1e10)

    reservoir_properties = xr.Dataset(
        {
            "thickness": thickness,
            "porosity": (["depth", "samples"], porosity / 100),
            "ntg": ntg,
            "permeability": (["depth", "samples"], permeability),
        },
        coords={
            "samples": np.arange(n_samples),
            "depth": depths,
        },
    porosity_da = xr.DataArray(
        porosity / 100, dims=["depth", "samples"],
        coords={"depth": depths, "samples": np.arange(n_samples)}
    )
    permeability_da = xr.DataArray(
        permeability, dims=["depth", "samples"],
        coords={"depth": depths, "samples": np.arange(n_samples)}
    )
    depth_da = xr.DataArray(depths, dims=["depth"], coords={"depth": depths})

    # For every sample, run a doublet simulation
    simulations = calculate_doublet_performance(
        reservoir_properties,
        chunk_size=100,
    aquifer = Aquifer(
        thickness=thickness,
        porosity=porosity_da,
        ntg=ntg,
        depth=depth_da,
        permeability=permeability_da,
    )

    # For every sample, run a doublet simulation
    simulations = ThermoGISDoublet(aquifer=aquifer).simulate(chunk_size=100).to_dataset()

    simulations_stoch = simulations.quantile([0.1, 0.5, 0.9], dim="samples")

    # make a plot showing there is a sweet spot between Doublet power, Cost of energy