TNO Intern

Commit a8c09ae8 authored by Hen Brett's avatar Hen Brett 🐔
Browse files

Updating docstrings and adding a timer function

parent e207d247
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
import warnings

import xarray as xr
import numpy as np
import timeit

from pythermogis import simulate_doublet
from pythermogis.physics.temperature_grid_calculation import calculate_temperature_from_gradient
from pythermogis.thermogis_classes.utc_properties import instantiate_utc_properties_builder

def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properties = None, rng_seed = None) -> xr.Dataset:
def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properties = None, rng_seed = None, print_execution_duration = False) -> xr.Dataset:
    """
    Perform a deterministic Doublet performance simulation.

    This function computes doublet performance metrics across all dimensions of the input dataset.
    The input can be scalar, 1D, or 2D gridded data.

    If no temperature values are provided, they are estimated from a gradient defined in `utc_properties`.
    If a mask is provided, any non-NaN values in the mask datarray will result in zeroing the output values at those locations.

    Parameters
    ----------
    reservoir_properties : xr.Dataset
        An xarray Dataset containing the required input variables:
        - thickness, units: m
        - porosity, units: [0-1]
        - ntg, units [0-1]
        - depth, units: m +ive downwards
        - permeability, units: mD

        Optional variables:
        - transmissivity, units: Dm, if provided then permeability is ignored.
        - temperature : If not provided, temperature is estimated using the depth and a temperature gradient from `utc_properties`.
        - mask : If provided, all non-NaN values will result in setting corresponding output values to zero.

    utc_properties : JClass
        A Java class specifying the properties of the doublet being simulated

    rng_seed : int
        Random seed used for stochastic components of the simulation.

    print_execution_duration : bool
        False by default, If set to True print the time in seconds it took to simulate across all reservoir properties

    Returns
    -------
    output_data : xr.Dataset
        An xarray Dataset with the same spatial dimensions as `reservoir_properties`
        Contains the following output variables:
        - "power"
        - "heat_pump_power"
        - "capex"
        - "opex"
        - "utc"
        - "npv"
        - "hprod"
        - "cop"
        - "cophp"
        - "pres"
        - "flow_rate"
        - "welld"
        - "inj_temp"
        - "prd_temp"
        - "temperature"
        - "thickness"
        - "depth"
        - "permeability"
        - "transmissivity"
        - "transmissivity_with_ntg"
    """
    if print_execution_duration: start = timeit.default_timer()

    validate_input(reservoir_properties)

    if utc_properties is None:
@@ -30,6 +89,7 @@ def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properti
    # Setup output_data dataset as a copy of reservoir properties
    output_data = reservoir_properties.copy()

    if print_execution_duration: print(f"Doublet simulation took {timeit.default_timer() - start:.1f} seconds")
    return simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties)

def validate_input(reservoir_properties: xr.Dataset):
+45 −38
Original line number Diff line number Diff line
from typing import List
import xarray as xr
import numpy as np
import timeit

from pythermogis import simulate_doublet
from pythermogis.physics.temperature_grid_calculation import calculate_temperature_from_gradient
@@ -11,36 +12,38 @@ def calculate_doublet_performance_stochastic(reservoir_properties: xr.Dataset,
                                             utc_properties = None,
                                             rng_seed = None,
                                             p_values: List[float] = [50.0],
                                             print_execution_duration = False
                                             ) -> xr.Dataset:
    """
    Perform a ThermoGIS Doublet performance simulation.
    Perform a ThermoGIS Stochastic Doublet performance simulation.

    This function computes doublet performance metrics across all dimensions of the input dataset.
    The input can be scalar, 1D, or 2D gridded data. If no temperature values are provided, they
    are estimated from a gradient defined in `input_params`. If a mask is provided, any non-NaN
    values will result in zeroing the output values at those locations.
    The input can be scalar, 1D, or 2D gridded data.

    The ThermoGIS methodology works by simulating doublet performance across percentiles of transmissivity, which in turn is calcualted using probability distributions of thickness and permeability.
    If no temperature values are provided, they are estimated from a gradient defined in `utc_properties`.
    If a mask is provided, any non-NaN values in the mask datarray will result in zeroing the output values at those locations.

    The ThermoGIS methodology works by simulating doublet performance across percentiles of transmissivity, which in turn is calculated using probability distributions of thickness and permeability.
    The output results will always contain the dimension p_value; although by default only a P50 simulation is done.

    Parameters
    ----------
    reservoir_properties : xr.Dataset
        An xarray Dataset containing the required input variables:
        - "thickness_mean"
        - "thickness_sd"
        - "porosity"
        - "ntg"
        - "depth"
        - "ln_permeability_mean"
        - "ln_permeability_sd"
        - thickness_mean
        - thickness_sd
        - porosity
        - ntg
        - depth
        - ln_permeability_mean
        - ln_permeability_sd

        Optional variables:
        - "temperature" : If not provided, temperature is estimated using the depth and a temperature gradient from `input_params`.
        - "mask" : If provided, all non-NaN values will result in setting corresponding output values to zero.
        - temperature : If not provided, temperature is estimated using the depth and a temperature gradient from `input_params`.
        - mask : If provided, all non-NaN values will result in setting corresponding output values to zero.

    utc_properties : dict
        A dictionary of UTC (Underground Thermal Capacity) properties used for simulation.
    utc_properties : JClass
        A Java class specifying the properties of the doublet being simulated

    rng_seed : int
        Random seed used for stochastic components of the simulation.
@@ -49,33 +52,36 @@ def calculate_doublet_performance_stochastic(reservoir_properties: xr.Dataset,
        List of probability values (e.g., [0.1, 0.5, 0.9]) for the performance evaluation.
        If not provided, the default value of P50 (0.5) is used.

    print_execution_duration : bool
        False by default, If set to True print the time in seconds it took to simulate across all reservoir properties

    Returns
    -------
    output_data : xr.Dataset
        An xarray Dataset with the same spatial dimensions as `input_data`, plus an added `p_value` dimension.
        Contains the following output variables:
        - "power"
        - "heat_pump_power"
        - "capex"
        - "opex"
        - "utc"
        - "npv"
        - "hprod"
        - "cop"
        - "cophp"
        - "pres"
        - "flow_rate"
        - "welld"
        - "inj_temp"
        - "prd_temp"

        - "temperature"
        - "thickness"
        - "depth"
        - "permeability"
        - "transmissivity"
        - "transmissivity_with_ntg"
        - power
        - heat_pump_power
        - capex
        - opex
        - utc
        - npv
        - hprod
        - cop
        - cophp
        - pres
        - flow_rate
        - welld
        - inj_temp
        - prd_temp
        - temperature
        - thickness
        - depth
        - permeability
        - transmissivity
        - transmissivity_with_ntg
    """
    if print_execution_duration: start = timeit.default_timer()

    # Check that all essential variables are provided
    validate_input_data(reservoir_properties)
@@ -100,7 +106,7 @@ def calculate_doublet_performance_stochastic(reservoir_properties: xr.Dataset,
        reservoir_properties["mask"] = np.nan

    # Setup output_data dataset
    output_data = reservoir_properties["temperature"].copy().to_dataset(name="temperature")
    output_data = reservoir_properties["temperature"].copy().to_dataset()
    output_data["temperature"] = reservoir_properties["temperature"] * 1.0
    output_data = output_data.expand_dims({"p_value": p_values})

@@ -116,6 +122,7 @@ def calculate_doublet_performance_stochastic(reservoir_properties: xr.Dataset,
                                                                                                          vectorize=True
                                                                                                          )

    if print_execution_duration: print(f"Doublet simulation took {timeit.default_timer() - start:.1f} seconds")
    return simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties)


+4 −5
Original line number Diff line number Diff line
from typing import List

import numpy as np
import xarray as xr
from jpype import JClass

def simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties):
def simulate_doublet(output_data: xr.Dataset, reservoir_properties: xr.Dataset, rng_seed: int, utc_properties: JClass) -> xr.Dataset:
    # Calculate transmissivity scaled by ntg and converted to Dm
    output_data[f"transmissivity_with_ntg"] = (output_data[f"transmissivity"] * reservoir_properties.ntg) / 1e3

@@ -24,7 +22,8 @@ def simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties
                                        kwargs={"doublet": doublet, "utc_properties": utc_properties},
                                        input_core_dims=[[], [], [], [], [], [], [], []],
                                        output_core_dims=[[], [], [], [], [], [], [], [], [], [], [], [], [], []],
                                        vectorize=True
                                        vectorize=True,
                                        dask="parallelized",
                                        )

    # Assign output DataArrays to the output_data object
@@ -139,7 +138,7 @@ def calculate_performance_of_single_location(mask: float, depth: float, thicknes

def instantiate_thermogis_doublet(utc_properties, rng_seed: int = None) -> JClass:
    """
    Instantiate a ThermoGIS Doublet class, optionally using a specified random seed.
    Instantiate a ThermoGIS Doublet class, setting necessary parameters from utc_properties and optionally using a specified random seed.

    Parameters
    ----------
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ def test_deterministic_doublet():
        "permeability": 200
    })

    results1 = calculate_doublet_performance(reservoir_properties)
    results1 = calculate_doublet_performance(reservoir_properties, print_execution_duration=True)
    results2 = calculate_doublet_performance(reservoir_properties)
    xr.testing.assert_equal(results1, results2)