Skip to content

Commit d04896c

Browse files
Merge pull request NREL#126 from softwareengineerprogrammer/main
Hydrostatic-aware vapor pressure; >7km simple well cost correlation; other fixes (v3.4.4) * NREL#118 * NREL#65
2 parents ed16813 + 7171142 commit d04896c

34 files changed

+1752
-1178
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 3.4.3
2+
current_version = 3.4.4
33
commit = True
44
tag = True
55

.cookiecutterrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ default_context:
5454
sphinx_doctest: "no"
5555
sphinx_theme: "sphinx-py3doc-enhanced-theme"
5656
test_matrix_separate_coverage: "no"
57-
version: 3.4.3
57+
version: 3.4.4
5858
version_manager: "bump2version"
5959
website: "https://github.com/NREL"
6060
year_from: "2023"

CHANGELOG.rst

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,38 @@ GEOPHIRES-X (2023-2024)
77

88
3.4
99
^^^
10-
Monte Carlo moved to dedicated module
1110

12-
`diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.3.0...v3.4.0>`__
11+
`release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.4.0>`__ | `diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.3.0...v3.4.0>`__
1312

13+
Monte Carlo moved to dedicated module
1414

1515
3.3
1616
^^^
1717

18+
`release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.3.0>`__ | `diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.2.0...v3.3.0>`__
19+
1820
- Surface plant objectification. Note: some input values of ``End-Use Option`` will need to be updated to ``Plant Type``, see `SUTRAExample1.txt update for example <https://github.com/softwareengineerprogrammer/GEOPHIRES-X/commit/c7ded3dbf01577d9f92fe39ee8cc921e0cf4b9e2#diff-2defdec554de21ee27fb205f3418b138d8c55fa74ea49281f536e9453df4c973R30-R32>`__
1921
- Introduction of HIP-RA-X
2022

21-
`diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.2.0...v3.3.0>`__
2223

2324

2425
3.2
2526
^^^
26-
Bug fixes
27+
`release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.2.0>`__ | `diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.1.0...v3.2.0>`__
2728

28-
`diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.1.0...v3.2.0>`__
29+
Bug fixes
2930

3031
3.1
3132
^^^
32-
Internal changes to support unit testing
33+
`release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.1.0>`__ | `diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.0.0...v3.1.0>`__
3334

34-
`diff <https://github.com/NREL/GEOPHIRES-X/compare/v3.0.0...v3.1.0>`__
35+
Internal changes to support unit testing
3536

3637

3738
3.0
3839
^^^
40+
`release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.0.0>`__
41+
3942
- New repository: https://github.com/NREL/GEOPHIRES-X (Originally https://github.com/NREL/python-geophires-x, renamed to GEOPHIRES-X 2023-12-15 per https://github.com/NREL/GEOPHIRES-X/issues/48.)
4043
- Ported from `malcolm-dsider/GEOPHIRES-X <https://github.com/malcolm-dsider/GEOPHIRES-X>`__ and `softwareengineerprogrammer/python-geophires-x <https://github.com/softwareengineerprogrammer/python-geophires-x>`__ using `ionelmc/cookiecutter-pylibrary <https://github.com/ionelmc/cookiecutter-pylibrary/>`__.
4144
- Releases now marked with tags/version metadata generated with ``bumpversion``

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ Free software: `MIT license <LICENSE>`__
4747
:alt: Supported implementations
4848
:target: https://pypi.org/project/geophires-x
4949

50-
.. |commits-since| image:: https://img.shields.io/github/commits-since/NREL/GEOPHIRES-X/v3.4.3.svg
50+
.. |commits-since| image:: https://img.shields.io/github/commits-since/NREL/GEOPHIRES-X/v3.4.4.svg
5151
:alt: Commits since latest release
52-
:target: https://github.com/NREL/GEOPHIRES-X/compare/v3.4.3...main
52+
:target: https://github.com/NREL/GEOPHIRES-X/compare/v3.4.4...main
5353

5454
.. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat
5555
:target: https://nrel.github.io/GEOPHIRES-X

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
year = '2023'
1919
author = 'NREL'
2020
copyright = f'{year}, {author}'
21-
version = release = '3.4.3'
21+
version = release = '3.4.4'
2222

2323
pygments_style = 'trac'
2424
templates_path = ['./templates']

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def read(*names, **kwargs):
1313

1414
setup(
1515
name='geophires-x',
16-
version='3.4.3',
16+
version='3.4.4',
1717
license='MIT',
1818
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
1919
long_description='{}\n{}'.format(

src/geophires_x/AGSWellBores.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ def interp_outlet_states(self, point):
140140
Pout = interpn(self.ivars, self.Pout, points)
141141

142142
except BaseException as ex:
143-
tb = sys.exc_info()[2]
144143
print(str(ex))
145-
print("Error: AGS Wellbores: interp_outlet_states failed. Exiting....Line %i" % tb.tb_lineno)
146-
sys.exit()
144+
msg = 'Error: AGSWellBores: interp_outlet_states failed.'
145+
print(msg)
146+
raise RuntimeError(msg) from ex
147147
return Tout, Pout
148148

149149
def interp_kWe_avg(self, point):
@@ -635,10 +635,10 @@ def __init__(self, model: Model):
635635
CurrentUnits=PressureUnit.KPASCAL
636636
)
637637

638-
model.logger.info("complete " + str(__class__) + ": " + sys._getframe().f_code.co_name)
638+
model.logger.info(f'complete {__class__!s}: {sys._getframe().f_code.co_name}')
639639

640640
def __str__(self):
641-
return "AGSWellBores"
641+
return 'AGSWellBores'
642642

643643
def read_parameters(self, model: Model) -> None:
644644
"""
@@ -734,7 +734,7 @@ def initialize(self, model: Model) -> None:
734734
:type model: :class:`~geophires_x.Model.Model`
735735
:return: None
736736
"""
737-
model.logger.info("Init " + str(__class__) + ": " + sys._getframe().f_code.co_name)
737+
model.logger.info(f'Init {__class__!s}: {sys._getframe().f_code.co_name}')
738738

739739
if self.Fluid.value == WorkingFluid.WATER:
740740
if self.Configuration.value == Configuration.ULOOP:

src/geophires_x/Economics.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ def Calculate(self, model: Model) -> None:
17561756
:type model: :class:`~geophires_x.Model.Model`
17571757
:return: Nothing, but it does make calculations and set values in the model
17581758
"""
1759-
model.logger.info("Init " + str(__class__) + ": " + sys._getframe().f_code.co_name)
1759+
model.logger.info(f'Init {__class__!s}: {sys._getframe().f_code.co_name}')
17601760

17611761
# capital costs
17621762
# well costs (using GeoVision drilling correlations). These are calculated whether totalcapcostvalid = 1
@@ -1766,40 +1766,44 @@ def Calculate(self, model: Model) -> None:
17661766
self.Cwell.value = self.C1well * (model.wellbores.nprod.value + model.wellbores.ninj.value)
17671767
else:
17681768
# if depth is > 7000 m, we don't have a correlation for it, so we must use the SIMPLE logic
1769-
checkdepth = model.reserv.depth.value
1770-
if model.reserv.depth.CurrentUnits != LengthUnit.METERS:
1771-
checkdepth = checkdepth * 1000.0
1769+
checkdepth = model.reserv.depth.quantity().to('m').magnitude
17721770
if (
17731771
checkdepth > 7000.0 or checkdepth < 500) and not self.wellcorrelation.value == WellDrillingCostCorrelation.SIMPLE:
1774-
print("Warning: simple user-specified cost per meter used for drilling depth < 500 or > 7000 m")
1775-
model.logger.warning(
1776-
"Warning: simple user-specified cost per meter used for drilling depth < 500 or > 7000 m")
1772+
msg = f'Simple user-specified cost per meter used for drilling depth <500 or >7000 m ({checkdepth}m)'
1773+
print(f'Warning: {msg}')
1774+
model.logger.warning(msg)
17771775
self.wellcorrelation.value = WellDrillingCostCorrelation.SIMPLE
1778-
if self.wellcorrelation.value == WellDrillingCostCorrelation.SIMPLE: # use SIMPLE approach
1776+
1777+
if self.wellcorrelation.value == WellDrillingCostCorrelation.SIMPLE:
1778+
# use SIMPLE approach
17791779
if hasattr(model.wellbores, 'Configuration'):
17801780
if model.wellbores.Configuration.value == Configuration.ULOOP:
1781-
if hasattr(model.reserv,
1782-
'InputDepth'): # must be using simple cylindrical model, which has an Input and Output Depth
1781+
if hasattr(model.reserv, 'InputDepth'):
1782+
# must be using simple cylindrical model, which has an Input and Output Depth
17831783
self.C1well = ((self.Vertical_drilling_cost_per_m.value *
1784-
(model.reserv.InputDepth.value * 1000.0)) +
1784+
(model.reserv.InputDepth.quantity().to('m').magnitude)) +
17851785
(self.Vertical_drilling_cost_per_m.value * (
1786-
model.reserv.OutputDepth.value * 1000.0)) +
1786+
model.reserv.OutputDepth.quantity().to('m').magnitude)) +
17871787
(
17881788
self.Nonvertical_drilling_cost_per_m.value * model.wellbores.Nonvertical_length.value)) * 1E-6
17891789
else:
17901790
if hasattr(model.wellbores, 'Nonvertical_length'):
17911791
self.C1well = ((2 * self.Vertical_drilling_cost_per_m.value *
1792-
(model.reserv.depth.value * 1000.0)) +
1792+
(model.reserv.depth.quantity().to('m').magnitude)) +
17931793
(
17941794
self.Nonvertical_drilling_cost_per_m.value * model.wellbores.Nonvertical_length.value)) * 1E-6
17951795
else:
17961796
self.C1well = (2 * self.Vertical_drilling_cost_per_m.value * (
1797-
model.reserv.depth.value * 1000.0)) * 1E-6
1798-
else: # Coaxial
1799-
self.C1well = ((self.Vertical_drilling_cost_per_m.value * (model.reserv.depth.value * 1000.0)) +
1797+
model.reserv.depth.value.quantity().to('m').magnitude)) * 1E-6
1798+
else:
1799+
# Coaxial
1800+
self.C1well = ((self.Vertical_drilling_cost_per_m.value * (model.reserv.depth.quantity().to('m').magnitude)) +
18001801
(
18011802
self.Nonvertical_drilling_cost_per_m.value * model.wellbores.Nonvertical_length.value)) * 1E-6
18021803

1804+
else:
1805+
self.C1well = self.Vertical_drilling_cost_per_m.value * model.reserv.depth.quantity().to(
1806+
'm').magnitude * 1E-6
18031807
elif self.wellcorrelation.value == WellDrillingCostCorrelation.VERTICAL_SMALL:
18041808
self.C1well = (
18051809
0.3021 * checkdepth ** 2 + 584.9112 * checkdepth + 751368.) * 1E-6 # well drilling and completion cost in M$/well
@@ -2279,7 +2283,7 @@ def Calculate(self, model: Model) -> None:
22792283
# Calculate LCOE/LCOH
22802284
self.LCOE.value, self.LCOH.value, self.LCOC.value = CalculateLCOELCOH(self, model)
22812285

2282-
model.logger.info("complete " + str(__class__) + ": " + sys._getframe().f_code.co_name)
2286+
model.logger.info(f'complete {__class__!s}: {sys._getframe().f_code.co_name}')
22832287

22842288
def __str__(self):
22852289
return "Economics"

src/geophires_x/Model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def __init__(self, enable_geophires_logging_config=True, input_file=None):
104104
self.reserv: Reservoir = SUTRAReservoir(self) # SUTRA output is created
105105

106106
# initialize the default objects
107-
self.wellbores = WellBores(self)
107+
self.wellbores: WellBores = WellBores(self)
108108
self.surfaceplant = SurfacePlant(self)
109109
self.economics = Economics(self)
110110

@@ -117,7 +117,7 @@ def __init__(self, enable_geophires_logging_config=True, input_file=None):
117117
if 'Reservoir Model' in self.InputParameters:
118118
if self.InputParameters['Reservoir Model'].sValue == '7':
119119
# if we use SUTRA output for simulating reservoir thermal energy storage, we use a special wellbore object that can handle SUTRA data
120-
self.wellbores = SUTRAWellBores(self)
120+
self.wellbores: WellBores = SUTRAWellBores(self)
121121
self.surfaceplant = SurfacePlantSUTRA(self)
122122
self.economics = SUTRAEconomics(self)
123123
self.outputs = SUTRAOutputs(self, output_file=output_file)
@@ -130,7 +130,7 @@ def __init__(self, enable_geophires_logging_config=True, input_file=None):
130130
# that means importing them, initializing them, then reading their parameters
131131
# use the simple cylindrical reservoir for all AGS systems.
132132
self.reserv: Reservoir = CylindricalReservoir(self)
133-
self.wellbores = AGSWellBores(self)
133+
self.wellbores: WellBores = AGSWellBores(self)
134134
self.surfaceplant = SurfacePlantAGS(self)
135135
self.economics = AGSEconomics(self)
136136
self.outputs = AGSOutputs(self, output_file=output_file)

src/geophires_x/Outputs.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,11 @@ def PrintOutputs(self, model: Model):
371371
f.write(f" Initial Net Electricity Generation: {model.surfaceplant.NetElectricityProduced.value[0]:10.2f} " + model.surfaceplant.NetElectricityProduced.PreferredUnits.value + NL)
372372
f.write(f" Average Annual Total Electricity Generation: {np.average(model.surfaceplant.TotalkWhProduced.value/1E6):10.2f} GWh" + NL)
373373
f.write(f" Average Annual Net Electricity Generation: {np.average(model.surfaceplant.NetkWhProduced.value/1E6):10.2f} GWh" + NL)
374-
if model.wellbores.PumpingPower.value[0] > 0.0: f.write(f" Initial pumping power/net installed power: {(model.wellbores.PumpingPower.value[0]/model.wellbores.PumpingPower.value[0]*100):10.2f} %" + NL)
374+
375+
if model.wellbores.PumpingPower.value[0] > 0.0:
376+
ipp_nip = model.wellbores.PumpingPower.value[0] / model.surfaceplant.NetElectricityProduced.value[0]
377+
f.write(f' Initial pumping power/net installed power: {(ipp_nip*100):10.2f} %\n')
378+
375379
if model.surfaceplant.enduse_option.value in [EndUseOptions.HEAT, PlantType.ABSORPTION_CHILLER, PlantType.HEAT_PUMP, EndUseOptions.COGENERATION_TOPPING_EXTRA_HEAT, EndUseOptions.COGENERATION_TOPPING_EXTRA_ELECTRICITY, EndUseOptions.COGENERATION_BOTTOMING_EXTRA_ELECTRICITY, EndUseOptions.COGENERATION_BOTTOMING_EXTRA_HEAT, EndUseOptions.COGENERATION_PARALLEL_EXTRA_HEAT, EndUseOptions.COGENERATION_PARALLEL_EXTRA_ELECTRICITY]: # geothermal heating component:
376380
f.write(f" Maximum Net Heat Production: {np.max(model.surfaceplant.HeatProduced.value):10.2f} " + model.surfaceplant.HeatProduced.PreferredUnits.value + NL)
377381
f.write(f" Average Net Heat Production: {np.average(model.surfaceplant.HeatProduced.value):10.2f} " + model.surfaceplant.HeatProduced.PreferredUnits.value + NL)

0 commit comments

Comments
 (0)