Skip to content

stochastic doublet

Stochastic Doublet Performance Calculations

This is a simple example of how to use the calculate_doublet_performance_stochastic function from the pythermogis package to run a stochastsic ThermoGIS doublet simulation. This differs from the calculate_doublet_performance function as this function will run simulations across multiple p-values of transmissivity, thickness and permeability. Transmissivity is defined through the combination of a Normal distribution of thickness and a Log-Normal distribution of permeability. For a predetermined set of p-values (default is only P50) simulations are run across these transmissivity samples resulting in a output Dataset with the dimension p_value. This is how ThermoGIS currently handles uncertainty in the reservoir properties.

xarray is at the heart of data handling in pythermogis

The calculate_doublet_performance_stochastic function expects an xarray Dataset as input, which contains the necessary reservoir properties. The output is also an xarray Dataset, which contains the results of the doublet simulation. for more information on how to use xarray, see the xarray documentation.

🧪 Basic Example

This example demonstrates how to run a stochastic doublet simulation using the calculate_doublet_performance_stochastic function for a single set of inputs and only the P50. The outcomes are stochastic, meaning that different output values can occur with each run.

Permeability vs Log-permeability

The function calculate_doublet_performance uses permeability in natural space, while the stochastic method defines permeability as a Log-normal distribution with a mean and a standard deviation. This means that permeability mean and sd is in log space. A log-permeability of 5 is equal to 148.6mD natural-permability (for example).

from pythermogis import calculate_doublet_performance_stochastic
import xarray as xr

input_data = xr.Dataset({
    "thickness_mean": 300,
    "thickness_sd": 50,
    "ntg": 0.5,
    "porosity": 0.5,
    "depth": 2000,
    "ln_permeability_mean": 4,
    "ln_permeability_sd": 0.5,
})

results = calculate_doublet_performance_stochastic(input_data)
print(results)

🧪 P-values Example

This example is an extension of the deterministic doublet simulation using the calculate_doublet_performance_stochastic function. The outcomes correspond to the p-value range of the transmissivity are presented as an expectation curve of transmissivity. This example corresponds to test case test_example5 in test_doc_examples.py in the tests directory of the repository.

from pythermogis import calculate_doublet_performance_stochastic
import xarray as xr
from matplotlib import pyplot as plt
from pathlib import Path
from os import path
output_data_path = Path(path.dirname(__file__), "resources") / "test_output" / "example_data"
output_data_path.mkdir(parents=True, exist_ok=True)

input_data = xr.Dataset({
    "thickness_mean": 300,
    "thickness_sd": 50,
    "ntg": 0.5,
    "porosity": 0.5,
    "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])
fig, axe = plt.subplots(figsize=(10, 5))
kh = results.transmissivity_with_ntg * 1.0
kh.plot(y="p_value", ax=axe)
axe.set_title(f"Aquifer Net transmissivity\n kH")
temp =  input_data.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(50.0, label=f"TEMP res: {temp:.1f} inj: {inj_temp:.1f} prd: {prd_temp:.1f} ",
            ls="--", c="tab:orange")
# axes.axhline(pos, label=f"probability of success: {pos:.1f}%",ls="--", c="tab:orange")
kh50 = kh.sel(p_value=50, method="nearest")
axe.axvline(kh50, ls="--", c="tab:orange" )
axe.legend()
axe.set_xlabel("kH [Dm]")
axe.set_ylabel("p-value [%]")
plt.savefig(output_data_path / "kh.png")

The other examples from deterministic doublet can easily be adapted to this stochastic framework.