diff --git a/docs/changelog.md b/docs/changelog.md index 6bd4abb8f20b749ebdffb7ee00f50657b6ae66ed..cac827de2d797935239a5aff91ff25034f84de3f 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/docs/reference/utc_properties.md b/docs/reference/utc_properties.md index b620f33a8b35a26c798d2ce83dab64add76dad68..857f645b18350360296d14843cd96ccaeb2d8595 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/docs/usage/customized_props.md b/docs/usage/customized_props.md index 0496e23b56d002c781b1b840f08b63822ed7f74b..64e0eb72d62e00182041f7da6a8731063d6c2916 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,18 +28,18 @@ 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_utc_properties_builder +from pythermogis import calculate_doublet_performance, instantiate_thermogis_parameters import xarray as xr input_data = xr.Dataset({ @@ -50,7 +50,9 @@ input_data = xr.Dataset({ "permeability": 300, }) -utc_properties = instantiate_utc_properties_builder().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) ``` diff --git a/pixi.lock b/pixi.lock index d771c6c405d80e84f00fc3cfb4a4cf19128046f1..2d40a2345169926084ec1183225afb59921110ed 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/pyproject.toml b/pyproject.toml index 90e15525c5614fcb18552074fbe0b39794afd44d..0f229317dabf9230f416fe21d26cbce051433481 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.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/src/pythermogis/__init__.py b/src/pythermogis/__init__.py index 54e857759cf30d0cf3470f1e082773dff8ce3d38..f56a5c768b3fabf24377538d3137d37efcffb725 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 98282eb1cf3eb6a3dc9cad77c2e03c166a9a0b84..c6ac7cfab911ad8f945b86d1d3f3021ae16247de 100644 --- a/src/pythermogis/doublet_simulation/deterministic_doublet.py +++ b/src/pythermogis/doublet_simulation/deterministic_doublet.py @@ -9,12 +9,12 @@ 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 ( - instantiate_utc_properties_builder, +from pythermogis.thermogis_classes.properties import ( + instantiate_thermogis_parameters, ) -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. @@ -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. @@ -90,7 +87,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: @@ -109,7 +106,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 701b1ecd73eb348758a53b868a31c18a1c3036c3..0ca77e39dfc2ca4a47f2465be2089d3afb377708 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.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( @@ -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/main.py b/src/pythermogis/main.py index 7cbcd55b6b5e55d7eb3db19eb32eae0372dad36e..6b1cd181c9fbd9bd0ea8257867b67d4b38104be0 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/doublet.py b/src/pythermogis/thermogis_classes/doublet.py index f9ca1b708f41d5532eb1d40ed2a0711d8440f795..87d0190413724a1faeb2bee4d9f7d42afc02be23 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. @@ -180,8 +178,6 @@ def instantiate_thermogis_doublet(utc_properties, rng_seed: int = None) -> JClas ---------- utc_properties : UTCProperties Instance containing the input parameters required for the doublet simulation. - rng_seed : int - Optional random seed for reproducibility. Returns ------- @@ -192,15 +188,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/src/pythermogis/thermogis_classes/potential_properties.py b/src/pythermogis/thermogis_classes/potential_properties.py deleted file mode 100644 index 5f514ddb98b85c2a1e8e9f7a06edacce99bbdea0..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..2c1cf5aed948aeef32d01f6d8a5603cdbb16c4da --- /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 50308d4fa67cdb97151f44bcbb67a24e6aed3930..0000000000000000000000000000000000000000 --- a/src/pythermogis/thermogis_classes/utc_properties.py +++ /dev/null @@ -1,65 +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_utc_properties_builder() -> JClass: - """ - Create and return a ``UTCPropertiesBuilder`` Java object. - - The builder wraps the ThermoGIS **UTCPropertiesBuilder** Java class, which can - - * 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. - """ - start_jvm() - return JClass("thermogis.properties.builders.UTCPropertiesBuilder")() - -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/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar b/src/pythermogis/thermogis_jar/thermogis-1.7.0-shaded.jar index e9b30a8965c4e0eee1940138bed253869fc84cea..b5180f2eb42a2b1fdb186fb4419b9c64439dc8e8 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 896739baeb77c4c2b46f5389810c50ea5fe1cea3..8d31cf489102cf410b6e8f268eb258ddb234440e 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,9 @@ def test_example_3(): "permeability": 300, }) - utc_properties = instantiate_utc_properties_builder().setUseHeatPump(True).build() + 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 9dac69befb6774c144829fc719966d3b9b9c9b24..6278fb10553bd3271d4d15693b48991302084105 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_utc_properties_builder() - .setOpexBase(0) - .setDhReturnTemp(40) - .setViscosityMode(ViscosityMode.KESTIN) - .setUseStimulation(False) - .build()) + 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_utc_properties_builder() - .setCapexConst(0.5) - .setCapexVariable(1100) - .setHeatExchangerEfficiency(0.4) - .setHeatExchangerParasitic(0.1) - .setDhReturnTemp(60) - .setViscosityMode(ViscosityMode.KESTIN) - .build()) + 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_utc_properties_builder() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(70) - .setUseHeatPump(True) - .setDhReturnTemp(35) - .setViscosityMode(ViscosityMode.KESTIN) - .build()) + 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,20 +198,21 @@ 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) # 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): @@ -231,20 +224,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_utc_properties_builder() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(80) - #.setHpApplicationMode(True) - .setUseHeatPump(True) - .setDhReturnTemp(50) - .setViscosityMode(ViscosityMode.KESTIN) - .build()) + 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 +252,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 +276,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_utc_properties_builder() - .setCapexConst(0) - .setCapexVariable(2300) - .setHeatExchangerEfficiency(0.6) - .setUseORC(True) - .setViscosityMode(ViscosityMode.KESTIN) - .setDhReturnTemp(60) - .setHeatExchangerBasetemp(20).build()) + 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 +305,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) @@ -331,16 +320,17 @@ 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): + 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 3a227ebef9371376ef4d2edef84bf1509feb2dd2..9357ed64ad449d30652f90d8518ae70bebde2e74 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 be5ac85459a3cbbd9348ffeebc7e9104c8201979..f759f45cbdc0412aa32743c516967ec174f8e69e 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/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 Binary files a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P10_HP.nc and b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P10_HP.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P50_HP.nc b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P50_HP.nc index e2a6b541dad0a92ed0b01787143edbf6e46b60de..60be53ae7775acefa566f53e4ff55fd2278bb388 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P50_HP.nc and b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P50_HP.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P90_HP.nc b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P90_HP.nc index 911c766791426f49a123d90723572f234bbcdd06..629fb5e839aaaa11d38791fba0a87f6643e8f6cb 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P90_HP.nc and b/tests/resources/test_benchmark_output/doublet/HP/simplified__hprod_P90_HP.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/HP/simplified__npv_P10_HP.nc and b/tests/resources/test_benchmark_output/doublet/HP/simplified__npv_P10_HP.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P10_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P10_HP_STIM.nc index 91201b282981cdd80e54d0d4c97912956090cd0a..443b8dddbfb6d7df771cb6cc9c357e8b1de7011a 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P10_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P10_HP_STIM.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P50_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P50_HP_STIM.nc index e2a6b541dad0a92ed0b01787143edbf6e46b60de..d51a2ed868bea88ceb2d0c660cb5f4bd6592d9f7 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P50_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P50_HP_STIM.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P90_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P90_HP_STIM.nc index 911c766791426f49a123d90723572f234bbcdd06..106af90501c329335755aea5bce799e4fa3601d2 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P90_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__hprod_P90_HP_STIM.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P10_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P10_HP_STIM.nc differ diff --git a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P50_HP_STIM.nc b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P50_HP_STIM.nc index 7816c36420f0dc61c11b0100e2548169ad522c4c..830903ce23a36e1dedda8980b21271a0da4fdc8d 100644 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P50_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P50_HP_STIM.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P90_HP_STIM.nc and b/tests/resources/test_benchmark_output/doublet/HP_STIM/simplified__npv_P90_HP_STIM.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P10.nc and b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P10.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P50.nc and b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P50.nc differ 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 Binary files a/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P90.nc and b/tests/resources/test_benchmark_output/doublet/basecase/simplified__flowr_P90.nc differ diff --git a/tests/simulation/test_pythermogis_doublet_benchmark.py b/tests/simulation/test_pythermogis_doublet_benchmark.py index cc274af2e9f263c9031411b1de5b07b0e3427b15..b004982cbb0efe22b0f47d35f346d08a7e0dfa15 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_utc_properties_builder() - .setDhReturnTemp(40) - .setViscosityMode(viscosity_mode) - .build() - ) + 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_utc_properties_builder().setOpexBase(0).build() - ) + 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_utc_properties_builder() - .setCapexConst(0.5) - .setCapexVariable(1100) - .setHeatExchangerEfficiency(0.4) - .setDhReturnTemp(60) - .setHeatExchangerParasitic(0.1) - .build() - ) + 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_utc_properties_builder() - .setCapexConst(0) - .setCapexVariable(2300) - .setHeatExchangerEfficiency(0.6) - .setUseORC(True) - .setHeatExchangerBasetemp(20) - .setDhReturnTemp(60) - .build() - ) + 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_utc_properties_builder() - .setOpexPerPower(100) - .setOpexBase(0) - .setHpDirectHeatInputTemp(70) - .setUseHeatPump(True) - .setDhReturnTemp(35) - .build() - ) + 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,32 @@ class ThermoGISDoubletBenchmark(TestCase): # Assert - self.assertTrue(np.isclose(5.856159806251526, results.power + power_hpelec, 0.1)) + 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)) - - def setup_template_utc_properties_builder(self): - viscosity_mode = get_viscosity_mode("kestin") - - 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) - .setDhReturnTemp(40) - .setViscosityMode(viscosity_mode) - ) \ No newline at end of file + 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): + 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 diff --git a/tests/simulation/test_thermogis_scenarios.py b/tests/simulation/test_thermogis_scenarios.py index ae63b42e4d85677612f7fd37cca36daf1d246e98..0e713ed757e2f84f691d2f3b9c814037f2a9f5a7 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,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_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseHeatPump(True).build() + 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) @@ -59,8 +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_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseStimulation(True).build() + 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 @@ -75,8 +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_builder = instantiate_utc_properties_builder() - utc_properties = utc_properties_builder.setUseStimulation(True).setUseHeatPump(True).build() + 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) @@ -126,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)