Loading pixi.lock +74 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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.* Loading Loading @@ -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 Loading Loading @@ -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 Loading pyproject.toml +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading src/pythermogis/workflow/utc/cooling_temp.py +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, Loading Loading @@ -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) src/pythermogis/workflow/utc/doublet.py +26 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 = ( Loading @@ -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 Loading @@ -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( Loading @@ -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 ) Loading Loading @@ -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 = ( Loading Loading @@ -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, ) src/pythermogis/workflow/utc/doublet_utils.py +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( Loading Loading @@ -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: Loading @@ -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, Loading @@ -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) Loading Loading @@ -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 Loading @@ -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 Loading @@ -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
pixi.lock +74 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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.* Loading Loading @@ -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 Loading Loading @@ -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 Loading
pyproject.toml +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
src/pythermogis/workflow/utc/cooling_temp.py +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, Loading Loading @@ -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)
src/pythermogis/workflow/utc/doublet.py +26 −17 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 = ( Loading @@ -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 Loading @@ -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( Loading @@ -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 ) Loading Loading @@ -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 = ( Loading Loading @@ -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, )
src/pythermogis/workflow/utc/doublet_utils.py +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( Loading Loading @@ -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: Loading @@ -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, Loading @@ -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) Loading Loading @@ -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 Loading @@ -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 Loading @@ -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