From 414bfb9de5e4c8f4567358d8c351411f215440b9 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 09:45:46 +0100 Subject: [PATCH 01/11] first changes --- docs/usage/customized_props.md | 4 +- pixi.lock | 4 +- .../deterministic_doublet.py | 4 +- .../doublet_simulation/stochastic_doublet.py | 4 +- .../thermogis_classes/utc_properties.py | 16 +++---- .../thermogis_jar/thermogis-1.7.0-shaded.jar | 4 +- tests/documentation/test_doc_examples.py | 4 +- tests/java/test_ThermoGISDoublet_Benchmark.py | 46 +++++++++---------- .../test_pythermogis_doublet_benchmark.py | 22 ++++----- tests/simulation/test_thermogis_scenarios.py | 11 ++--- 10 files changed, 56 insertions(+), 63 deletions(-) diff --git a/docs/usage/customized_props.md b/docs/usage/customized_props.md index 0496e23..e9b111e 100644 --- a/docs/usage/customized_props.md +++ b/docs/usage/customized_props.md @@ -39,7 +39,7 @@ Here is an example, where the default utc_properties is used, but the UseHeatPum `utc_properties` themselves, with the `.build()` method of the `utc_properties_builder`. ```python -from pythermogis import calculate_doublet_performance, instantiate_utc_properties_builder +from pythermogis import calculate_doublet_performance, instantiate_thermogis_parameters import xarray as xr input_data = xr.Dataset({ @@ -50,7 +50,7 @@ input_data = xr.Dataset({ "permeability": 300, }) -utc_properties = instantiate_utc_properties_builder().setUseHeatPump(True).build() +utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).build() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) print(results) ``` diff --git a/pixi.lock b/pixi.lock index d771c6c..2d40a23 100644 --- a/pixi.lock +++ b/pixi.lock @@ -4933,8 +4933,8 @@ packages: timestamp: 1740946648058 - pypi: ./ name: pythermogis - version: 1.2.4 - sha256: 4406d3c4da3a9e6ee46a39b7ce7b61063e676db495638f1f9d992ac174589913 + version: 1.2.5 + sha256: f7faf166eaa5141f37e7e96c2fc7f2c01cf26da4be5fc5164aa0c8c784614e2b requires_dist: - jpype1>=1.5.2,<2 - xarray==2024.9.0.* diff --git a/src/pythermogis/doublet_simulation/deterministic_doublet.py b/src/pythermogis/doublet_simulation/deterministic_doublet.py index 98282eb..86acf5d 100644 --- a/src/pythermogis/doublet_simulation/deterministic_doublet.py +++ b/src/pythermogis/doublet_simulation/deterministic_doublet.py @@ -10,7 +10,7 @@ from pythermogis.physics.temperature_grid_calculation import ( calculate_temperature_from_gradient, ) from pythermogis.thermogis_classes.utc_properties import ( - instantiate_utc_properties_builder, + instantiate_thermogis_parameters, ) @@ -90,7 +90,7 @@ def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properti validate_input(reservoir_properties) if utc_properties is None: - utc_properties = instantiate_utc_properties_builder().build() + utc_properties = instantiate_thermogis_parameters().setupUTCParameters() # If no mask grid is provided, then provide a dummy mask grid with only nan if "mask" not in reservoir_properties: diff --git a/src/pythermogis/doublet_simulation/stochastic_doublet.py b/src/pythermogis/doublet_simulation/stochastic_doublet.py index 701b1ec..a2db2da 100644 --- a/src/pythermogis/doublet_simulation/stochastic_doublet.py +++ b/src/pythermogis/doublet_simulation/stochastic_doublet.py @@ -7,7 +7,7 @@ from pythermogis import simulate_doublet from pythermogis.dask_utils.auto_chunk import auto_chunk_dataset from pythermogis.physics.temperature_grid_calculation import calculate_temperature_from_gradient from pythermogis.transmissivity.calculate_thick_perm_trans import generate_thickness_permeability_transmissivity_for_pvalues -from pythermogis.thermogis_classes.utc_properties import instantiate_utc_properties_builder +from pythermogis.thermogis_classes.utc_properties import instantiate_thermogis_parameters def calculate_doublet_performance_stochastic( reservoir_properties: xr.Dataset, @@ -101,7 +101,7 @@ def calculate_doublet_performance_stochastic( validate_input_data(reservoir_properties) if utc_properties is None: # Instantiate utc_properties if none is provided - utc_properties = instantiate_utc_properties_builder().build() + utc_properties = instantiate_thermogis_parameters().setupUTCParameters() # convert p_values list to a xarray DataArray; needed to ensure the dimensionality of the calculations p_values = xr.DataArray( diff --git a/src/pythermogis/thermogis_classes/utc_properties.py b/src/pythermogis/thermogis_classes/utc_properties.py index 50308d4..e8821fd 100644 --- a/src/pythermogis/thermogis_classes/utc_properties.py +++ b/src/pythermogis/thermogis_classes/utc_properties.py @@ -22,23 +22,21 @@ def instantiate_utc_properties_from_xml(xml_file: str | Path) -> JClass: # parse to string and pass to the Java utc xml parser return JClass("thermogis.properties.parsers.UTCXmlParser")().parse(ET.tostring(root, encoding='utf8', method='xml')) -def instantiate_utc_properties_builder() -> JClass: +def instantiate_thermogis_parameters() -> JClass: """ - Create and return a ``UTCPropertiesBuilder`` Java object. + Create and return a ``ThermoGISParameters`` Java object. - The builder wraps the ThermoGIS **UTCPropertiesBuilder** Java class, which can + The ThermoGISParameters holds the input parameters for all TG calculations, and + can be used to setup the record classes for the 4 calculations. - * parse ThermoGIS scenario XML files, and - * programmatically modify individual scenario parameters prior to running a simulation. Returns ------- - utc_properties_builder : jpype.JClass - An instantiated ``UTCPropertiesBuilder`` that can be used to build or modify - ``UTCProperties`` objects for ThermoGIS simulations. + ThermoGISParameters : jpype.JClass + An instantiated ``ThermoGISParameters``. """ start_jvm() - return JClass("thermogis.properties.builders.UTCPropertiesBuilder")() + return JClass("thermogis.parameters.ThermoGISParameters")() def get_viscosity_mode(mode: t.Literal["kestin", "batzlewang"]) -> JClass: """ diff --git a/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar b/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar index e9b30a8..b5180f2 100644 --- a/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar +++ b/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:207f0a0ecd48947dd4fdb2739edc17eaf60e1cd4351d06915adcc25d29b10e21 -size 173318007 +oid sha256:7c7a8cfee4f0a08d821a2bb1f58fd4cd61dbc28332d130993303673f732a492c +size 174049130 diff --git a/tests/documentation/test_doc_examples.py b/tests/documentation/test_doc_examples.py index 896739b..8721d4b 100644 --- a/tests/documentation/test_doc_examples.py +++ b/tests/documentation/test_doc_examples.py @@ -32,7 +32,7 @@ def test_example_2(): print(results) def test_example_3(): - from pythermogis import calculate_doublet_performance, instantiate_utc_properties_builder + from pythermogis import calculate_doublet_performance, instantiate_thermogis_parameters import xarray as xr input_data = xr.Dataset({ @@ -43,7 +43,7 @@ def test_example_3(): "permeability": 300, }) - utc_properties = instantiate_utc_properties_builder().setUseHeatPump(True).build() + utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).setupUTCParameters() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) print(results) diff --git a/tests/java/test_ThermoGISDoublet_Benchmark.py b/tests/java/test_ThermoGISDoublet_Benchmark.py index 9dac69b..a324616 100644 --- a/tests/java/test_ThermoGISDoublet_Benchmark.py +++ b/tests/java/test_ThermoGISDoublet_Benchmark.py @@ -75,12 +75,12 @@ class ThermoGISDoubletBenchmark(TestCase): DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - utc_properties = (self.setup_template_utc_properties_builder() + utc_properties = (self.setup_template_tg_properties() .setOpexBase(0) .setDhReturnTemp(40) .setViscosityMode(ViscosityMode.KESTIN) .setUseStimulation(False) - .build()) + .setupUTCParameters()) thickness = 100 permeability = 175 @@ -127,14 +127,14 @@ class ThermoGISDoubletBenchmark(TestCase): DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - utc_properties = (self.setup_template_utc_properties_builder() + utc_properties = (self.setup_template_tg_properties() .setCapexConst(0.5) .setCapexVariable(1100) .setHeatExchangerEfficiency(0.4) .setHeatExchangerParasitic(0.1) .setDhReturnTemp(60) .setViscosityMode(ViscosityMode.KESTIN) - .build()) + .setupUTCParameters()) thickness = 100 permeability = 175 @@ -181,14 +181,14 @@ class ThermoGISDoubletBenchmark(TestCase): DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - utc_properties = (self.setup_template_utc_properties_builder() + utc_properties = (self.setup_template_tg_properties() .setOpexPerPower(100) .setOpexBase(0) .setHpDirectHeatInputTemp(70) .setUseHeatPump(True) .setDhReturnTemp(35) .setViscosityMode(ViscosityMode.KESTIN) - .build()) + .setupUTCParameters()) thickness = 100 permeability = 175 @@ -236,7 +236,7 @@ class ThermoGISDoubletBenchmark(TestCase): DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - utc_properties = (self.setup_template_utc_properties_builder() + utc_properties = (self.setup_template_tg_properties() .setOpexPerPower(100) .setOpexBase(0) .setHpDirectHeatInputTemp(80) @@ -244,7 +244,7 @@ class ThermoGISDoubletBenchmark(TestCase): .setUseHeatPump(True) .setDhReturnTemp(50) .setViscosityMode(ViscosityMode.KESTIN) - .build()) + .setupUTCParameters()) thickness = 100 permeability = 175 @@ -291,14 +291,14 @@ class ThermoGISDoubletBenchmark(TestCase): DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - utc_properties = (self.setup_template_utc_properties_builder() + utc_properties = (self.setup_template_tg_properties() .setCapexConst(0) .setCapexVariable(2300) .setHeatExchangerEfficiency(0.6) .setUseORC(True) .setViscosityMode(ViscosityMode.KESTIN) .setDhReturnTemp(60) - .setHeatExchangerBasetemp(20).build()) + .setHeatExchangerBasetemp(20).setupUTCParameters()) thickness = 100 permeability = 175 @@ -331,16 +331,16 @@ class ThermoGISDoubletBenchmark(TestCase): self.assertTrue(np.isclose(0.06459403120103477, results.cop(), 0.001)) self.assertTrue(np.isclose(12.44409167482118, results.capex(), 0.001)) - def setup_template_utc_properties_builder(self): - return (instantiate_utc_properties_builder() - .setSalinityGradient(47.0) - .setDrillingTime(1) - .setTaxRate(20) - .setEquityReturn(15) - .setOpexBase(10000) - .setOpexPerPower(50) - .setWellCostScaling(1) - .setOpexPerEnergy(0) - .setWellCostConst(0.375) - .setWellCostZ(1050) - .setWellCostZ2(0.3)) \ No newline at end of file + def setup_template_tg_properties(self): + return (instantiate_thermogis_parameters() + .setSalinityGradient(47.0) + .setDrillingTime(1) + .setTaxRate(20) + .setEquityReturn(15) + .setOpexBase(10000) + .setOpexPerPower(50) + .setWellCostScaling(1) + .setOpexPerEnergy(0) + .setWellCostConst(0.375) + .setWellCostZ(1050) + .setWellCostZ2(0.3)) \ No newline at end of file diff --git a/tests/simulation/test_pythermogis_doublet_benchmark.py b/tests/simulation/test_pythermogis_doublet_benchmark.py index cc274af..244a9ce 100644 --- a/tests/simulation/test_pythermogis_doublet_benchmark.py +++ b/tests/simulation/test_pythermogis_doublet_benchmark.py @@ -11,10 +11,10 @@ class ThermoGISDoubletBenchmark(TestCase): def test_calculateDoubletPerformanceTest(self): viscosity_mode = get_viscosity_mode("kestin") utc_properties = ( - instantiate_utc_properties_builder() + instantiate_thermogis_parameters() .setDhReturnTemp(40) .setViscosityMode(viscosity_mode) - .build() + .setupUTCParameters() ) input_data = xr.Dataset( @@ -51,7 +51,7 @@ class ThermoGISDoubletBenchmark(TestCase): # Arrange # Instantiate the UTC properties class utc_properties = ( - self.setup_template_utc_properties_builder().setOpexBase(0).build() + self.setup_template_tg_properties().setOpexBase(0).setupUTCParameters() ) input_data = xr.Dataset( @@ -89,13 +89,13 @@ class ThermoGISDoubletBenchmark(TestCase): # Arrange # Instantiate the UTC properties class utc_properties = ( - self.setup_template_utc_properties_builder() + self.setup_template_tg_properties() .setCapexConst(0.5) .setCapexVariable(1100) .setHeatExchangerEfficiency(0.4) .setDhReturnTemp(60) .setHeatExchangerParasitic(0.1) - .build() + .setupUTCParameters() ) input_data = xr.Dataset( @@ -134,14 +134,14 @@ class ThermoGISDoubletBenchmark(TestCase): # Arrange # Instantiate the UTC properties class utc_properties = ( - self.setup_template_utc_properties_builder() + self.setup_template_tg_properties() .setCapexConst(0) .setCapexVariable(2300) .setHeatExchangerEfficiency(0.6) .setUseORC(True) .setHeatExchangerBasetemp(20) .setDhReturnTemp(60) - .build() + .setupUTCParameters() ) input_data = xr.Dataset( @@ -180,13 +180,13 @@ class ThermoGISDoubletBenchmark(TestCase): # Arrange # Instantiate the UTC properties class utc_properties = ( - self.setup_template_utc_properties_builder() + self.setup_template_tg_properties() .setOpexPerPower(100) .setOpexBase(0) .setHpDirectHeatInputTemp(70) .setUseHeatPump(True) .setDhReturnTemp(35) - .build() + .setupUTCParameters() ) input_data = xr.Dataset( @@ -223,11 +223,11 @@ class ThermoGISDoubletBenchmark(TestCase): self.assertTrue(np.isclose(10.401010755009017, results.utc, 0.001)) self.assertTrue(np.isclose(16.50359210062243, results.capex, 0.001)) - def setup_template_utc_properties_builder(self): + def setup_template_tg_properties(self): viscosity_mode = get_viscosity_mode("kestin") return ( - instantiate_utc_properties_builder() + instantiate_thermogis_parameters() .setSalinityGradient(47.0) .setDrillingTime(1) .setTaxRate(20) diff --git a/tests/simulation/test_thermogis_scenarios.py b/tests/simulation/test_thermogis_scenarios.py index ae63b42..7fd9c1d 100644 --- a/tests/simulation/test_thermogis_scenarios.py +++ b/tests/simulation/test_thermogis_scenarios.py @@ -1,5 +1,3 @@ -import shutil -from os import path from unittest import TestCase from pygridsio import read_grid @@ -44,8 +42,7 @@ class PyThermoGIS(TestCase): def test_doublet_grid_HP(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the heat pump scenario # Instantiate UTC properties, and set useHeatPump to True - utc_properties_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseHeatPump(True).build() + utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values output_grids = calculate_doublet_performance_stochastic(self.input_grids, utc_properties=utc_properties, rng_seed=123, p_values=self.p_values) @@ -59,8 +56,7 @@ class PyThermoGIS(TestCase): def test_doublet_grid_STIM(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the stimulation scenario # Instantiate UTC properties, and set useStim to True - utc_properties_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseStimulation(True).build() + utc_properties = instantiate_thermogis_parameters().setUseStimulation(True).setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values @@ -75,8 +71,7 @@ class PyThermoGIS(TestCase): def test_doublet_grid_HP_STIM(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the heat pump and stimulation scenario # Instantiate UTC properties, and set useStim to True - utc_properties_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseStimulation(True).setUseHeatPump(True).build() + utc_properties = instantiate_thermogis_parameters().setUseStimulation(True).setUseHeatPump(True).setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values output_grids = calculate_doublet_performance_stochastic(self.input_grids, utc_properties = utc_properties, p_values=self.p_values) -- GitLab From 0b170b03e8f994ce780e6d7155d3a34e6471326d Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 10:10:17 +0100 Subject: [PATCH 02/11] fixed some more tests --- .../deterministic_doublet.py | 4 ++-- .../doublet_simulation/stochastic_doublet.py | 2 +- src/pythermogis/thermogis_classes/doublet.py | 21 ++++++------------- tests/simulation/test_thermogis_scenarios.py | 13 +++++++++--- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/pythermogis/doublet_simulation/deterministic_doublet.py b/src/pythermogis/doublet_simulation/deterministic_doublet.py index 86acf5d..f8cb4b6 100644 --- a/src/pythermogis/doublet_simulation/deterministic_doublet.py +++ b/src/pythermogis/doublet_simulation/deterministic_doublet.py @@ -14,7 +14,7 @@ from pythermogis.thermogis_classes.utc_properties import ( ) -def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properties = None, rng_seed: int = None, chunk_size: int = None, print_execution_duration: bool = False, mask_value: float = np.nan) -> xr.Dataset: +def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properties = None, chunk_size: int = None, print_execution_duration: bool = False, mask_value: float = np.nan) -> xr.Dataset: """ Perform a deterministic Doublet performance simulation. @@ -109,7 +109,7 @@ def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properti reservoir_properties = auto_chunk_dataset(reservoir_properties, chunk_size) output_data = reservoir_properties.copy() - output_data = simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties, mask_value=mask_value) + output_data = simulate_doublet(output_data, reservoir_properties, utc_properties, mask_value=mask_value) if chunk_size is not None: output_data.load() # If chunking has occurred then the data must be de-chunked diff --git a/src/pythermogis/doublet_simulation/stochastic_doublet.py b/src/pythermogis/doublet_simulation/stochastic_doublet.py index a2db2da..c53fd60 100644 --- a/src/pythermogis/doublet_simulation/stochastic_doublet.py +++ b/src/pythermogis/doublet_simulation/stochastic_doublet.py @@ -140,7 +140,7 @@ def calculate_doublet_performance_stochastic( dask="parallelized", ) - output_data = simulate_doublet(output_data, reservoir_properties, rng_seed, utc_properties, mask_value=mask_value) + output_data = simulate_doublet(output_data, reservoir_properties, utc_properties, mask_value=mask_value) if chunk_size is not None: output_data.load() # If chunking has occurred then the data must be de-chunked if print_execution_duration: print(f"Doublet simulation took {timeit.default_timer() - start:.1f} seconds") return output_data diff --git a/src/pythermogis/thermogis_classes/doublet.py b/src/pythermogis/thermogis_classes/doublet.py index f9ca1b7..a693f20 100644 --- a/src/pythermogis/thermogis_classes/doublet.py +++ b/src/pythermogis/thermogis_classes/doublet.py @@ -5,7 +5,6 @@ from jpype import JClass def simulate_doublet( output_data: xr.Dataset, reservoir_properties: xr.Dataset, - rng_seed: int, utc_properties: JClass, mask_value: float = 0.0 ) -> xr.Dataset: @@ -23,11 +22,10 @@ def simulate_doublet( output_data.temperature, output_data.transmissivity, output_data.transmissivity_with_ntg, - rng_seed, kwargs={"utc_properties": utc_properties, "mask_value": mask_value}, dask="parallelized", - input_core_dims=[[], [], [], [], [], [], [], [], []], + input_core_dims=[[], [], [], [], [], [], [], []], output_core_dims=[[], [], [], [], [], [], [], [], [], [], [], [], [], []], vectorize=True, ) @@ -50,7 +48,7 @@ def simulate_doublet( return output_data -def calculate_performance_of_single_location(mask: float, depth: float, thickness: float, porosity: float, ntg: float, temperature: float, transmissivity: float, transmissivity_with_ntg: float, rng_seed: int, utc_properties: JClass = None, mask_value: float = 0.0) -> float: +def calculate_performance_of_single_location(mask: float, depth: float, thickness: float, porosity: float, ntg: float, temperature: float, transmissivity: float, transmissivity_with_ntg: float, utc_properties: JClass = None, mask_value: float = 0.0) -> float: """ Calculate the performance of a doublet at a single location. @@ -103,9 +101,9 @@ def calculate_performance_of_single_location(mask: float, depth: float, thicknes return (mask_value,) * 14 # Instantiate ThermoGIS doublet - doublet = instantiate_thermogis_doublet(utc_properties, rng_seed) + doublet = instantiate_thermogis_doublet(utc_properties) - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") input = DoubletInput( -9999.0, # unknowninput thickness, @@ -172,7 +170,7 @@ def validate_input(depth: float, """ return not np.any(np.isnan([depth, ntg, porosity, temperature, thickness, transmissivity, transmissivity_with_ntg])) -def instantiate_thermogis_doublet(utc_properties, rng_seed: int = None) -> JClass: +def instantiate_thermogis_doublet(utc_properties) -> JClass: """ Instantiate a ThermoGIS Doublet class, setting necessary parameters from utc_properties and optionally using a specified random seed. @@ -192,15 +190,8 @@ def instantiate_thermogis_doublet(utc_properties, rng_seed: int = None) -> JClas # Instantiate doublet class Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - # Create an instance of a ThermoGISDoublet - if rng_seed is not None: - rng = RNG(rng_seed) - else: - rng = RNG() - - doublet = ThermoGISDoublet(Mockito.mock(Logger), rng, utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) return doublet diff --git a/tests/simulation/test_thermogis_scenarios.py b/tests/simulation/test_thermogis_scenarios.py index 7fd9c1d..ddce3f9 100644 --- a/tests/simulation/test_thermogis_scenarios.py +++ b/tests/simulation/test_thermogis_scenarios.py @@ -42,7 +42,9 @@ class PyThermoGIS(TestCase): def test_doublet_grid_HP(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the heat pump scenario # Instantiate UTC properties, and set useHeatPump to True - utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).setupUTCParameters() + tg_properties = instantiate_thermogis_parameters() + tg_properties.setUseHeatpump(True) + utc_properties = tg_properties.setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values output_grids = calculate_doublet_performance_stochastic(self.input_grids, utc_properties=utc_properties, rng_seed=123, p_values=self.p_values) @@ -56,7 +58,9 @@ class PyThermoGIS(TestCase): def test_doublet_grid_STIM(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the stimulation scenario # Instantiate UTC properties, and set useStim to True - utc_properties = instantiate_thermogis_parameters().setUseStimulation(True).setupUTCParameters() + tg_properties = instantiate_thermogis_parameters() + tg_properties.setUseWellStimulation(True) + utc_properties = tg_properties.setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values @@ -71,7 +75,10 @@ class PyThermoGIS(TestCase): def test_doublet_grid_HP_STIM(self): # This tests that the python API produces (approximately) the same output as the Java code, when running on the same set of input data for the heat pump and stimulation scenario # Instantiate UTC properties, and set useStim to True - utc_properties = instantiate_thermogis_parameters().setUseStimulation(True).setUseHeatPump(True).setupUTCParameters() + tg_properties = instantiate_thermogis_parameters() + tg_properties.setUseWellStimulation(True) + tg_properties.setUseHeatpump(True) + utc_properties = tg_properties.setupUTCParameters() # Run calculation across all dimensions of input_grids, and all provided P_values output_grids = calculate_doublet_performance_stochastic(self.input_grids, utc_properties = utc_properties, p_values=self.p_values) -- GitLab From 072daddb742e363e371fbec10628fe291c184011 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 14:50:29 +0100 Subject: [PATCH 03/11] fixed some more tests --- src/pythermogis/__init__.py | 2 +- .../deterministic_doublet.py | 2 +- .../doublet_simulation/stochastic_doublet.py | 2 +- src/pythermogis/main.py | 4 +- .../thermogis_classes/potential_properties.py | 22 --- .../thermogis_classes/properties.py | 36 ++++ .../thermogis_classes/utc_properties.py | 63 ------- tests/documentation/test_doc_examples.py | 4 +- tests/java/test_ThermoGISDoublet_Benchmark.py | 159 ++++++++---------- tests/java/test_utc_properties.py | 28 ++- tests/potential/test_potential.py | 6 +- .../test_pythermogis_doublet_benchmark.py | 121 +++++++------ 12 files changed, 201 insertions(+), 248 deletions(-) delete mode 100644 src/pythermogis/thermogis_classes/potential_properties.py create mode 100644 src/pythermogis/thermogis_classes/properties.py delete mode 100644 src/pythermogis/thermogis_classes/utc_properties.py diff --git a/src/pythermogis/__init__.py b/src/pythermogis/__init__.py index 54e8577..f56a5c7 100644 --- a/src/pythermogis/__init__.py +++ b/src/pythermogis/__init__.py @@ -1,6 +1,6 @@ from pythermogis.jvm.jvm_start import * from pythermogis.thermogis_classes.doublet import * -from pythermogis.thermogis_classes.utc_properties import * +from pythermogis.thermogis_classes.properties import * from pythermogis.transmissivity.calculate_thick_perm_trans import * from pythermogis.tables.utc_properties_table import * from pythermogis.postprocessing.pos import * diff --git a/src/pythermogis/doublet_simulation/deterministic_doublet.py b/src/pythermogis/doublet_simulation/deterministic_doublet.py index f8cb4b6..5d6c74c 100644 --- a/src/pythermogis/doublet_simulation/deterministic_doublet.py +++ b/src/pythermogis/doublet_simulation/deterministic_doublet.py @@ -9,7 +9,7 @@ from pythermogis.dask_utils.auto_chunk import auto_chunk_dataset from pythermogis.physics.temperature_grid_calculation import ( calculate_temperature_from_gradient, ) -from pythermogis.thermogis_classes.utc_properties import ( +from pythermogis.thermogis_classes.properties import ( instantiate_thermogis_parameters, ) diff --git a/src/pythermogis/doublet_simulation/stochastic_doublet.py b/src/pythermogis/doublet_simulation/stochastic_doublet.py index c53fd60..0ca77e3 100644 --- a/src/pythermogis/doublet_simulation/stochastic_doublet.py +++ b/src/pythermogis/doublet_simulation/stochastic_doublet.py @@ -7,7 +7,7 @@ from pythermogis import simulate_doublet from pythermogis.dask_utils.auto_chunk import auto_chunk_dataset from pythermogis.physics.temperature_grid_calculation import calculate_temperature_from_gradient from pythermogis.transmissivity.calculate_thick_perm_trans import generate_thickness_permeability_transmissivity_for_pvalues -from pythermogis.thermogis_classes.utc_properties import instantiate_thermogis_parameters +from pythermogis.thermogis_classes.properties import instantiate_thermogis_parameters def calculate_doublet_performance_stochastic( reservoir_properties: xr.Dataset, diff --git a/src/pythermogis/main.py b/src/pythermogis/main.py index 7cbcd55..6b1cd18 100644 --- a/src/pythermogis/main.py +++ b/src/pythermogis/main.py @@ -5,7 +5,7 @@ import typer import xarray as xr from pythermogis import calculate_doublet_performance -from pythermogis.thermogis_classes.potential_properties import instantiate_potential_properties_builder +from pythermogis.thermogis_classes.properties import instantiate_thermogis_parameters from pythermogis.potential.potential import calculate_potential app = typer.Typer(pretty_exceptions_enable=False) @@ -77,7 +77,7 @@ def potential( depth: float = typer.Option(500, help="The depth of the aquifer, +ive downwards, units: [m]"), ) -> None: """Perform the potential calculation for a given location.""" - properties = instantiate_potential_properties_builder().build() + properties = instantiate_thermogis_parameters().setupPotentialParameters() results = calculate_potential(properties, porosity, temperature, depth, thickness, ntg) print("\n---potential results---") diff --git a/src/pythermogis/thermogis_classes/potential_properties.py b/src/pythermogis/thermogis_classes/potential_properties.py deleted file mode 100644 index 5f514dd..0000000 --- a/src/pythermogis/thermogis_classes/potential_properties.py +++ /dev/null @@ -1,22 +0,0 @@ -from jpype import JClass - -from pythermogis import start_jvm - - -def instantiate_potential_properties_builder() -> JClass: - """ - Create and return a ``PotentialPropertiesBuilder`` Java object. - - The builder wraps the ThermoGIS **PotentialPropertiesBuilder** Java class, which can - - * parse ThermoGIS scenario XML files, and - * programmatically modify individual scenario parameters prior to running a simulation. - - Returns - ------- - potential_properties_builder : jpype.JClass - An instantiated ``PotentialPropertiesBuilder`` that can be used to build or modify - ``PotentialProperties`` objects for ThermoGIS simulations. - """ - start_jvm() - return JClass("thermogis.properties.builders.PotentialPropertiesBuilder")() diff --git a/src/pythermogis/thermogis_classes/properties.py b/src/pythermogis/thermogis_classes/properties.py new file mode 100644 index 0000000..2c1cf5a --- /dev/null +++ b/src/pythermogis/thermogis_classes/properties.py @@ -0,0 +1,36 @@ +from pathlib import Path + +from jpype import JClass + +from pythermogis import start_jvm + + +def instantiate_thermogis_properties_from_file(xml_file: str | Path) -> JClass: + """Provided the path to an xml scenario file, parse this file for the utc properties; beware, the xml parses does some validation checks, checking that files exist. + Even if these parameters are not needed by the pyThermoGIS module, if these validation checks fail, the xml parser will fail. To get around this set these variables to null""" + start_jvm() + + # parse to string and pass to the Java utc xml parser + tg_parameters = JClass("thermogis.parameters.ThermoGISParameters")() + java_file_object = JClass("java.io.File") + tg_file = java_file_object(str(xml_file)) + tg_parameters.readSettingsFromFile(tg_file) + tg_parameters.setInputDataDir("") + tg_parameters.setResultsDir("") + return tg_parameters + +def instantiate_thermogis_parameters() -> JClass: + """ + Create and return a ``ThermoGISParameters`` Java object. + + The ThermoGISParameters holds the input parameters for all TG calculations, and + can be used to setup the record classes for the 4 calculations. + + + Returns + ------- + ThermoGISParameters : jpype.JClass + An instantiated ``ThermoGISParameters``. + """ + start_jvm() + return JClass("thermogis.parameters.ThermoGISParameters")() diff --git a/src/pythermogis/thermogis_classes/utc_properties.py b/src/pythermogis/thermogis_classes/utc_properties.py deleted file mode 100644 index e8821fd..0000000 --- a/src/pythermogis/thermogis_classes/utc_properties.py +++ /dev/null @@ -1,63 +0,0 @@ -import typing as t -import xml.etree.ElementTree as ET -from pathlib import Path - -from jpype import JClass - -from pythermogis import start_jvm - - -def instantiate_utc_properties_from_xml(xml_file: str | Path) -> JClass: - """Provided the path to an xml scenario file, parse this file for the utc properties; beware, the xml parses does some validation checks, checking that files exist. - Even if these parameters are not needed by the pyThermoGIS module, if these validation checks fail, the xml parser will fail. To get around this set these variables to null""" - start_jvm() - root = ET.parse(xml_file).getroot() - - # change the parameters input_data_directory, results_directory, and temperature_voxet_file to null; these parameters are not used by pyThermoGIS, and if they are not null then the UTCXmlParser will check for directory and file - # existence and cause the parsing to fail if they do not exist. - variables = [root.find(variable) for variable in ["input_data_directory", "results_directory", "temperature_voxet_file"]] - for var in variables: - var.text = "" - - # parse to string and pass to the Java utc xml parser - return JClass("thermogis.properties.parsers.UTCXmlParser")().parse(ET.tostring(root, encoding='utf8', method='xml')) - -def instantiate_thermogis_parameters() -> JClass: - """ - Create and return a ``ThermoGISParameters`` Java object. - - The ThermoGISParameters holds the input parameters for all TG calculations, and - can be used to setup the record classes for the 4 calculations. - - - Returns - ------- - ThermoGISParameters : jpype.JClass - An instantiated ``ThermoGISParameters``. - """ - start_jvm() - return JClass("thermogis.parameters.ThermoGISParameters")() - -def get_viscosity_mode(mode: t.Literal["kestin", "batzlewang"]) -> JClass: - """ - Map a string to the Java ViscosityMode enum. - - Parameters - ---------- - mode : Literal["kestin", "batzlewang"] - The viscosity mode to select. - - Returns - ------- - viscosity_mode_enum : jpype.JClass - The corresponding Java enum instance. - """ - start_jvm() - viscosity_mode = JClass("tno.geoenergy.ViscosityMode") - - if mode == "kestin": - return viscosity_mode.KESTIN - elif mode == "batzlewang": - return viscosity_mode.BATZLEWANG - else: - raise ValueError(f"Unknown viscosity mode: {mode}") \ No newline at end of file diff --git a/tests/documentation/test_doc_examples.py b/tests/documentation/test_doc_examples.py index 8721d4b..8d31cf4 100644 --- a/tests/documentation/test_doc_examples.py +++ b/tests/documentation/test_doc_examples.py @@ -43,7 +43,9 @@ def test_example_3(): "permeability": 300, }) - utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).setupUTCParameters() + tg_properties = instantiate_thermogis_parameters() + tg_properties.setUseHeatpump(True) + utc_properties = tg_properties.setupUTCParameters() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) print(results) diff --git a/tests/java/test_ThermoGISDoublet_Benchmark.py b/tests/java/test_ThermoGISDoublet_Benchmark.py index a324616..1109a83 100644 --- a/tests/java/test_ThermoGISDoublet_Benchmark.py +++ b/tests/java/test_ThermoGISDoublet_Benchmark.py @@ -19,16 +19,14 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - UTCPropertiesBuilder = JClass("thermogis.properties.builders.UTCPropertiesBuilder") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - - utc_properties = (UTCPropertiesBuilder() - .setViscosityMode(ViscosityMode.KESTIN) - .setDhReturnTemp(40) - .build()) + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") + ThermoGISParameters = JClass("thermogis.parameters.ThermoGISParameters") + + tg_parameters = ThermoGISParameters() + tg_parameters.setUseKestinViscosity(True) + tg_parameters.setDhReturnTemp(40) + utc_properties = tg_parameters.setupUTCParameters() permeability = 175 thickness = 100 transmissivity = thickness * permeability @@ -46,7 +44,7 @@ class ThermoGISDoubletBenchmark(TestCase): None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act @@ -70,17 +68,15 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") - utc_properties = (self.setup_template_tg_properties() - .setOpexBase(0) - .setDhReturnTemp(40) - .setViscosityMode(ViscosityMode.KESTIN) - .setUseStimulation(False) - .setupUTCParameters()) + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setOpexBase(0) + tg_parameters.setDhReturnTemp(40) + tg_parameters.setUseKestinViscosity(True) + tg_parameters.setUseWellStimulation(False) + utc_properties = tg_parameters.setupUTCParameters() thickness = 100 permeability = 175 @@ -98,7 +94,7 @@ class ThermoGISDoubletBenchmark(TestCase): temperature, None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act results = doublet.calculateDoubletPerformance(input) @@ -122,19 +118,17 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - - utc_properties = (self.setup_template_tg_properties() - .setCapexConst(0.5) - .setCapexVariable(1100) - .setHeatExchangerEfficiency(0.4) - .setHeatExchangerParasitic(0.1) - .setDhReturnTemp(60) - .setViscosityMode(ViscosityMode.KESTIN) - .setupUTCParameters()) + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") + + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setCapexConstant(0.5) + tg_parameters.setCapexVariable(1100) + tg_parameters.setHeatExchangerEfficiency(0.4) + tg_parameters.setHeatExchangerParasitic(0.1) + tg_parameters.setDhReturnTemp(60) + tg_parameters.setUseKestinViscosity(True) + utc_properties = tg_parameters.setupUTCParameters() thickness = 100 permeability = 175 @@ -152,7 +146,7 @@ class ThermoGISDoubletBenchmark(TestCase): temperature, None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act results = doublet.calculateDoubletPerformance(input) @@ -176,19 +170,17 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - - utc_properties = (self.setup_template_tg_properties() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(70) - .setUseHeatPump(True) - .setDhReturnTemp(35) - .setViscosityMode(ViscosityMode.KESTIN) - .setupUTCParameters()) + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") + + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setOpexPower(100) + tg_parameters.setOpexBase(0) + tg_parameters.setGoalTemperature(70) + tg_parameters.setUseHeatpump(True) + tg_parameters.setDhReturnTemp(35) + tg_parameters.setUseKestinViscosity(True) + utc_properties = tg_parameters.setupUTCParameters() thickness = 100 permeability = 175 @@ -206,7 +198,7 @@ class ThermoGISDoubletBenchmark(TestCase): temperature, None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act results = doublet.calculateDoubletPerformance(input) @@ -231,20 +223,17 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - - utc_properties = (self.setup_template_tg_properties() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(80) - #.setHpApplicationMode(True) - .setUseHeatPump(True) - .setDhReturnTemp(50) - .setViscosityMode(ViscosityMode.KESTIN) - .setupUTCParameters()) + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") + + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setOpexPower(100) + tg_parameters.setOpexBase(0) + tg_parameters.setGoalTemperature(80) + tg_parameters.setUseHeatpump(True) + tg_parameters.setDhReturnTemp(50) + tg_parameters.setUseKestinViscosity(True) + utc_properties = tg_parameters.setupUTCParameters() thickness = 100 permeability = 175 @@ -262,7 +251,7 @@ class ThermoGISDoubletBenchmark(TestCase): temperature, None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act results = doublet.calculateDoubletPerformance(input) @@ -286,19 +275,18 @@ class ThermoGISDoubletBenchmark(TestCase): start_jvm() Logger = JClass("logging.Logger") Mockito = JClass("org.mockito.Mockito") - RNG = JClass("tno.geoenergy.stochastic.RandomNumberGenerator") ThermoGISDoublet = JClass("thermogis.calc.utc.doublet.ThermoGisDoublet") - DoubletInput = JClass("thermogis.calc.utc.doublet.records.DoubletInput") - ViscosityMode = JClass("tno.geoenergy.ViscosityMode") - - utc_properties = (self.setup_template_tg_properties() - .setCapexConst(0) - .setCapexVariable(2300) - .setHeatExchangerEfficiency(0.6) - .setUseORC(True) - .setViscosityMode(ViscosityMode.KESTIN) - .setDhReturnTemp(60) - .setHeatExchangerBasetemp(20).setupUTCParameters()) + DoubletInput = JClass("thermogis.calc.utc.doublet.Doublet.DoubletInput") + + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setCapexConstant(0) + tg_parameters.setCapexVariable(2300) + tg_parameters.setHeatExchangerEfficiency(0.6) + tg_parameters.setUseORC(True) + tg_parameters.setDhReturnTemp(60) + tg_parameters.setHeatExchangerBaseTemp(20) + tg_parameters.setUseKestinViscosity(True) + utc_properties = tg_parameters.setupUTCParameters() thickness = 100 permeability = 175 @@ -316,7 +304,7 @@ class ThermoGISDoubletBenchmark(TestCase): temperature, None, # ates input ) - doublet = ThermoGISDoublet(Mockito.mock(Logger), RNG(0), utc_properties) + doublet = ThermoGISDoublet(Mockito.mock(Logger), utc_properties) # Act results = doublet.calculateDoubletPerformance(input) @@ -332,15 +320,16 @@ class ThermoGISDoubletBenchmark(TestCase): self.assertTrue(np.isclose(12.44409167482118, results.capex(), 0.001)) def setup_template_tg_properties(self): - return (instantiate_thermogis_parameters() - .setSalinityGradient(47.0) - .setDrillingTime(1) - .setTaxRate(20) - .setEquityReturn(15) - .setOpexBase(10000) - .setOpexPerPower(50) - .setWellCostScaling(1) - .setOpexPerEnergy(0) - .setWellCostConst(0.375) - .setWellCostZ(1050) - .setWellCostZ2(0.3)) \ No newline at end of file + tg_parameters = JClass("thermogis.parameters.ThermoGISParameters")() + tg_parameters.setSalinityGradient(47.0) + tg_parameters.setDrillingTime(1) + tg_parameters.setTaxRate(20) + tg_parameters.setEquityReturn(15) + tg_parameters.setOpexBase(10000) + tg_parameters.setOpexPower(50) + tg_parameters.setWellCostScaling(1) + tg_parameters.setOpexEnergy(0) + tg_parameters.setWellCostConstant(0.375) + tg_parameters.setWellCostDepth(1050) + tg_parameters.setWellCostDepth2(0.3) + return tg_parameters diff --git a/tests/java/test_utc_properties.py b/tests/java/test_utc_properties.py index 3a227eb..9357ed6 100644 --- a/tests/java/test_utc_properties.py +++ b/tests/java/test_utc_properties.py @@ -7,16 +7,36 @@ class UTCBuilder(TestCase): def test_tg_scenario_xmls_parse_and_run(self): # These are the current 2.4 scenario settings, for BaseCase, HP, Stim and HP&Stim - scenarios = ["doublet_techno-econ_basecase.xml", "doublet_techno-econ_HP.xml", "doublet_techno-econ_STIM.xml", "doublet_techno-econ_STIM_HP.xml"] - utc_properties = [instantiate_utc_properties_from_xml(self.scenarios_file_path / scenario) for scenario in scenarios] + scenarios = [ + "doublet_techno-econ_basecase.xml", + "doublet_techno-econ_HP.xml", + "doublet_techno-econ_STIM.xml", + "doublet_techno-econ_STIM_HP.xml", + ] + utc_properties = [] + for scenario in scenarios: + tg_properties = instantiate_thermogis_properties_from_file( + self.scenarios_file_path / scenario + ) + utc_properties.append(tg_properties.setupUTCParameters()) # If test reaches here, then parsing of xml's worked, check that the scenarios actually run on a set of test data: [self.run_scenario(utc_property) for utc_property in utc_properties] def test_ga4a_scenario_xmls_parse_and_run(self): # The ga4a scenarios no longer work as they are missing necessary input parameters; they were generated by an older version of TG, I corrected them using the gui, producing a new set of configs. - scenarios = ["ga4a_ORC_new_config.xml", "ga4a_directheat_new_config.xml", "ga4a_directheatHP_new_config.xml", "ga4a_chiller_new_config.xml"] - utc_properties = [instantiate_utc_properties_from_xml(self.scenarios_file_path / scenario) for scenario in scenarios] + scenarios = [ + "ga4a_ORC_new_config.xml", + "ga4a_directheat_new_config.xml", + "ga4a_directheatHP_new_config.xml", + "ga4a_chiller_new_config.xml", + ] + utc_properties = [] + for scenario in scenarios: + tg_properties = instantiate_thermogis_properties_from_file( + self.scenarios_file_path / scenario + ) + utc_properties.append(tg_properties.setupUTCParameters()) # If test reaches here, then parsing of xml's worked, check that the scenarios actually run on a set of test data: [self.run_scenario(utc_property) for utc_property in utc_properties] diff --git a/tests/potential/test_potential.py b/tests/potential/test_potential.py index be5ac85..f759f45 100644 --- a/tests/potential/test_potential.py +++ b/tests/potential/test_potential.py @@ -6,13 +6,11 @@ from pythermogis.potential.potential import ( calculate_potential, calculate_heat_in_place, ) -from pythermogis.thermogis_classes.potential_properties import ( - instantiate_potential_properties_builder, -) +from pythermogis.thermogis_classes.properties import instantiate_thermogis_parameters def test_calculate_potential(): - properties = instantiate_potential_properties_builder().build() + properties = instantiate_thermogis_parameters().setupPotentialParameters() results = calculate_potential( properties, diff --git a/tests/simulation/test_pythermogis_doublet_benchmark.py b/tests/simulation/test_pythermogis_doublet_benchmark.py index 244a9ce..cedab2e 100644 --- a/tests/simulation/test_pythermogis_doublet_benchmark.py +++ b/tests/simulation/test_pythermogis_doublet_benchmark.py @@ -9,13 +9,11 @@ class ThermoGISDoubletBenchmark(TestCase): """ def test_calculateDoubletPerformanceTest(self): - viscosity_mode = get_viscosity_mode("kestin") - utc_properties = ( - instantiate_thermogis_parameters() - .setDhReturnTemp(40) - .setViscosityMode(viscosity_mode) - .setupUTCParameters() - ) + tg_parameters = instantiate_thermogis_parameters() + tg_parameters.setDhReturnTemp(40) + tg_parameters.setUseKestinViscosity(True) + utc_properties = tg_parameters.setupUTCParameters() + input_data = xr.Dataset( { @@ -50,9 +48,10 @@ class ThermoGISDoubletBenchmark(TestCase): """ # Arrange # Instantiate the UTC properties class - utc_properties = ( - self.setup_template_tg_properties().setOpexBase(0).setupUTCParameters() - ) + tg_properties = self.setup_template_tg_properties() + tg_properties.setOpexBase(0) + + utc_properties = tg_properties.setupUTCParameters() input_data = xr.Dataset( { @@ -88,15 +87,14 @@ class ThermoGISDoubletBenchmark(TestCase): """ # Arrange # Instantiate the UTC properties class - utc_properties = ( - self.setup_template_tg_properties() - .setCapexConst(0.5) - .setCapexVariable(1100) - .setHeatExchangerEfficiency(0.4) - .setDhReturnTemp(60) - .setHeatExchangerParasitic(0.1) - .setupUTCParameters() - ) + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setCapexConstant(0.5) + tg_parameters.setCapexVariable(1100) + tg_parameters.setHeatExchangerEfficiency(0.4) + tg_parameters.setDhReturnTemp(60) + tg_parameters.setHeatExchangerParasitic(0.1) + + utc_properties = tg_parameters.setupUTCParameters() input_data = xr.Dataset( { @@ -133,16 +131,14 @@ class ThermoGISDoubletBenchmark(TestCase): """ # Arrange # Instantiate the UTC properties class - utc_properties = ( - self.setup_template_tg_properties() - .setCapexConst(0) - .setCapexVariable(2300) - .setHeatExchangerEfficiency(0.6) - .setUseORC(True) - .setHeatExchangerBasetemp(20) - .setDhReturnTemp(60) - .setupUTCParameters() - ) + tg_parameters = self.setup_template_tg_properties() + tg_parameters.setCapexConstant(0) + tg_parameters.setCapexVariable(2300) + tg_parameters.setHeatExchangerEfficiency(0.6) + tg_parameters.setUseORC(True) + tg_parameters.setHeatExchangerBaseTemp(20) + tg_parameters.setDhReturnTemp(60) + utc_properties = tg_parameters.setupUTCParameters() input_data = xr.Dataset( { @@ -179,15 +175,13 @@ class ThermoGISDoubletBenchmark(TestCase): """ # Arrange # Instantiate the UTC properties class - utc_properties = ( - self.setup_template_tg_properties() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(70) - .setUseHeatPump(True) - .setDhReturnTemp(35) - .setupUTCParameters() - ) + tg_properties = self.setup_template_tg_properties() + tg_properties.setOpexPower(100) + tg_properties.setOpexBase(0) + tg_properties.setGoalTemperature(70) + tg_properties.setUseHeatpump(True) + tg_properties.setDhReturnTemp(35) + utc_properties = tg_properties.setupUTCParameters() input_data = xr.Dataset( { @@ -211,34 +205,33 @@ class ThermoGISDoubletBenchmark(TestCase): # Assert - self.assertTrue(np.isclose(5.856159806251526, results.power + power_hpelec, 0.1)) + print(results.capex) + self.assertTrue(np.isclose(7.06616794, results.power + power_hpelec, 0.1)) self.assertTrue(np.isclose(8.83718197747828, results.utc * power_ratio, 0.1)) self.assertTrue(np.isclose(17499.99940, 17500, 0.001)) - self.assertTrue(np.isclose(163.99771118164062, results.flow_rate, 0.001)) + self.assertTrue(np.isclose(152.5, results.flow_rate, 0.001)) self.assertTrue(np.isclose(60, results.pres, 0.001)) - self.assertTrue(np.isclose(4.97566556930542, results.power, 0.001)) - self.assertTrue(np.isclose(989.2578125, results.welld, 0.001)) - self.assertTrue(np.isclose(4.383212200392486, results.cop, 0.001)) - self.assertTrue(np.isclose(3.798196792602539, results.cophp, 0.001)) - self.assertTrue(np.isclose(10.401010755009017, results.utc, 0.001)) - self.assertTrue(np.isclose(16.50359210062243, results.capex, 0.001)) + self.assertTrue(np.isclose(5.673, results.power, 0.001)) + self.assertTrue(np.isclose(955.3, results.welld, 0.001)) + self.assertTrue(np.isclose(3.89047122, results.cop, 0.001)) + self.assertTrue(np.isclose(3.405, results.cophp, 0.001)) + self.assertTrue(np.isclose(10.36858654, results.utc, 0.001)) + self.assertTrue(np.isclose(17.3787117, results.capex, 0.001)) def setup_template_tg_properties(self): - viscosity_mode = get_viscosity_mode("kestin") - - return ( - instantiate_thermogis_parameters() - .setSalinityGradient(47.0) - .setDrillingTime(1) - .setTaxRate(20) - .setEquityReturn(15) - .setOpexBase(10000) - .setOpexPerPower(50) - .setWellCostScaling(1) - .setOpexPerEnergy(0) - .setWellCostConst(0.375) - .setWellCostZ(1050) - .setWellCostZ2(0.3) - .setDhReturnTemp(40) - .setViscosityMode(viscosity_mode) - ) \ No newline at end of file + tg_parameters = instantiate_thermogis_parameters() + tg_parameters.setSalinityGradient(47.0) + tg_parameters.setDrillingTime(1) + tg_parameters.setTaxRate(20) + tg_parameters.setEquityReturn(15) + tg_parameters.setOpexBase(10000) + tg_parameters.setOpexPower(50) + tg_parameters.setWellCostScaling(1) + tg_parameters.setOpexEnergy(0) + tg_parameters.setWellCostConstant(0.375) + tg_parameters.setWellCostDepth(1050) + tg_parameters.setWellCostDepth2(0.3) + tg_parameters.setDhReturnTemp(40) + tg_parameters.setUseKestinViscosity(True) + + return tg_parameters \ No newline at end of file -- GitLab From df343d4d052832a8df34eaa2a88e57258cfd677a Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 14:53:21 +0100 Subject: [PATCH 04/11] fixed some more tests --- tests/java/test_ThermoGISDoublet_Benchmark.py | 11 ++++++----- .../simulation/test_pythermogis_doublet_benchmark.py | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/java/test_ThermoGISDoublet_Benchmark.py b/tests/java/test_ThermoGISDoublet_Benchmark.py index 1109a83..6278fb1 100644 --- a/tests/java/test_ThermoGISDoublet_Benchmark.py +++ b/tests/java/test_ThermoGISDoublet_Benchmark.py @@ -204,14 +204,15 @@ class ThermoGISDoubletBenchmark(TestCase): results = doublet.calculateDoubletPerformance(input) # Assert + print(results) self.assertTrue(np.isclose(17499.99940, transmissivity, 0.001)) self.assertTrue(np.isclose(163.99771118164062, results.flow(), 1)) self.assertTrue(np.isclose(60, results.pres(), 0.001)) - self.assertTrue(np.isclose(4.97566556930542, results.power(), 0.001)) - self.assertTrue(np.isclose(989.2578125, results.welld(), 0.001)) - self.assertTrue(np.isclose(4.383212200392486, results.cop(), 0.001)) - self.assertTrue(np.isclose(10.401010755009017, results.utc(), 0.001)) - self.assertTrue(np.isclose(16.50359210062243, results.capex(), 0.001)) + self.assertTrue(np.isclose(5.6734843, results.power(), 0.001)) + self.assertTrue(np.isclose(955.27344, results.welld(), 0.001)) + self.assertTrue(np.isclose(3.8904712, results.cop(), 0.001)) + self.assertTrue(np.isclose(10.368587, results.utc(), 0.001)) + self.assertTrue(np.isclose(17.378712, results.capex(), 0.001)) @pytest.mark.skip("This test requires a fix in the java core. ignore until fix is pushed") def test_calculateDoubletPerformance_directheatHP_App(self): diff --git a/tests/simulation/test_pythermogis_doublet_benchmark.py b/tests/simulation/test_pythermogis_doublet_benchmark.py index cedab2e..b004982 100644 --- a/tests/simulation/test_pythermogis_doublet_benchmark.py +++ b/tests/simulation/test_pythermogis_doublet_benchmark.py @@ -205,7 +205,6 @@ class ThermoGISDoubletBenchmark(TestCase): # Assert - print(results.capex) self.assertTrue(np.isclose(7.06616794, results.power + power_hpelec, 0.1)) self.assertTrue(np.isclose(8.83718197747828, results.utc * power_ratio, 0.1)) self.assertTrue(np.isclose(17499.99940, 17500, 0.001)) -- GitLab From 5fda73cad5ca75f045f365f08f7cceead6b9044a Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 15:13:42 +0100 Subject: [PATCH 05/11] fixed all tests --- .../doublet/HP/simplified__hprod_P10_HP.nc | Bin 2368 -> 9412 bytes .../doublet/HP/simplified__hprod_P50_HP.nc | Bin 2368 -> 9412 bytes .../doublet/HP/simplified__hprod_P90_HP.nc | Bin 2368 -> 9412 bytes .../doublet/HP/simplified__npv_P10_HP.nc | Bin 2368 -> 9412 bytes .../HP_STIM/simplified__hprod_P10_HP_STIM.nc | Bin 2368 -> 9412 bytes .../HP_STIM/simplified__hprod_P50_HP_STIM.nc | Bin 2368 -> 9412 bytes .../HP_STIM/simplified__hprod_P90_HP_STIM.nc | Bin 2368 -> 9412 bytes 7 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P10_HP.nc b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P10_HP.nc index 91201b282981cdd80e54d0d4c97912956090cd0a..32af1c20f386665a650de5ba04e74b7cd07aa517 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGNBOLNPEf{C4!740b;6bVf$7dzcs*8KK59z-bYXiv<PD&L>L(2{ZdPkQ_@VF z^Ye>RGV>BkQi~Y`I2gbo!@!`x0CFfe92pouZUE^8V;*e~pP7M;fdi!0*~c+Bm_e9< zfdLd`px|)v^mX+M_Vo9Q4|aC+ab@6sY%*{+ebraYH3=BLjAa^n|a5IR2z2cUclM|MhQ<}yBPGq$ z)=785qD_Do_sq z<~bM*^57A0mkiXOfnXRPq-K)KEMJhDVKJczjR~+v85kINau^s`8JHRP84N%!2y%6E z4RZB!c8v$Sz>EpfAxcRsNi0q+VPJqcB_%UAH4oJGW#9mHm>`B??`^?C4-~Q>EOq1B zGh`PzLNqhb-$kIX1Gz{f)zue7kK)k~7!85Z5EwZj;O^}211<$Yg*eg(8El{qHq;2J zNkE|j6Ne2Lg2X`h0JLEPVvpj{5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c J4S~TG0st8GR}=sM literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32@zQ25@zVAw^3vA6@1-4B;H6zL*-N|Z2`GVj c$qDs%Y3D6-RA69mT)@EK_PD&L>L(2{ZdPkQ_@VF z^Ye>RGV>BkQi~Y`I2gbo!@!`x0CFfe92pouZUE^8V;*e~pP7M;fdi!0*~c+Bm_e9< zfdLd`px|)v^mX+M_Vo9Q4|aC+ab@6sY%*{+ebraYH3=BLjAa^n|a5IR2z2cUclM|MhQ<}yBPGq$ z)=oCKgmzHh2NqW- zh0qYA85kPW`|Uvb90YxxKr~EzlpYO%(GVC7fzc2c4S~@RpmPX-niP=Mt_?rLYFKL* z)WRXU#RzJlP_xB&ouR%R(qd#_WCZtDn3%9M>LD&Bvysms1k%pT7zygAFfcH9fVfCq z7iQeed}tetgl0adMFuh-MuXU(K!b$+H)yYB3rHA**+B#puaS)I0Ywv=1W1691=giu z%_u0!PdNf@0bk)`;RC4x#R8~dN_o4TCkE1~;Aap3^#Blk4j<3p5C%zTcSM|l0oZmAhVemaCb`V=1-Tg(6PnPN0DF{yfq^H7fq|8QnSr0d0OW!o zS2x!nS3hUhc(4o1m>?aZl*E$6;?xob2AES)GILY&Ky6*#BaM*32I^o# zji8zY6e=)r*nlBO41^Cr8#W;JC>{-g(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c M4S~@R7+fI$0M)ctDF6Tf literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32@zQ497`xy1(ZNN cf8VJ05-SpNRA69mT)@EK_PD&L>L(2{ZdPkQ_@VF z^Ye>RGV>BkQi~Y`I2gbo!@!`x0CFfe92pouZUE^8V;*e~pP7M;fdi!0*~c+Bm_e9< zfdLd`px|)v^mX+M_Vo9Q4|aC+ab@6sY%*{+ebraYH3=BLjAa^n|a5IR2z2cUclM|MhQ<}yBPGq$ z)=4d*BR>DAuUD*Mn-Udg^3AEqaNa7G8_3ELLlwTjFF&@3IhX! z2Z)Q*bz#Qc%!jtYNNDDRT4W&eVKj&h3N%RAe}ndFwt$2|m>onw@fykK9#Ax~Nq__x zSzuin){KIp{FEcm7Vs557Cw+FP%MBNrj)nad14@)3VsFwP!9mn=kW0i4q=dlc1Oe+ z7{FaBP!9m+IT#J{;1O__4Ah^2U>F~yW|GS+Uyz$&F`)^K39v^Q7#MhR7#LU?m>KvP z3_vaja&>bJa`kg|jR(8Hj0w^qN=Yn9EKV(9V1PL#B{MfQ57hQ$-~e@)AckV^ZNWkh z6tW;Jb>rGIWEVL?G&9iOMWC<)xkx0{)fYsM;?WQo4S~@R7&#%}?(FXaE(Jk_IMN6i zY@iM{)Cj6cK%oK?hYc8l#6b7}v|$5ckK)k~7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z Q5Eu=C(GVC7fx#650E?AZrvLx| literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32@zQ4Z@Y43Z=%sC>=OwZJwwE@$sF!w~8YqE! c?n{jKe7!Q+QGtQMaRCE^;|B%?WHv|*0L_eEe*gdg diff --git a/tests/resources/test_benchmark_output/doublet/HP/simplified__npv_P10_HP.nc b/tests/resources/test_benchmark_output/doublet/HP/simplified__npv_P10_HP.nc index ee37e5c3f9e080fea204f0c6ec100e984ce2a314..689daa3453d4c88743e32b17781b9477f402c267 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGK?B2L=X)mvcQQf}PJhoskjj9wtUcMyRn2a9RZ9VnGFa21tN7Fqm*NnEYpE zU|{6~$uMg{#6hP2sE63Kf)B)FV3-7<;C^Dm=_ejXkWyv_5e6Ox5e9~MztocClr$6P z{QRPn%)G>s)M5q!4hC?@Ffb@EfE)@AM+OFv8$f!&m`5ALXJ%ky-~g$0_HhgjW)Nmz zU;qUfC^%d^eO>*6J^lUSgPk3HTp4&|7#Nrsm>F0h8vGo6UBT)>YC*V?0c0dI12Y33 z0}seZn9E!;b2C#=-2`?40|So>$eqj#+zcXMuefFA7WE8ie#u9MVdSi=gx*u^ob%+l!3yNk%5X)RKdW&;9?gcj4eJu7H*H#UhD7d;mzX; z@+v4I!D%Dj&pDtdzaX`!Br~-b9Os}c42tuz)S}|d{5)GDojhF~Uz)jq&tdEH7V(#s{0^QL557(B=XVIc z=3Ka=io; zn6NbJAucAfk8Aub12C+eb1_}Ew z&|b|JkT3|dg9s=tn;3Z%6isYmAOS`ec$X%xpzH{={mZ-JrVdCAC=Ni)Qp#KHJTZ_i z1wVrTsQr)Vark%!hcHM&J0s!@4B!qGsQnM~8jJ>c?+Ca<2I|c~FpLjUGs$I^FUZZX zc+iB#g9ON%3=9lBISdS}49pDt3c+Ka$S!h(Xl9_li$Gxqa+OG`t1pNi#iJoG z8UmvsFp@&R-PzvVYaikG4*gzd@s1a0`fWieP4jV88iGlC|Xu}4?9>t>}Fd71* kAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0)s0A0D;tEt^fc4 literal 2368 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 Lfzc2cTp<7e<`7pD literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32@zQ497`xy1(ZNN cf8VJ05-SpNRA69mT)@EK_PD&L>L(2{ZdPkQ_@VF z^Ye>RGV>BkQi~Y`I2gbo!@!`x0CFfe92pouZUE^8V;*e~pP7M;fdi!0*~c+Bm_e9< zfdLd`px|)v^mX+M_Vo9Q4|aC+ab@6sY%*{+ebraYH3=BLjAa^n|a5IR2z2cUclM|MhQ<}yBPGq$ z)=agH14Dv}xj9Jw!NILIAQ~nPvj0AO57#J8l zKwPA*3p4I!KC}%+LNg!KA_JKZqd{y?ph3d^8?;xm1tbi@>>vV)*GNY9fTD>_0wlo5 z0_)PSW)u|VryPN{fUoee@PSl;Vgb}JrM%tF69ef~@G}U2dH{$%hmU7)2!kZFJ0i}& z0Pa$OdH^ub!Dx^NkAS;mp#BU5!}uUIlU!!`g4_&?2~B8BfIZ58`qv8yT}ounSuT;0)-vOMIx!Lz94!OkA}c#2#kin$O!>=XMZ1XDF`aWkw(a1 z19h;WMo>)x3Kf_*Y`_pC2EqrR4I2=96px0$Xb6mkz-S1JhQMeDjE2By2#kinXb6mk Qz-S1JhQMeD46YCW0OkHzpa1{> literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32@zQ4Z@Y43Z=%sC>=OwZJwwE@$sF!w~8YqE! c?n{jKe7!Q+QGtQMaRCE^;|B%?WHv|*0L_eEe*gdg -- GitLab From c801cc120ebbd307fb34264fb4026e8bda86ca7f Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 15:19:39 +0100 Subject: [PATCH 06/11] fix docs warnings --- docs/reference/utc_properties.md | 2 +- src/pythermogis/doublet_simulation/deterministic_doublet.py | 3 --- src/pythermogis/thermogis_classes/doublet.py | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/reference/utc_properties.md b/docs/reference/utc_properties.md index b620f33..857f645 100644 --- a/docs/reference/utc_properties.md +++ b/docs/reference/utc_properties.md @@ -1,3 +1,3 @@ # API Reference -::: pythermogis.thermogis_classes.utc_properties \ No newline at end of file +::: pythermogis.thermogis_classes.properties \ No newline at end of file diff --git a/src/pythermogis/doublet_simulation/deterministic_doublet.py b/src/pythermogis/doublet_simulation/deterministic_doublet.py index 5d6c74c..c6ac7cf 100644 --- a/src/pythermogis/doublet_simulation/deterministic_doublet.py +++ b/src/pythermogis/doublet_simulation/deterministic_doublet.py @@ -42,9 +42,6 @@ def calculate_doublet_performance(reservoir_properties: xr.Dataset, utc_properti 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. - chunk_size : int None by default, if set to an integer then chunking of the reservoir properties occurs. The chunk size is used to split up the number of simulations into "chunks" which can be processed in parallel using the dask framework. diff --git a/src/pythermogis/thermogis_classes/doublet.py b/src/pythermogis/thermogis_classes/doublet.py index a693f20..87d0190 100644 --- a/src/pythermogis/thermogis_classes/doublet.py +++ b/src/pythermogis/thermogis_classes/doublet.py @@ -178,8 +178,6 @@ def instantiate_thermogis_doublet(utc_properties) -> JClass: ---------- utc_properties : UTCProperties Instance containing the input parameters required for the doublet simulation. - rng_seed : int - Optional random seed for reproducibility. Returns ------- -- GitLab From 64e974c7dd8f95d6441bda7618c5c6c8dccb7ad3 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Thu, 26 Feb 2026 15:41:36 +0100 Subject: [PATCH 07/11] update docs on properties/paramers --- docs/usage/customized_props.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/usage/customized_props.md b/docs/usage/customized_props.md index e9b111e..64e0eb7 100644 --- a/docs/usage/customized_props.md +++ b/docs/usage/customized_props.md @@ -3,7 +3,7 @@ To adjust properties of the simulation, you can pass a `utc_properties` instance to the calculate_doublet_performance function. A `utc_properties` instance is a JClass implementation of the Java UTCProperties class. -It is generated by using the `utc_properties_builder`, upon which custom properties can be set, +It is generated by using the `thermogis_properties`, upon which custom properties can be set for all calculations in ThermoGIS, and used to build an instance of the `utc_properties`. be aware: The number of parameters is large, and the default values are set to the ThermoGIS base case. @@ -11,8 +11,8 @@ A comprehensive list of parameters is given in [UTC properties](../theory/utcpr There are two ways to set the properties of the simulation, by either: -1. Using the `utc_properties_builder` class to set the properties of the simulation, and then building the `utc_properties` instance. -2. Using the `instantiate_utc_properties_from_xml` function to parse a configuration file, which will return a `utc_properties` instance. +1. Using the `instantiate_thermogis_parameters` class to set the properties of the simulation, and then using the `setupUTCParameters` method. +2. Using the `instantiate_thermogis_properties_from_file` function to parse a configuration file, which will return a `thermogis_properties` method. !!! info "customizing the thermoGIS techno-economic properties" @@ -28,15 +28,15 @@ There are two ways to set the properties of the simulation, by either: Common properties to change include: -- `setUseHeatPump(Boolean)`: if true, include a heat-pump when modelling -- `setUseStimulation(Boolean)`: if true, apply reservoir stimulation when simulating a doublet +- `setUseHeatpump(Boolean)`: if true, include a heat-pump when modelling +- `setUseWellStimulation(Boolean)`: if true, apply reservoir stimulation when simulating a doublet - `setSurfaceTemperature(float)`: The temperature of the surface - `setTempGradient(float)`: The gradient at which temperature increases with depth, in C/km - `setDhReturnTemp(float)`: The goal of the direct heat return temperature - `setStimKhMax(float)`: The maximum transmissivity above which no stimulation will occur (if UseStimulation = True) -Here is an example, where the default utc_properties is used, but the UseHeatPump option is set to True. this is achievied by instantiating a `utc_properties_builder` class, running `.useHeatPump(True)` on that class, and then building the -`utc_properties` themselves, with the `.build()` method of the `utc_properties_builder`. +Here is an example, where the default utc_properties is used, but the UseHeatpump option is set to True. this is achievied by instantiating a `thermogis_properties` class, running `.useHeatpump(True)` on that class, and then building the +`utc_properties` themselves, with the `.setupUTCParameters()` method of the `thermogis_properties`. ```python from pythermogis import calculate_doublet_performance, instantiate_thermogis_parameters @@ -50,7 +50,9 @@ input_data = xr.Dataset({ "permeability": 300, }) -utc_properties = instantiate_thermogis_parameters().setUseHeatPump(True).build() +tg_parameters = instantiate_thermogis_parameters() +tg_parameters.setUseHeatpump(True) +utc_properties = tg_parameters.setupUTCParameters() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) print(results) ``` @@ -65,7 +67,7 @@ The vast majority of the parameters in the xml are not used by this python API; unfortunately they are still needed in the xml file to enable parsing. ```python -from src.pythermogis import calculate_doublet_performance_stochastic, instantiate_utc_properties_from_xml +from src.pythermogis import calculate_doublet_performance_stochastic, instantiate_thermogis_properties_from_file import xarray as xr input_data = xr.Dataset({ @@ -78,7 +80,8 @@ input_data = xr.Dataset({ "ln_permeability_sd": 0.5, }) -utc_properties = instantiate_utc_properties_from_xml("path/to/valid/xml/file") +tg_properties = instantiate_thermogis_properties_from_file("path/to/valid/xml/file") +utc_properties = tg_properties.setupUTCParameters() results = calculate_doublet_performance_stochastic(input_data, utc_properties=utc_properties) print(results) ``` -- GitLab From ff683a4b9b1254a721bd04011ce15113398acad6 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Fri, 27 Feb 2026 15:37:57 +0100 Subject: [PATCH 08/11] bump version number --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 90e1552..3f70d16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pythermogis" -version = "1.2.5" +version = "2.0" description = "This repository is used as a python API for the ThermoGIS Doublet simulations" authors = [ { name = "Hen Brett", email = "hen.brett@tno.nl" }, -- GitLab From 7063050b4fc21b2cf212ab5f1c44c49b0d0842b7 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Fri, 27 Feb 2026 15:45:56 +0100 Subject: [PATCH 09/11] bump version number and add changes to changelog, and fix test --- docs/changelog.md | 4 ++++ pyproject.toml | 2 +- .../HP_STIM/simplified__npv_P10_HP_STIM.nc | Bin 2368 -> 9412 bytes .../HP_STIM/simplified__npv_P50_HP_STIM.nc | Bin 2368 -> 9412 bytes .../HP_STIM/simplified__npv_P90_HP_STIM.nc | Bin 2368 -> 9412 bytes 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 6bd4abb..cac827d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,9 @@ # Change log +## v2.0.0 (27-2-2026) +After an essential rewrite of the java code, parts of the API of pythermoGIS had to be updated. Since these were breaking, non-backward compatible, changes, a version 2.0.0 is released. +The most important and noticible change is that the method of setting up the input parameters has changed. Please check out the customized properties page for + ## v1.2.5 (26-1-2026) A java 17 virtual machine is now automatically installed the first time a pythermogis simulation is run. This uses the [install-jdk](https://pypi.org/project/install-jdk/) python project. diff --git a/pyproject.toml b/pyproject.toml index 3f70d16..0f22931 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pythermogis" -version = "2.0" +version = "2.0.0" description = "This repository is used as a python API for the ThermoGIS Doublet simulations" authors = [ { name = "Hen Brett", email = "hen.brett@tno.nl" }, diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P10_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P10_HP_STIM.nc index ee37e5c3f9e080fea204f0c6ec100e984ce2a314..3b941d14b2433d13cfb92ed3616aa521bb72b465 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGK?B2L=X)mvcQQf}PJhoskjj9wtUcMyRn2a9RZ9VnGFa21tN7Fqm*NnEYpE zU|{6~$uMg{#6hP2sE63Kf)B)FV3-7<;C^Dm=_ejXkWyv_5e6Ox5e9~MztocClr$6P z{QRPn%)G>s)M5q!4hC?@Ffb@EfE)@AM+OFv8$f!&m`5ALXJ%ky-~g$0_HhgjW)Nmz zU;qUfC^%d^eO>*6J^lUSgPk3HTp4&|7#Nrsm>F0h8vGo6UBT)>YC*V?0c0dI12Y33 z0}seZn9E!;b2C#=-2`?40|So>$eqj#+zcXMuefFA7WE8ie#u9MVdSi=gx*u^ob%+l!3yNk%5X)RKdW&;9?gcj4eJu7H*H#UhD7d;mzX; z@+v4I!D%Dj&pDtdzaX`!Br~-b9Os}c42tuz)S}|d{5)GDojh zn6NbJAucAfk8Aub12C+eb1_}Ew z&|b|JkT3|dg9s=tn;3Z%6isYmAOS`ec$X%xpzH{={mZ-JrVdCAC=Ni)Qp#KHJTZ_i z1wVrTsQr)Vark%!hcHM&J0s!@4B!qGsQnM~8jJ>c?+Ca<2I|c~FpLjUGs$I^FUZZX zc+iB#g9ON%3=9lBISdS}49pDt3c+Ka$S!h(Xl9_li$Gxqa+OG`t1pNi#iJoG z8UmvsFp@&R-PzvVYaikG4*gzd@s1a0`fWieP4jV88iGlC|Xu}4?9>t>}Fd71* kAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0)s0A00bIiqyPW_ literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32acH+@aOl1@!J$XU*&(rC(V@go)S=s)M5q!4hC?@Ffb@EfE)@AM+OFv8$f!&m`5ALXJ%ky-~g$0_HhgjW)Nmz zU;qUfC^%d^eO>*6J^lUSgPk3HTp4&|7#Nrsm>F0h8vGo6UBT)>YC*V?0c0dI12Y33 z0}seZn9E!;b2C#=-2`?40|So>$eqj#+zcXMuefFA7WE8ie#u9MVdSi=gx*u^ob%+l!3yNk%5X)RKdW&;9?gcj4eJu7H*H#UhD7d;mzX; z@+v4I!D%Dj&pDtdzaX`!Br~-b9Os}c42tuz)S}|d{5)GDojhOzdBB_~?Cmh<&5vXb6mk zz-S1JhQMeDjE2BKgaD{X0cq`8@k8u~wRS-*9HLu{pcV=>TZ|#L3k)GGMg~Ska9f{= z2}`3M;$kuz`5ZzZ?aYjkppFUy1A_;Mi_~>t#@)VVXM;sDevrM%V769ef| z@G}U2+W&|ihmU7)2!kZFGa}Bw0PawM+W#=G!Dx{8j(|I4pxz7w!}uUIlU!!`g4_&? z2Tf=^NPxV_z`($h!@$7Gz|6qUU;uJKkgJ<(kgK1wYdqKmW=xRoP)cG+VsUB-0|U${ zDVe#cd7zdr0|%(P1ThqQUkes`PzxEPZd`kY>>@{qW(NAZ2o!c8SBa#$`hw_DJQ@O{ zAut*OBPj&jo&9~lEabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32aVUs8<4~uP?$8iz<)G&%?%-t_>=5@Z43t3k cvn*O@pHOGysKCJBxPXDd@dE<`G8?1@00x#{Jpcdz diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P90_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P90_HP_STIM.nc index 7c0997b9767683e38af87cdb0b4d11b46c0a4075..7d918fc368dbae215f0213a54a0396c9067afd95 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGK?B2L=X)mvcQQf}PJhoskjj9wtUcMyRn2a9RZ9VnGFa21tN7Fqm*NnEYpE zU|{6~$uMg{#6hP2sE63Kf)B)FV3-7<;C^Dm=_ejXkWyv_5e6Ox5e9~MztocClr$6P z{QRPn%)G>s)M5q!4hC?@Ffb@EfE)@AM+OFv8$f!&m`5ALXJ%ky-~g$0_HhgjW)Nmz zU;qUfC^%d^eO>*6J^lUSgPk3HTp4&|7#Nrsm>F0h8vGo6UBT)>YC*V?0c0dI12Y33 z0}seZn9E!;b2C#=-2`?40|So>$eqj#+zcXMuefFA7WE8ie#u9MVdSi=gx*u^ob%+l!3yNk%5X)RKdW&;9?gcj4eJu7H*H#UhD7d;mzX; z@+v4I!D%Dj&pDtdzaX`!Br~-b9Os}c42tuz)S}|d{5)GDojhhq#!`Mm~oSNINrQB&egpz`)=E;v#ijm~l7rT|r7oYUYDlWFSp28pH+#8YJw$ zKzlV?K*Au*4kDnqY+~e5P&BcLfdm*?;9Z)$g0dsf_Al>>n>rvhpf~_EODS))^Ta^9 z6#NVVp!Pqa$Km4{9Ks+8?Tm;sFn~K$p!Pq^YcLw*y(8cb8K^e{!7x5Z%_Nsuz92Wl z;z1J{4-z16GB7akGB7jnGZ=te5ajCS8szHd>>3Ytff*B|JCu@Gl31Kt!oUD? zN=jyKY96TN%fJEZEEabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32ad7(7;1Cga#UZBD#C~#lqyw*1i-V5JB~SuA cAU@e(f7j$GjtUG6jtdwV96vBHAhSVg07&>?vH$=8 -- GitLab From 603e7a835452f065c2bec74f7f8dee8a81705edd Mon Sep 17 00:00:00 2001 From: knappersfy Date: Fri, 27 Feb 2026 17:41:00 +0100 Subject: [PATCH 10/11] try new atol --- tests/simulation/test_thermogis_scenarios.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/simulation/test_thermogis_scenarios.py b/tests/simulation/test_thermogis_scenarios.py index ddce3f9..0e713ed 100644 --- a/tests/simulation/test_thermogis_scenarios.py +++ b/tests/simulation/test_thermogis_scenarios.py @@ -128,7 +128,7 @@ class PyThermoGIS(TestCase): xr.testing.assert_allclose(output_grids[f"transmissivity_with_ntg"], read_grid(benchmark_path / f"simplified__kh_P{p_value}{scenario}.nc"), atol=5) xr.testing.assert_allclose(output_grids.power, read_grid(benchmark_path / f"simplified__power_P{p_value}{scenario}.nc"), atol=1.0) xr.testing.assert_allclose(output_grids.utc, read_grid(benchmark_path / f"simplified__utc_P{p_value}{scenario}.nc"), atol=0.1) - xr.testing.assert_allclose(output_grids.npv, read_grid(benchmark_path / f"simplified__npv_P{p_value}{scenario}.nc"), atol=0.5) + xr.testing.assert_allclose(output_grids.npv, read_grid(benchmark_path / f"simplified__npv_P{p_value}{scenario}.nc"), atol=0.75) xr.testing.assert_allclose(output_grids.hprod, read_grid(benchmark_path / f"simplified__hprod_P{p_value}{scenario}.nc"), atol=40000) xr.testing.assert_allclose(output_grids.cop, read_grid(benchmark_path / f"simplified__cop_P{p_value}{scenario}.nc"), atol=1.0) xr.testing.assert_allclose(output_grids.pres, read_grid(benchmark_path / f"simplified__pres_P{p_value}{scenario}.nc"), atol=2.0) -- GitLab From 937df4d14281f8e93946d589a4ce14d258a01bc1 Mon Sep 17 00:00:00 2001 From: knappersfy Date: Fri, 27 Feb 2026 17:47:19 +0100 Subject: [PATCH 11/11] update flowrate files --- .../doublet/basecase/simplified__flowr_P10.nc | Bin 2368 -> 9412 bytes .../doublet/basecase/simplified__flowr_P50.nc | Bin 2368 -> 9412 bytes .../doublet/basecase/simplified__flowr_P90.nc | Bin 2368 -> 9412 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P10.nc b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P10.nc index 4bfb00508d17355ae81ea43d65add7e68e1d9491..4c7f298cd4dbc05085e94f3298a79cdb62344b63 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGNBMLNPEfEWG|d8SH%C>5PnE_b@RsGD3}IfYTx%7Yi!bGe82wfx(2E!Q?+P z0|P4`NQPMpA`UY4M?J)@b$lQm1H&W;1@{vhPCxNDf|N2dh%oRlh%hk3`=yp7r=*!U z=jRutWacH7q!u#>a4>*FhJitW0pw6{I5IGR+yK%G#yr{}J~IOw0|!X0vyWqNFoQ4y z0|O|?K*8bS>Feqj?CI|pAMEVtk3v6QVYVB3?L(!8JHRP z7L#!Y7#Mh5K<;E_;ARj3d&Mm?Cnqd1r!T{hR}e@(WUnN-|T6!Ep}C!k{=WOD!tS%+Iqm(#Zp-LR%9(OFbiQ6Wk#*LlcC4FbhH-xC)^koPf{} zqZt?&0t#zD`WEa$6Nf7pWsHWvXb6mkz-S1JhQMeD&?N*wO$tbB*MT2mA*{6vYT*#w zVg$8NsM%s{+#i_)X)!V|GJ^XnOiWlB^$-`6*~sS*0%>Pvj0AO57#J8lKwPA*3p4I! zKC}%+LNg!KA_JKZqd{y?ph3d^7qnNi1tbi@>>vV)C-NO}0Ywv=3`l^H1=gkEOv}kH zk1t9rNj(B>1#iujG6AUs#RRBvN_pFzCkE27;Aap3^#Tz64j<3p5C%zTmqeU_0o<(u z^#WiXgwY^R9szgDKz$krhVemaCb`V=1-Tg(8=BDAkN|m>fq{W1hk=2Wfti7y!2slf zAXhinAXh(U*LbiC%$OjZqLjpv#NyNv1_qc@QZjQ>^FZxi1`bfC31TSr9v3Y1pcXPn z-MID)*+q^J%?$K+5h(0Ht`bRg^##$Rcr*k?Ltr!nMn(v@JNx^9OF&Qojx<6B8>oW~ zHG*mpP>8_9VFQLBF%UigZPEabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32asK)DyYtU~kr7U~pW(z~K0SfdQEfQUd@39BIw~ diff --git a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P50.nc b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P50.nc index 0446970717653495d65d8c5570f6962b36451d9b..8882503599633c0c2816ab705671642a4e5d6557 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGNBMLNPEfEWG|d8SH%C>5PnE_b@RsGD3}IfYTx%7Yi!bGe82wfx(2E!Q?+P z0|P4`NQPMpA`UY4M?J)@b$lQm1H&W;1@{vhPCxNDf|N2dh%oRlh%hk3`=yp7r=*!U z=jRutWacH7q!u#>a4>*FhJitW0pw6{I5IGR+yK%G#yr{}J~IOw0|!X0vyWqNFoQ4y z0|O|?K*8bS>Feqj?CI|pAMEVtk3v6QVYVB3?L(!8JHRP z7L#!Y7#Mh5K<;E_;ARj3d&Mm?Cnqd1r!T{hR}e@(WUnN-|T6!Ep}C!k{=WOD!tS%+Iqm(#Zp-LR%9(OFbihXANa0cq_z@I&l|wRS-*9HLu{ zpcV=>Ta1nSBat#@)<^ zw!uhf=7U;fAoF1~hz$xfNZ9{^_G-3(gh7}cL_qOGz9TN6XkwEA2{5w2x-^_=Ir-)B zMTsS;N1(0Xt+`SrAeEq)05wi2Z@crvKspxu3<98D0HWXF;~5;nAPMb~h%+#NyH%iG z0L+6h8sy0%;BFbHPXoa)K1j_Zms!3bH^X8>6B-*5AkQ)|F!1CsFt9Q(Gw?GQfLsvd z>gF2c>gVhl4|ahW6Qom=l30>hoLa)b0CP%8W^QU8sQt^p0qQhC48`8#f`uN`LI$ZD z*PbD}$PuEMf&MN6g&oLMBB`#vAbJ#!hQMeDjE2C-2myCze;;rO2r9slM#x|Tb+DmE zP%Q!q5tuk^zz`$`!Uv!Y8xVUGkA}c#2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk Lz-R~zt`GnKo(o!S literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32asK&N&H3lA0Oy~-8J&OrjdlL{`@HkdU%x>K e)OkzB6zA)kEF2XW7#tTcFgSi-U_fSr)BpgWFlUzl diff --git a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P90.nc b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P90.nc index a9962bf3b47ef6bbd5121f4afb07ce9c94773efa..013578c883b8ee4d007ec3c7292be2b224ddc3c1 100644 GIT binary patch literal 9412 zcmeD5aB<`1lHy|G;9!7(|4?v51tMYqp%@lMnpFFHxCAlrY++IYi!rl+DFz0p4h)Km ziGdNMgiQoQGQyNIFjl??2{14)h{`a4M41_Jnjs(nQhJRUL^3c0LnsEAiA+#FW5pyW z6QceCFGNBMLNPEfEWG|d8SH%C>5PnE_b@RsGD3}IfYTx%7Yi!bGe82wfx(2E!Q?+P z0|P4`NQPMpA`UY4M?J)@b$lQm1H&W;1@{vhPCxNDf|N2dh%oRlh%hk3`=yp7r=*!U z=jRutWacH7q!u#>a4>*FhJitW0pw6{I5IGR+yK%G#yr{}J~IOw0|!X0vyWqNFoQ4y z0|O|?K*8bS>Feqj?CI|pAMEVtk3v6QVYVB3?L(!8JHRP z7L#!Y7#Mh5K<;E_;ARj3d&Mm?Cnqd1r!T{hR}e@(WUnN-|T6!Ep}C!k{=WOD!tS%+Iqm(#Zp-LR%9(OFbi%b4O8rIqc zwQz`TF@jns)NC;}?vG4@v=|u}8NvM(CMGP6dWeh3Y~*tYfwVI-MuIvj3=9k&ATCnZ zg&B7&&|3)-vM0ulycb`Sx@6Zwv~fTD>_1|-190_)On zrsd?9#}_4*q#l8`g16>MnSfM+Vgl4SrM&IV69eg3@G}U2dI5-jhmU7)2!kZFOCrv| z0Pa?SdI2yG!f22ukAS;npgs)*!}uUIlU!!`g4_&?4NYilNPs-cz`($h!@$7Gz|6qU zU;uJKkgJ<(kgK1wYdqKmW=xPyQA%P-VsUB-0|U${DVe#cd7$<$0|%(n1ThqQj|&!h zPzxEPZd`kY>>@{qW(NAZ2o!c8SBa#$`hw_DJQ@O{Aut*OBO?Udo&9~lB_OB(M;al6 z4b;Jg8bP%PC`4f5umMAm7ziJLHf%ubQ9K#~qaiRF0;3@?8UmvsFd71*Aut*OqaiRF Q0;3@?8UmvsFt|bh04SYWumAu6 literal 2368 zcmZ>EabskF04@dw1||ju2F3~qpBcoiM6e+&1_o{h1_l-oPDw0Dgz14w@-Q$kfb?i%(9?D=A9MiO)?f%1p^jgakhW8z`(CM0-A(R_+6(HQuzuoZ{5@)WqTv zNWx%XfT(d~dVK)oCWDHC^J11#cnU* zzk=&q)-W(IC=@3r=A_1_B_@~T7sV%*U~@9q9{czI?QR()&0}C-P(;^*&n_f=*zygZ zb5O8CN@`kWUM4(!N~45fK~ZLIDoO}~-2?SAh~h6!&CQI@P0RxMpdu5TO2KLzBZA+0 zzHXIgU|YL0@Tg^8h(j+wE!xv{0Wo}sC!j*+FMo}sCcg`tr}Y^+W|kf*P!Z?uwo zQEF;ld1i8kl8!;FPN<(}NVHN)YI;#>s*;X@o`IpciK(%XrID$jrKO3nv5sSCh=+fW zXGmnUl50S)yONHQrJ<3LQfw?1851K5OOOo6f3D6Up8kH(O8(HYC>XgcQi|0Ha13(v zbq#S1idI5SVvuyDq+@ENXJ~3>Xl7sv24*N4(6fM&j;Wrpg}Irr1r%7KC`V3OAU|4K zT3Q;IqpE>q1!#6r(lInOH83zhF$JOmmRXc^Ow5eIN+2Pan_5zos-$BWtK%5q862(T z3dwj%INM+Tn3e%?~L`%qvdIF9KDop!S4?k%h6jo`JcciGrblfq{a7f|;>}sim==iHV^R zC{tKkDi|o}T3TA_L3mJ70otx$VPN32asK(|wDZq@51oJhs&u~Xu-N%)+9~Ise`7%j e)VX8ZbLSPW#T*qF7#tTcFgSi-U_fSr)BpgwlV{cd -- GitLab