TNO Intern

Commit 2648a990 authored by Florian Knappers's avatar Florian Knappers
Browse files

Merge branch '91-cleanup-the-workflow-utc-code' into 'python-rewrite-of-java-code'

Resolve "cleanup the workflow/utc code"

See merge request !110
parents 60f69559 4da1bf49
Loading
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ environments:
      - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_1.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_1.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda
      - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.8-h813ae00_0.conda
      - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda
      - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py313h78bf25f_3.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.2-pyhff2d567_0.conda
@@ -252,6 +253,7 @@ environments:
      - pypi: https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
      - pypi: https://files.pythonhosted.org/packages/f5/64/41c4367bcaecbc03ef0d2a3ecee58a7065d0a36ae1aa817fe573a2da66d4/matplotlib-3.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
      - pypi: https://files.pythonhosted.org/packages/d1/80/b9c19f1bb4ac6c5fa6f94a4f278bc68a778473d1814a86a375d7cffa193a/netCDF4-1.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
      - pypi: https://files.pythonhosted.org/packages/78/f9/690a8600b93c332de3ab4a344a4ac34f00c8f104917061f779db6a918ed6/pathlib-1.0.1-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/02/65/ad2bc85f7377f5cfba5d4466d5474423a3fb7f6a97fd807c06f92dd3e721/plotly-6.0.1-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/c9/58/c3bc54c0fad9a82899e9a2703e04ee6e8eaa76caa90c0689fd1b468a4427/pygridsio-1.0-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/ea/00/d815833441d8c52bf4a6930952e77d3de77d0bf67b3202ccc12dabdae279/pykrige-1.7.2.tar.gz
@@ -263,7 +265,9 @@ environments:
      - pypi: https://files.pythonhosted.org/packages/2a/2f/63d2cacc0e525f8e3398bcf32bd3620385f22cd1600834ec49d7f3597a7b/rioxarray-0.19.0-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
      - pypi: https://files.pythonhosted.org/packages/d1/a7/5c9cb413e4e2ce52c16be717e94abd40ce91b1f8974624d5d56154c5d40b/shapely-2.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
      - pypi: https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl
      - pypi: ./
      - pypi: C:/Users/knappersfy/work/thermogis/pydoubletcalc
      win-64:
      - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda
@@ -436,6 +440,7 @@ environments:
      - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_1.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_1.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda
      - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.14.8-h15e3a1f_0.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.8.2-pyhff2d567_0.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_1.conda
      - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda
@@ -486,6 +491,7 @@ environments:
      - pypi: https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl
      - pypi: https://files.pythonhosted.org/packages/b1/0f/eed564407bd4d935ffabf561ed31099ed609e19287409a27b6d336848653/matplotlib-3.10.3-cp313-cp313-win_amd64.whl
      - pypi: https://files.pythonhosted.org/packages/66/b5/e04550fd53de57001dbd5a87242da7ff784c80790adc48897977b6ccf891/netCDF4-1.7.2-cp313-cp313-win_amd64.whl
      - pypi: https://files.pythonhosted.org/packages/78/f9/690a8600b93c332de3ab4a344a4ac34f00c8f104917061f779db6a918ed6/pathlib-1.0.1-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/02/65/ad2bc85f7377f5cfba5d4466d5474423a3fb7f6a97fd807c06f92dd3e721/plotly-6.0.1-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/c9/58/c3bc54c0fad9a82899e9a2703e04ee6e8eaa76caa90c0689fd1b468a4427/pygridsio-1.0-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/ea/00/d815833441d8c52bf4a6930952e77d3de77d0bf67b3202ccc12dabdae279/pykrige-1.7.2.tar.gz
@@ -497,7 +503,9 @@ environments:
      - pypi: https://files.pythonhosted.org/packages/2a/2f/63d2cacc0e525f8e3398bcf32bd3620385f22cd1600834ec49d7f3597a7b/rioxarray-0.19.0-py3-none-any.whl
      - pypi: https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl
      - pypi: https://files.pythonhosted.org/packages/e3/f0/9f8cdf2258d7aed742459cea51c70d184de92f5d2d6f5f7f1ded90a18c31/shapely-2.1.0-cp313-cp313-win_amd64.whl
      - pypi: https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl
      - pypi: ./
      - pypi: C:/Users/knappersfy/work/thermogis/pydoubletcalc
packages:
- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2
  sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726
@@ -4471,6 +4479,10 @@ packages:
  - pkg:pypi/partd?source=hash-mapping
  size: 20884
  timestamp: 1715026639309
- pypi: https://files.pythonhosted.org/packages/78/f9/690a8600b93c332de3ab4a344a4ac34f00c8f104917061f779db6a918ed6/pathlib-1.0.1-py3-none-any.whl
  name: pathlib
  version: 1.0.1
  sha256: f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147
- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda
  sha256: 9f64009cdf5b8e529995f18e03665b03f5d07c0b17445b8badef45bde76249ee
  md5: 617f15191456cc6a13db418a275435e5
@@ -4752,6 +4764,20 @@ packages:
  - pkg:pypi/pycparser?source=hash-mapping
  size: 110100
  timestamp: 1733195786147
- pypi: C:/Users/knappersfy/work/thermogis/pydoubletcalc
  name: pydoubletcalc
  version: 0.0.2
  sha256: 89fbb20be0f5da6d0e8e543b9160e4ac3aef8369557ca71ae4a96086f521145e
  requires_dist:
  - pandas
  - matplotlib
  - pathlib
  - xarray
  - tqdm>=4.67.1
  - scipy>=1.16.2
  - numba>=0.62.1
  requires_python: '>=3.13,<3.14'
  editable: true
- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda
  sha256: 28a3e3161390a9d23bc02b4419448f8d27679d9e2c250e29849e37749c8de86b
  md5: 232fb4577b6687b2d503ef8e254270c9
@@ -4919,7 +4945,7 @@ packages:
- pypi: ./
  name: pythermogis
  version: 1.2.0
  sha256: 44271718a4a84514ee6d1f6a413b57b060a4868ea6dd8fadf0e1ed09c39dfae1
  sha256: 35de67af8136fb6442b90f5a2956e6ac57f8a6f52f1fbbfad15768e83e08b31f
  requires_dist:
  - jpype1>=1.5.2,<2
  - xarray==2024.9.0.*
@@ -5305,6 +5331,37 @@ packages:
  - scipy ; extra == 'interp'
  - scipy ; extra == 'all'
  requires_python: '>=3.10'
- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.14.8-h813ae00_0.conda
  noarch: python
  sha256: 4adf379daccb73f03297a6966d1200f6ea65e6a1513d749e7f782e32267fe2bb
  md5: 295ce05c06920527a581a5e148a4eec6
  depends:
  - python
  - __glibc >=2.17,<3.0.a0
  - libgcc >=14
  constrains:
  - __glibc >=2.17
  license: MIT
  license_family: MIT
  purls:
  - pkg:pypi/ruff?source=hash-mapping
  size: 11340280
  timestamp: 1764866215629
- conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.14.8-h15e3a1f_0.conda
  noarch: python
  sha256: fbcaafffd55c7022464219b95658d38980ee04bb001d35c3d97e2e933d7c6bf7
  md5: 35ec53f16d22dc8b17e17865a98c2120
  depends:
  - python
  - vc >=14.3,<15
  - vc14_runtime >=14.44.35208
  - ucrt >=10.0.20348.0
  license: MIT
  license_family: MIT
  purls:
  - pkg:pypi/ruff?source=hash-mapping
  size: 11874411
  timestamp: 1764866263950
- conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.21-h7ab7c64_0.conda
  sha256: c8b252398b502a5cc6ea506fd2fafe7e102e7c9e2ef48b7813566e8a72ce2205
  md5: 28b5a7895024a754249b2ad7de372faa
@@ -5616,6 +5673,22 @@ packages:
  - pkg:pypi/tornado?source=hash-mapping
  size: 878044
  timestamp: 1748003914685
- pypi: https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl
  name: tqdm
  version: 4.67.1
  sha256: 26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2
  requires_dist:
  - colorama ; sys_platform == 'win32'
  - pytest>=6 ; extra == 'dev'
  - pytest-cov ; extra == 'dev'
  - pytest-timeout ; extra == 'dev'
  - pytest-asyncio>=0.24 ; extra == 'dev'
  - nbval ; extra == 'dev'
  - requests ; extra == 'discord'
  - slack-sdk ; extra == 'slack'
  - requests ; extra == 'telegram'
  - ipywidgets>=6 ; extra == 'notebook'
  requires_python: '>=3.7'
- conda: https://conda.anaconda.org/conda-forge/noarch/twine-6.1.0-pyh29332c3_0.conda
  sha256: c5b373f6512b96324c9607d7d91a76bb53c1056cb1012b4f9c86900c6b7f8898
  md5: d319066fad04e07a0223bf9936090161
+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ narwhals = ">=1.43.1,<2"
pre-commit = ">=4.3.0,<5"
python-dotenv = ">=1.2.1,<2"
numba = ">=0.62.1,<0.63"
ruff = ">=0.14.8,<0.15"

[tool.ruff]
line-length = 88
+4 −8
Original line number Diff line number Diff line
from pythermogis.workflow.utc.flow import calculate_volumetric_flow
from pythermogis.workflow.utc.doublet_utils import calc_lifetime
from pythermogis.workflow.utc.flow import calculate_volumetric_flow


def calculate_cooling_temperature(
    props,
    input,
    drawdown_pressure: float,
    well_distance: float,
    injection_temp: float
    props, input, drawdown_pressure: float, well_distance: float, injection_temp: float
) -> float:

    results = calculate_volumetric_flow(
        props=props,
        input_data=input,
@@ -51,7 +46,8 @@ def calculate_cooling_temperature(

    if (not props.is_ates) and cooling_frac > 0.3:
        raise RuntimeError(
            f"Large cooling factor ({cooling_frac}) could result in less reliable calculation"
            f"Large cooling factor ({cooling_frac}) "
            f"could result in less reliable calculation"
        )

    return cooling_frac * (input.temperature - injection_temp)
+26 −17
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ from pythermogis.workflow.utc.well_distance import optimize_well_distance
EUR_PER_CT_PER_KWH = 0.36
NPV_SCALE = 1e-6


@dataclass
class DoubletInput:
    unknown_input_value: float
@@ -32,6 +33,7 @@ class DoubletInput:
        DARCY_SI = 1.0e-12 / 1.01325
        return self.transmissivity / self.thickness * 1e-3 * DARCY_SI


@dataclass
class DoubletOutput:
    power: float
@@ -53,7 +55,10 @@ class DoubletOutput:
    production_temp: float
    injection_temp: float

def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput, verbose: bool = False) -> DoubletOutput | None:

def calculate_doublet_performance(
    props: UTCConfiguration, input: DoubletInput, verbose: bool = False
) -> DoubletOutput | None:
    timer = timeit.default_timer()
    # determine initial well distance
    well_distance = (
@@ -73,8 +78,9 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput,
            props.hp_minimum_injection_temperature,
        )
    else:
        injection_temperature = max(input.temperature - props.max_cooling_temp_range,
            props.dh_return_temp)
        injection_temperature = max(
            input.temperature - props.max_cooling_temp_range, props.dh_return_temp
        )
    timer = print_time(timer, "injection temperature: ", verbose=verbose)

    # calculate maximum pressure
@@ -91,9 +97,8 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput,

    # cooling temperature and well distance optimization
    if props.optim_well_dist:
        end_temperature_p = (
                props.optim_dist_cooling_fraction *
                (input.temperature - injection_temperature)
        end_temperature_p = props.optim_dist_cooling_fraction * (
            input.temperature - injection_temperature
        )
    else:
        end_temperature_p = calculate_cooling_temperature(
@@ -117,7 +122,10 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput,
    # stimulation capex
    stimulation_capex = (
        0.0
        if (not props.use_stimulation or input.transmissivity_with_ntg > props.stim_kh_max)
        if (
            not props.use_stimulation
            or input.transmissivity_with_ntg > props.stim_kh_max
        )
        else props.stimulation_capex
    )

@@ -176,11 +184,13 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput,
        props.salinity_surface,
        props.salinity_gradient,
        props.optim_dist_cp_rock,
        props.optim_dist_rho_rock
        props.optim_dist_rho_rock,
    )

    utc_cutoff = (
        props.utc_cutoff_deep if input.depth > props.utc_deep_depth else props.utc_cutoff
        props.utc_cutoff_deep
        if input.depth > props.utc_deep_depth
        else props.utc_cutoff
    )

    npv = (
@@ -211,6 +221,5 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput,
        breakthrough=breakthrough_years,
        cooling=end_temperature_p,
        production_temp=production_temp,
        injection_temp=injection_temperature
        injection_temp=injection_temperature,
    )
+21 −9
Original line number Diff line number Diff line
import math

from numba import njit
from pythermogis.workflow.utc.water import density, heat_capacity, get_salinity, get_hydrostatic_pressure

from pythermogis.workflow.utc.water import (
    density,
    get_hydrostatic_pressure,
    get_salinity,
    heat_capacity,
)


@njit
def calculate_injection_temp_with_heat_pump(
@@ -33,13 +41,15 @@ def calculate_injection_temp_with_heat_pump(

    return max(
        needed_injection_temp,
        max(reservoir_temp - max_cooling_temp_range, hp_minimum_injection_temperature)
        max(reservoir_temp - max_cooling_temp_range, hp_minimum_injection_temperature),
    )


@njit
def get_orc_efficiency(Tx: float, Ts: float, etarel: float) -> float:
    return etarel * (Tx - Ts) / (Tx + Ts + 2 * 273.1)


@njit
def get_cop_carnot(eta: float, Tout: float, Tin: float) -> float:
    if Tout < 0.0 or Tin < 0.0:
@@ -59,6 +69,7 @@ def get_cop_carnot(eta: float, Tout: float, Tin: float) -> float:

    return eta * (Tcond + TKELVIN) / (Tcond - Tevap)


@njit
def calc_lifetime(
    well_distance: float,
@@ -73,7 +84,6 @@ def calc_lifetime(
    cp_rock: float,
    rho_rock: float,
) -> float:

    # --- Water properties at depth ---
    salinity = get_salinity(salinity_surface, salinity_gradient, depth)
    pressure = get_hydrostatic_pressure(depth)
@@ -102,9 +112,10 @@ def calc_lifetime(
    Aseg = Aseg1 - Aseg2
    Vseg = Aseg * thickness

    Eseg = 1e-9 * Vseg * (
        (1 - porosity) * cp_rock * rho_rock +
        porosity * cp_water * rho_water
    Eseg = (
        1e-9
        * Vseg
        * ((1 - porosity) * cp_rock * rho_rock + porosity * cp_water * rho_water)
    )

    flowseg = flowrate * 365 * 24 * dangle / math.pi
@@ -120,7 +131,6 @@ def get_along_hole_length(
    curve_scaling_factor: float,
    max_true_vertical_depth_stepout_factor: float,
) -> float:

    if curve_scaling_factor == 0:
        return true_vertical_depth

@@ -134,6 +144,8 @@ def get_along_hole_length(

    stepout -= horizontal_distance

    oblique_distance = math.sqrt(stepout**2 + true_vertical_depth**2) * curve_scaling_factor
    oblique_distance = (
        math.sqrt(stepout**2 + true_vertical_depth**2) * curve_scaling_factor
    )

    return oblique_distance + horizontal_distance
Loading