Loading pythermogis/cli.py +2 −2 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ from pathlib import Path import typer from pytg3.aquifer import Aquifer from pytg3.doublet import ThermoGISDoublet from pythermogis.pytg3.aquifer import Aquifer from pythermogis.pytg3.doublet import ThermoGISDoublet from pythermogis.potential import calculate_potential from pythermogis.properties import instantiate_thermogis_parameters Loading pythermogis/pytg3/aquifer.py +11 −0 Original line number Diff line number Diff line Loading @@ -48,12 +48,23 @@ class BaseAquifer(BaseModel): ) -> None: raise NotImplementedError def to_dataset(self) -> xr.Dataset: return xr.Dataset( { field_name: value for field_name, value in self if isinstance(value, xr.DataArray) } ) class Aquifer(BaseAquifer): thickness: FloatOrArray permeability: FloatOrArray | None = None transmissivity: FloatOrArray | None = None @model_validator(mode="after") def check_permeability_or_transmissivity(self) -> Aquifer: has_perm = self.permeability is not None Loading tests/test_doc_examples.py +120 −107 Original line number Diff line number Diff line Loading @@ -6,29 +6,23 @@ import xarray as xr from matplotlib import pyplot as plt from pygridsio import plot_grid, read_grid, resample_grid from pythermogis.doublet import ( calculate_doublet_performance, calculate_doublet_performance_stochastic, ) from pythermogis.pytg3.aquifer import Aquifer, StochasticAquifer from pythermogis.pytg3.settings import Settings from pythermogis.pytg3.doublet import ThermoGISDoublet from pythermogis.plot import plot_exceedance from pythermogis.postprocess import calculate_pos from pythermogis.properties import instantiate_thermogis_parameters def test_example_1(): import xarray as xr input_data = xr.Dataset( { "thickness": 300, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "permeability": 300, } aquifer = Aquifer( thickness=300, ntg=0.5, porosity=0.2, depth=2000, permeability=300 ) results = calculate_doublet_performance(input_data) results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() print(results) Loading @@ -44,42 +38,38 @@ def test_example_2(): coords={"x": [0, 1], "y": [10, 20]}, ) results = calculate_doublet_performance(input_data) aquifer = Aquifer( thickness=input_data["thickness"], ntg=input_data["ntg"], porosity=input_data["porosity"], depth=input_data["depth"], permeability=input_data["permeability"], ) results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() print(results) def test_example_3(): input_data = xr.Dataset( { "thickness": 300, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "permeability": 300, } ) tg_properties = instantiate_thermogis_parameters() tg_properties.setUseHeatpump(True) utc_properties = tg_properties.setupUTCParameters() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) aquifer = Aquifer( thickness=300, ntg=0.5, porosity=0.2, depth=2000, permeability=300 ) settings = Settings() settings.set_use_heatpump(True) results = ThermoGISDoublet(aquifer=aquifer, settings=settings).simulate().to_dataset() print(results) def test_example_4(): input_data = xr.Dataset( { "thickness_mean": 300, "thickness_sd": 50, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "ln_permeability_mean": 4, "ln_permeability_sd": 0.5, } aquifer = StochasticAquifer( thickness_mean=300, thickness_sd=50, ntg=0.5, porosity=0.2, depth=2000, ln_permeability_mean=4, ln_permeability_sd=0.5 ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[50]).to_dataset() results = calculate_doublet_performance_stochastic(input_data) print(results) Loading @@ -89,25 +79,24 @@ def test_example_5(): ) output_data_path.mkdir(parents=True, exist_ok=True) input_data = xr.Dataset( { "thickness_mean": 300, "thickness_sd": 50, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "ln_permeability_mean": 5, "ln_permeability_sd": 0.5, } ) results = calculate_doublet_performance_stochastic( input_data, p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99] aquifer = StochasticAquifer( thickness_mean=300, thickness_sd=50, ntg=0.5, porosity=0.2, depth=2000, ln_permeability_mean=5, ln_permeability_sd=0.5, ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99]).to_dataset() fig, axe = plt.subplots(figsize=(10, 5)) kh = results.transmissivity_with_ntg * 1.0 kh.plot(y="p_value", ax=axe) axe.set_title("Aquifer Net transmissivity\n kH") temp = input_data.temperature temp = aquifer.temperature inj_temp = results.inj_temp.sel(p_value=50, method="nearest") prd_temp = results.prd_temp.sel(p_value=50, method="nearest") axe.axhline( Loading @@ -129,12 +118,12 @@ def test_example_6(): # the location of the input data: # the data can be found in the resources/example_data directory of the repo input_data_path = ( Path(__file__).parent.parent / "resources" / "test_input" / "example_data" Path(__file__).parent / "resources" / "test_input" / "example_data" ) # create a directory to write the output files to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example6" Path(__file__).parent / "resources" / "test_output" / "example6" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading @@ -145,37 +134,47 @@ def test_example_6(): # grids can be in .nc, .asc, .zmap or .tif format: see pygridsio package new_cellsize = 5000 # in m, this sets the resolution of the model; # to speed up calcualtions you can increase the cellsize reservoir_properties = resample_grid( thickness_mean = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__thick.zmap"), new_cellsize=new_cellsize ).to_dataset(name="thickness_mean") reservoir_properties["thickness_sd"] = resample_grid( ) thickness_sd = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__thick_sd.zmap"), new_cellsize=new_cellsize, ) reservoir_properties["ntg"] = resample_grid( ntg = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap"), new_cellsize=new_cellsize ) reservoir_properties["porosity"] = ( porosity = ( resample_grid( read_grid(input_data_path / "ROSL_ROSLU__poro.zmap"), new_cellsize=new_cellsize, ) / 100 ) reservoir_properties["depth"] = resample_grid( depth = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__top.zmap"), new_cellsize=new_cellsize ) reservoir_properties["ln_permeability_mean"] = np.log( ln_permeability_mean = np.log( resample_grid( read_grid(input_data_path / "ROSL_ROSLU__perm.zmap"), new_cellsize=new_cellsize, ) ) reservoir_properties["ln_permeability_sd"] = resample_grid( ln_permeability_sd = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap"), new_cellsize=new_cellsize, ) aquifer = StochasticAquifer( thickness_mean=thickness_mean, thickness_sd=thickness_sd, ntg=ntg, porosity=porosity, depth=depth, ln_permeability_mean=ln_permeability_mean, ln_permeability_sd=ln_permeability_sd, ) # output inputs variables_to_plot = ["depth", "thickness_mean", "thickness_sd"] fig, axes = plt.subplots( Loading @@ -187,7 +186,7 @@ def test_example_6(): ) for i, variable in enumerate(variables_to_plot): plot_grid( reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True ) # See documentation on plot_grid in pygridsio, # you can also provide your own shapefile plt.tight_layout() # ensure there is enough spacing Loading @@ -203,7 +202,7 @@ def test_example_6(): ) for i, variable in enumerate(variables_to_plot): plot_grid( reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True ) # See documentation on plot_grid in pygridsio, # you can also provide your own shapefile plt.tight_layout() # ensure there is enough spacing Loading @@ -215,9 +214,8 @@ def test_example_6(): if (output_data_path / "output_results.nc").exists and not run_simulation: results = xr.load_dataset(output_data_path / "output_results.nc") else: results = calculate_doublet_performance_stochastic( reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90] ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset() results.to_netcdf( output_data_path / "output_results.nc" ) # write doublet simulation results to file Loading Loading @@ -284,22 +282,28 @@ def test_example_7(): output_data_path.mkdir(parents=True, exist_ok=True) # read in reservoir property maps reservoir_properties = read_grid( thickness_mean = read_grid( input_data_path / "ROSL_ROSLU__thick.zmap" ).to_dataset(name="thickness_mean") reservoir_properties["thickness_sd"] = read_grid( ) thickness_sd = read_grid( input_data_path / "ROSL_ROSLU__thick_sd.zmap" ) reservoir_properties["ntg"] = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap") reservoir_properties["porosity"] = 0.01 * read_grid( ntg = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap") porosity = 0.01 * read_grid( input_data_path / "ROSL_ROSLU__poro.zmap" ) reservoir_properties["depth"] = read_grid(input_data_path / "ROSL_ROSLU__top.zmap") reservoir_properties["ln_permeability_mean"] = np.log( read_grid(input_data_path / "ROSL_ROSLU__perm.zmap") ) reservoir_properties["ln_permeability_sd"] = read_grid( input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap" depth = read_grid(input_data_path / "ROSL_ROSLU__top.zmap") ln_permeability_mean = np.log(read_grid(input_data_path / "ROSL_ROSLU__perm.zmap")) ln_permeability_sd = read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap") aquifer = StochasticAquifer( thickness_mean=thickness_mean, thickness_sd=thickness_sd, ntg=ntg, porosity=porosity, depth=depth, ln_permeability_mean=ln_permeability_mean, ln_permeability_sd=ln_permeability_sd, ) # Select locations of interest from the reservoir Loading @@ -313,16 +317,18 @@ def test_example_7(): ] # Collect selected locations, create a new Dataset with the coordinate 'location' aquifer_ds = aquifer.to_dataset() locations = [] for i, (x, y) in enumerate(portfolio_coords): point = reservoir_properties.sel(x=x, y=y, method="nearest") point = point.expand_dims(location=[i]) # Add new dim for stacking point = aquifer_ds.sel(x=x, y=y, method="nearest") point = point.expand_dims(location=[i]) locations.append(point) portfolio_reservoir_properties = xr.concat(locations, dim="location") results_portfolio = calculate_doublet_performance_stochastic( portfolio_reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90] ) portfolio_aquifer = StochasticAquifer(**portfolio_reservoir_properties.data_vars) results_portfolio = ThermoGISDoublet(aquifer=portfolio_aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset() # post process: clip the npv and calculate the probability of success AEC = -3.5 Loading Loading @@ -357,7 +363,7 @@ def test_example_7(): kh = results_loc.transmissivity_with_ntg kh.plot(y="p_value", ax=ax, color=colors[i_loc]) ax.set_title("Aquifer: ROSL_ROSLU\n kH") temp = results_loc.temperature.sel(p_value=50) temp = results_loc.temperature inj_temp = results_loc.inj_temp.sel(p_value=50) prd_temp = results_loc.prd_temp.sel(p_value=50) ax.axhline( Loading Loading @@ -409,7 +415,7 @@ def test_example_7(): def test_example_8(): # output directory to write output to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example8" Path(__file__).parent / "resources" / "test_output" / "example8" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading @@ -432,9 +438,14 @@ def test_example_8(): ) # For every sample, run a doublet simulation store the output values simulations = calculate_doublet_performance( reservoir_properties, print_execution_duration=True aquifer = Aquifer( thickness=reservoir_properties["thickness"], porosity=reservoir_properties["porosity"], ntg=reservoir_properties["ntg"], depth=reservoir_properties["depth"], permeability=reservoir_properties["permeability"], ) simulations = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() # post process the samples to calculate the percentiles of each variable percentiles = np.arange(1, 99) Loading Loading @@ -484,7 +495,7 @@ def test_example_8(): def test_example_9(): # output directory to write output to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example9" Path(__file__).parent / "resources" / "test_output" / "example9" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading Loading @@ -522,25 +533,27 @@ def test_example_9(): # clip to minimum transmissivity of 1Dm permeability = np.clip(permeability, 1000 / thickness, 1e10) reservoir_properties = xr.Dataset( { "thickness": thickness, "porosity": (["depth", "samples"], porosity / 100), "ntg": ntg, "permeability": (["depth", "samples"], permeability), }, coords={ "samples": np.arange(n_samples), "depth": depths, }, porosity_da = xr.DataArray( porosity / 100, dims=["depth", "samples"], coords={"depth": depths, "samples": np.arange(n_samples)} ) permeability_da = xr.DataArray( permeability, dims=["depth", "samples"], coords={"depth": depths, "samples": np.arange(n_samples)} ) depth_da = xr.DataArray(depths, dims=["depth"], coords={"depth": depths}) # For every sample, run a doublet simulation simulations = calculate_doublet_performance( reservoir_properties, chunk_size=100, aquifer = Aquifer( thickness=thickness, porosity=porosity_da, ntg=ntg, depth=depth_da, permeability=permeability_da, ) # For every sample, run a doublet simulation simulations = ThermoGISDoublet(aquifer=aquifer).simulate(chunk_size=100).to_dataset() simulations_stoch = simulations.quantile([0.1, 0.5, 0.9], dim="samples") # make a plot showing there is a sweet spot between Doublet power, Cost of energy Loading Loading
pythermogis/cli.py +2 −2 Original line number Diff line number Diff line Loading @@ -3,8 +3,8 @@ from pathlib import Path import typer from pytg3.aquifer import Aquifer from pytg3.doublet import ThermoGISDoublet from pythermogis.pytg3.aquifer import Aquifer from pythermogis.pytg3.doublet import ThermoGISDoublet from pythermogis.potential import calculate_potential from pythermogis.properties import instantiate_thermogis_parameters Loading
pythermogis/pytg3/aquifer.py +11 −0 Original line number Diff line number Diff line Loading @@ -48,12 +48,23 @@ class BaseAquifer(BaseModel): ) -> None: raise NotImplementedError def to_dataset(self) -> xr.Dataset: return xr.Dataset( { field_name: value for field_name, value in self if isinstance(value, xr.DataArray) } ) class Aquifer(BaseAquifer): thickness: FloatOrArray permeability: FloatOrArray | None = None transmissivity: FloatOrArray | None = None @model_validator(mode="after") def check_permeability_or_transmissivity(self) -> Aquifer: has_perm = self.permeability is not None Loading
tests/test_doc_examples.py +120 −107 Original line number Diff line number Diff line Loading @@ -6,29 +6,23 @@ import xarray as xr from matplotlib import pyplot as plt from pygridsio import plot_grid, read_grid, resample_grid from pythermogis.doublet import ( calculate_doublet_performance, calculate_doublet_performance_stochastic, ) from pythermogis.pytg3.aquifer import Aquifer, StochasticAquifer from pythermogis.pytg3.settings import Settings from pythermogis.pytg3.doublet import ThermoGISDoublet from pythermogis.plot import plot_exceedance from pythermogis.postprocess import calculate_pos from pythermogis.properties import instantiate_thermogis_parameters def test_example_1(): import xarray as xr input_data = xr.Dataset( { "thickness": 300, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "permeability": 300, } aquifer = Aquifer( thickness=300, ntg=0.5, porosity=0.2, depth=2000, permeability=300 ) results = calculate_doublet_performance(input_data) results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() print(results) Loading @@ -44,42 +38,38 @@ def test_example_2(): coords={"x": [0, 1], "y": [10, 20]}, ) results = calculate_doublet_performance(input_data) aquifer = Aquifer( thickness=input_data["thickness"], ntg=input_data["ntg"], porosity=input_data["porosity"], depth=input_data["depth"], permeability=input_data["permeability"], ) results = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() print(results) def test_example_3(): input_data = xr.Dataset( { "thickness": 300, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "permeability": 300, } ) tg_properties = instantiate_thermogis_parameters() tg_properties.setUseHeatpump(True) utc_properties = tg_properties.setupUTCParameters() results = calculate_doublet_performance(input_data, utc_properties=utc_properties) aquifer = Aquifer( thickness=300, ntg=0.5, porosity=0.2, depth=2000, permeability=300 ) settings = Settings() settings.set_use_heatpump(True) results = ThermoGISDoublet(aquifer=aquifer, settings=settings).simulate().to_dataset() print(results) def test_example_4(): input_data = xr.Dataset( { "thickness_mean": 300, "thickness_sd": 50, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "ln_permeability_mean": 4, "ln_permeability_sd": 0.5, } aquifer = StochasticAquifer( thickness_mean=300, thickness_sd=50, ntg=0.5, porosity=0.2, depth=2000, ln_permeability_mean=4, ln_permeability_sd=0.5 ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[50]).to_dataset() results = calculate_doublet_performance_stochastic(input_data) print(results) Loading @@ -89,25 +79,24 @@ def test_example_5(): ) output_data_path.mkdir(parents=True, exist_ok=True) input_data = xr.Dataset( { "thickness_mean": 300, "thickness_sd": 50, "ntg": 0.5, "porosity": 0.2, "depth": 2000, "ln_permeability_mean": 5, "ln_permeability_sd": 0.5, } ) results = calculate_doublet_performance_stochastic( input_data, p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99] aquifer = StochasticAquifer( thickness_mean=300, thickness_sd=50, ntg=0.5, porosity=0.2, depth=2000, ln_permeability_mean=5, ln_permeability_sd=0.5, ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99]).to_dataset() fig, axe = plt.subplots(figsize=(10, 5)) kh = results.transmissivity_with_ntg * 1.0 kh.plot(y="p_value", ax=axe) axe.set_title("Aquifer Net transmissivity\n kH") temp = input_data.temperature temp = aquifer.temperature inj_temp = results.inj_temp.sel(p_value=50, method="nearest") prd_temp = results.prd_temp.sel(p_value=50, method="nearest") axe.axhline( Loading @@ -129,12 +118,12 @@ def test_example_6(): # the location of the input data: # the data can be found in the resources/example_data directory of the repo input_data_path = ( Path(__file__).parent.parent / "resources" / "test_input" / "example_data" Path(__file__).parent / "resources" / "test_input" / "example_data" ) # create a directory to write the output files to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example6" Path(__file__).parent / "resources" / "test_output" / "example6" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading @@ -145,37 +134,47 @@ def test_example_6(): # grids can be in .nc, .asc, .zmap or .tif format: see pygridsio package new_cellsize = 5000 # in m, this sets the resolution of the model; # to speed up calcualtions you can increase the cellsize reservoir_properties = resample_grid( thickness_mean = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__thick.zmap"), new_cellsize=new_cellsize ).to_dataset(name="thickness_mean") reservoir_properties["thickness_sd"] = resample_grid( ) thickness_sd = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__thick_sd.zmap"), new_cellsize=new_cellsize, ) reservoir_properties["ntg"] = resample_grid( ntg = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap"), new_cellsize=new_cellsize ) reservoir_properties["porosity"] = ( porosity = ( resample_grid( read_grid(input_data_path / "ROSL_ROSLU__poro.zmap"), new_cellsize=new_cellsize, ) / 100 ) reservoir_properties["depth"] = resample_grid( depth = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__top.zmap"), new_cellsize=new_cellsize ) reservoir_properties["ln_permeability_mean"] = np.log( ln_permeability_mean = np.log( resample_grid( read_grid(input_data_path / "ROSL_ROSLU__perm.zmap"), new_cellsize=new_cellsize, ) ) reservoir_properties["ln_permeability_sd"] = resample_grid( ln_permeability_sd = resample_grid( read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap"), new_cellsize=new_cellsize, ) aquifer = StochasticAquifer( thickness_mean=thickness_mean, thickness_sd=thickness_sd, ntg=ntg, porosity=porosity, depth=depth, ln_permeability_mean=ln_permeability_mean, ln_permeability_sd=ln_permeability_sd, ) # output inputs variables_to_plot = ["depth", "thickness_mean", "thickness_sd"] fig, axes = plt.subplots( Loading @@ -187,7 +186,7 @@ def test_example_6(): ) for i, variable in enumerate(variables_to_plot): plot_grid( reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True ) # See documentation on plot_grid in pygridsio, # you can also provide your own shapefile plt.tight_layout() # ensure there is enough spacing Loading @@ -203,7 +202,7 @@ def test_example_6(): ) for i, variable in enumerate(variables_to_plot): plot_grid( reservoir_properties[variable], axes=axes[i], add_netherlands_shapefile=True getattr(aquifer, variable), axes=axes[i], add_netherlands_shapefile=True ) # See documentation on plot_grid in pygridsio, # you can also provide your own shapefile plt.tight_layout() # ensure there is enough spacing Loading @@ -215,9 +214,8 @@ def test_example_6(): if (output_data_path / "output_results.nc").exists and not run_simulation: results = xr.load_dataset(output_data_path / "output_results.nc") else: results = calculate_doublet_performance_stochastic( reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90] ) results = ThermoGISDoublet(aquifer=aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset() results.to_netcdf( output_data_path / "output_results.nc" ) # write doublet simulation results to file Loading Loading @@ -284,22 +282,28 @@ def test_example_7(): output_data_path.mkdir(parents=True, exist_ok=True) # read in reservoir property maps reservoir_properties = read_grid( thickness_mean = read_grid( input_data_path / "ROSL_ROSLU__thick.zmap" ).to_dataset(name="thickness_mean") reservoir_properties["thickness_sd"] = read_grid( ) thickness_sd = read_grid( input_data_path / "ROSL_ROSLU__thick_sd.zmap" ) reservoir_properties["ntg"] = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap") reservoir_properties["porosity"] = 0.01 * read_grid( ntg = read_grid(input_data_path / "ROSL_ROSLU__ntg.zmap") porosity = 0.01 * read_grid( input_data_path / "ROSL_ROSLU__poro.zmap" ) reservoir_properties["depth"] = read_grid(input_data_path / "ROSL_ROSLU__top.zmap") reservoir_properties["ln_permeability_mean"] = np.log( read_grid(input_data_path / "ROSL_ROSLU__perm.zmap") ) reservoir_properties["ln_permeability_sd"] = read_grid( input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap" depth = read_grid(input_data_path / "ROSL_ROSLU__top.zmap") ln_permeability_mean = np.log(read_grid(input_data_path / "ROSL_ROSLU__perm.zmap")) ln_permeability_sd = read_grid(input_data_path / "ROSL_ROSLU__ln_perm_sd.zmap") aquifer = StochasticAquifer( thickness_mean=thickness_mean, thickness_sd=thickness_sd, ntg=ntg, porosity=porosity, depth=depth, ln_permeability_mean=ln_permeability_mean, ln_permeability_sd=ln_permeability_sd, ) # Select locations of interest from the reservoir Loading @@ -313,16 +317,18 @@ def test_example_7(): ] # Collect selected locations, create a new Dataset with the coordinate 'location' aquifer_ds = aquifer.to_dataset() locations = [] for i, (x, y) in enumerate(portfolio_coords): point = reservoir_properties.sel(x=x, y=y, method="nearest") point = point.expand_dims(location=[i]) # Add new dim for stacking point = aquifer_ds.sel(x=x, y=y, method="nearest") point = point.expand_dims(location=[i]) locations.append(point) portfolio_reservoir_properties = xr.concat(locations, dim="location") results_portfolio = calculate_doublet_performance_stochastic( portfolio_reservoir_properties, p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90] ) portfolio_aquifer = StochasticAquifer(**portfolio_reservoir_properties.data_vars) results_portfolio = ThermoGISDoublet(aquifer=portfolio_aquifer).simulate(p_values=[10, 20, 30, 40, 50, 60, 70, 80, 90]).to_dataset() # post process: clip the npv and calculate the probability of success AEC = -3.5 Loading Loading @@ -357,7 +363,7 @@ def test_example_7(): kh = results_loc.transmissivity_with_ntg kh.plot(y="p_value", ax=ax, color=colors[i_loc]) ax.set_title("Aquifer: ROSL_ROSLU\n kH") temp = results_loc.temperature.sel(p_value=50) temp = results_loc.temperature inj_temp = results_loc.inj_temp.sel(p_value=50) prd_temp = results_loc.prd_temp.sel(p_value=50) ax.axhline( Loading Loading @@ -409,7 +415,7 @@ def test_example_7(): def test_example_8(): # output directory to write output to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example8" Path(__file__).parent / "resources" / "test_output" / "example8" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading @@ -432,9 +438,14 @@ def test_example_8(): ) # For every sample, run a doublet simulation store the output values simulations = calculate_doublet_performance( reservoir_properties, print_execution_duration=True aquifer = Aquifer( thickness=reservoir_properties["thickness"], porosity=reservoir_properties["porosity"], ntg=reservoir_properties["ntg"], depth=reservoir_properties["depth"], permeability=reservoir_properties["permeability"], ) simulations = ThermoGISDoublet(aquifer=aquifer).simulate().to_dataset() # post process the samples to calculate the percentiles of each variable percentiles = np.arange(1, 99) Loading Loading @@ -484,7 +495,7 @@ def test_example_8(): def test_example_9(): # output directory to write output to output_data_path = ( Path(__file__).parent.parent / "resources" / "test_output" / "example9" Path(__file__).parent / "resources" / "test_output" / "example9" ) output_data_path.mkdir(parents=True, exist_ok=True) Loading Loading @@ -522,25 +533,27 @@ def test_example_9(): # clip to minimum transmissivity of 1Dm permeability = np.clip(permeability, 1000 / thickness, 1e10) reservoir_properties = xr.Dataset( { "thickness": thickness, "porosity": (["depth", "samples"], porosity / 100), "ntg": ntg, "permeability": (["depth", "samples"], permeability), }, coords={ "samples": np.arange(n_samples), "depth": depths, }, porosity_da = xr.DataArray( porosity / 100, dims=["depth", "samples"], coords={"depth": depths, "samples": np.arange(n_samples)} ) permeability_da = xr.DataArray( permeability, dims=["depth", "samples"], coords={"depth": depths, "samples": np.arange(n_samples)} ) depth_da = xr.DataArray(depths, dims=["depth"], coords={"depth": depths}) # For every sample, run a doublet simulation simulations = calculate_doublet_performance( reservoir_properties, chunk_size=100, aquifer = Aquifer( thickness=thickness, porosity=porosity_da, ntg=ntg, depth=depth_da, permeability=permeability_da, ) # For every sample, run a doublet simulation simulations = ThermoGISDoublet(aquifer=aquifer).simulate(chunk_size=100).to_dataset() simulations_stoch = simulations.quantile([0.1, 0.5, 0.9], dim="samples") # make a plot showing there is a sweet spot between Doublet power, Cost of energy Loading