Skip to content

Commit 911cbb2

Browse files
Merge pull request #11 from softwareengineerprogrammer/remove-water-property-fallback-calcs
Remove water property fallback calculations NREL#110
2 parents 0d7d535 + c7e416b commit 911cbb2

26 files changed

+377
-334
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.1
2+
current_version = 3.4.2
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.1
57+
version: 3.4.2
5858
version_manager: "bump2version"
5959
website: "https://github.com/NREL"
6060
year_from: "2023"

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.1.svg
50+
.. |commits-since| image:: https://img.shields.io/github/commits-since/NREL/GEOPHIRES-X/v3.4.2.svg
5151
:alt: Commits since latest release
52-
:target: https://github.com/NREL/GEOPHIRES-X/compare/v3.4.1...main
52+
:target: https://github.com/NREL/GEOPHIRES-X/compare/v3.4.2...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.1'
21+
version = release = '3.4.2'
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.1',
16+
version='3.4.2',
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: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,19 +1044,19 @@ def Calculate(self, model: Model) -> None:
10441044
else: # PI is used for both the verticals
10451045
UpgoingPumpingPower, self.PumpingPowerProd.value, self.DPProdWell.value, self.Pprodwellhead.value = \
10461046
ProdPressureDropAndPumpingPowerUsingIndexes(
1047-
model, self.usebuiltinhydrostaticpressurecorrelation, self.productionwellpumping.value,
1047+
model, self.productionwellpumping.value,
10481048
self.usebuiltinppwellheadcorrelation,
1049-
model.reserv.Trock.value, model.reserv.Tsurf.value, model.reserv.depth.value,
1050-
model.reserv.averagegradient.value, self.ppwellhead.value, self.PI.value,
1049+
model.reserv.Trock.value, model.reserv.depth.value,
1050+
self.ppwellhead.value, self.PI.value,
10511051
self.prodwellflowrate.value, f3, vprod,
10521052
self.prodwelldiam.value, self.nprod.value, model.surfaceplant.pump_efficiency.value,
10531053
self.rhowaterprod)
10541054

10551055
DowngoingPumpingPower, ppp2, dppw, ppwh = ProdPressureDropAndPumpingPowerUsingIndexes(
1056-
model, self.usebuiltinhydrostaticpressurecorrelation, self.productionwellpumping.value,
1056+
model, self.productionwellpumping.value,
10571057
self.usebuiltinppwellheadcorrelation,
1058-
model.reserv.Trock.value, model.reserv.Tsurf.value, model.reserv.depth.value,
1059-
model.reserv.averagegradient.value, self.ppwellhead.value, self.PI.value,
1058+
model.reserv.Trock.value, model.reserv.depth.value,
1059+
self.ppwellhead.value, self.PI.value,
10601060
self.prodwellflowrate.value, f3, vprod,
10611061
self.injwelldiam.value, self.nprod.value, model.surfaceplant.pump_efficiency.value,
10621062
self.rhowaterinj)
@@ -1102,7 +1102,10 @@ def Calculate(self, model: Model) -> None:
11021102
self.ProducedTemperature.value = self.InterpolatedTemperatureArray.copy()
11031103

11041104
tot_length, vert_length, horizontal_lengths = self.calculatedrillinglengths(model)
1105-
model.reserv.depth.value = model.reserv.InputDepth.value * 1000.0 # in this case, reserv.depth is just the vertical drill depth
1105+
1106+
# in this case, reserv.depth is just the vertical drill depth
1107+
# FIXME earlier calculations use depth before this value is set, meaning they're using the wrong value
1108+
model.reserv.depth.value = model.reserv.InputDepth.quantity().to(model.reserv.depth.CurrentUnits).magnitude
11061109

11071110
# getTandP results must be rejiggered to match wellbores expected output. Once done,
11081111
# the surfaceplant and economics models should just work
@@ -1116,19 +1119,12 @@ def Calculate(self, model: Model) -> None:
11161119
rho_water = density_water_kg_per_m3(
11171120
self.Tout[0],
11181121
pressure = model.reserv.lithostatic_pressure(),
1119-
1120-
# FIXME TODO - get rid of fallback calculations https://github.com/NREL/GEOPHIRES-X/issues/110
1121-
enable_fallback_calculation=True
11221122
)
11231123

11241124

11251125
model.reserv.cpwater.value = heat_capacity_water_J_per_kg_per_K(
11261126
self.Tout[0],
1127-
11281127
pressure=model.reserv.lithostatic_pressure(),
1129-
1130-
# FIXME TODO - get rid of fallback calculations https://github.com/NREL/GEOPHIRES-X/issues/110
1131-
enable_fallback_calculation=True
11321128
) # Need this for surface plant output calculation
11331129

11341130
# set pumping power to zero for all times, assuming that the thermosphere wil always

src/geophires_x/CylindricalReservoir.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
from functools import lru_cache
55

66
import numpy as np
7+
from pint.facets.plain import PlainQuantity
78

8-
from geophires_x.GeoPHIRESUtils import density_water_kg_per_m3
9+
from geophires_x.GeoPHIRESUtils import density_water_kg_per_m3, lithostatic_pressure_MPa, quantity
910

1011
from geophires_x.GeoPHIRESUtils import heat_capacity_water_J_per_kg_per_K
1112
import geophires_x.Model as Model
@@ -228,7 +229,9 @@ def Calculate(self, model: Model) -> None:
228229
# initialize with the Initial reservoir temperature
229230
self.Tresoutput.value = np.array(len(self.timevector.value) * [self.Trock.value])
230231
# depth in this case is actually the total length of the drilled assembly
231-
self.depth.value = self.InputDepth.value / 1000.0 + self.OutputDepth.value + self.Length.value
232+
self.depth.value = ((self.InputDepth.quantity() + self.OutputDepth.quantity() + self.Length.quantity()
233+
).to(self.depth.CurrentUnits).magnitude)
234+
232235
# Total volume of all laterals but hollow cylinder - doesn't include drilled-out area, units = m3
233236
self.resvolcalc.value = (
234237
model.wellbores.numnonverticalsections.value
@@ -256,3 +259,12 @@ def Calculate(self, model: Model) -> None:
256259
)
257260

258261
model.logger.info(f'complete {str(__class__)}: {sys._getframe().f_code.co_name}')
262+
263+
def lithostatic_pressure(self) -> PlainQuantity:
264+
"""
265+
@override
266+
267+
Standard reservoir implementation uses depth but CylindricalReservoir sets depth to total drilled length
268+
"""
269+
return quantity(lithostatic_pressure_MPa(self.rhorock.quantity().to('kg/m**3').magnitude,
270+
self.InputDepth.quantity().to('m').magnitude), 'MPa')

src/geophires_x/GeoPHIRESUtils.py

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,13 @@ def quantity(value: float, unit: str) -> PlainQuantity:
104104
@lru_cache
105105
def density_water_kg_per_m3(
106106
Twater_degC: float,
107-
pressure: Optional[PlainQuantity] = None,
108-
enable_fallback_calculation=False) -> float:
107+
pressure: Optional[PlainQuantity] = None) -> float:
109108
"""
110109
Calculate the density of water as a function of temperature.
111110
112111
Args:
113112
Twater_degC: The temperature of water in degrees C.
114113
pressure: Pressure - should be provided
115-
enable_fallback_calculation: deprecation shim, do not use, see https://github.com/NREL/GEOPHIRES-X/issues/110
116114
Returns:
117115
The density of water in kg/m³.
118116
Raises:
@@ -129,15 +127,8 @@ def density_water_kg_per_m3(
129127
return CP.PropsSI('D', 'T', celsius_to_kelvin(Twater_degC), 'Q', 0, 'Water')
130128

131129
except (NotImplementedError, ValueError) as e:
132-
if enable_fallback_calculation:
133-
_logger.warning(f'density_water: Fallback calculation triggered for {Twater_degC}C')
134-
135-
Twater_K = celsius_to_kelvin(Twater_degC)
136-
# water density correlation as used in Geophires v1.2 [kg/m3]
137-
rho_water = (.7983223 + (1.50896E-3 - 2.9104E-6 * Twater_K) * Twater_K) * 1E3
138-
return rho_water
139-
140-
raise ValueError(f'Input temperature {Twater_degC} is out of range or otherwise not implemented') from e
130+
raise ValueError(f'Input temperature & pressure ({Twater_degC}, {pressure}) '
131+
f'are out of range or otherwise could not be used to calculate') from e
141132

142133

143134
def celsius_to_kelvin(celsius: float) -> float:
@@ -161,12 +152,13 @@ def celsius_to_kelvin(celsius: float) -> float:
161152
@lru_cache
162153
def viscosity_water_Pa_sec(
163154
Twater_degC: float,
164-
pressure: Optional[PlainQuantity] = None,
165-
enable_fallback_calculation=False) -> float:
155+
pressure: Optional[PlainQuantity] = None) -> float:
166156
"""
167-
The ViscosityWater function is used to calculate the dynamic viscosity of water as a function of temperature.
157+
Calculate the dynamic viscosity of water as a function of temperature and pressure.
158+
168159
Args:
169160
Twater_degC: the temperature of water in degrees C
161+
pressure: Pressure - should be provided
170162
Returns:
171163
Viscosity of water in Pa·s (Ns/m2)
172164
Raises:
@@ -181,29 +173,21 @@ def viscosity_water_Pa_sec(
181173
return CP.PropsSI('V', 'T', celsius_to_kelvin(Twater_degC), 'Q', 0, 'Water')
182174

183175
except (NotImplementedError, ValueError) as e:
184-
if enable_fallback_calculation:
185-
_logger.warning(f'viscosity_water: Fallback calculation triggered for {Twater_degC}C')
186-
187-
# accurate to within 2.5% from 0 to 370 degrees C [Ns/m2]
188-
muwater = 2.414E-5 * np.power(10, 247.8 / (Twater_degC + 273.15 - 140))
189-
return muwater
190-
191-
raise ValueError(f'Input temperature {Twater_degC} is out of range or otherwise not implemented') from e
176+
raise ValueError(f'Input temperature & pressure ({Twater_degC}, {pressure}) '
177+
f'are out of range or otherwise could not be used to calculate') from e
192178

193179

194180
@lru_cache
195181
def heat_capacity_water_J_per_kg_per_K(
196182
Twater_degC: float,
197183
pressure: Optional[PlainQuantity] = None,
198-
enable_fallback_calculation=False
199184
) -> float:
200185
"""
201186
Calculate the isobaric specific heat capacity (c_p) of water as a function of temperature.
202187
203188
Args:
204189
Twater_degC: The temperature of water in degrees C.
205190
pressure: Pressure - should be provided
206-
enable_fallback_calculation: deprecation shim, do not use, see https://github.com/NREL/GEOPHIRES-X/issues/110
207191
Returns:
208192
The isobaric specific heat capacity of water as a function of temperature in J/(kg·K).
209193
Raises:
@@ -224,21 +208,8 @@ def heat_capacity_water_J_per_kg_per_K(
224208
return CP.PropsSI('C', 'T', celsius_to_kelvin(Twater_degC), 'Q', 0, 'Water')
225209

226210
except (NotImplementedError, ValueError) as e:
227-
if enable_fallback_calculation:
228-
_logger.warning(f'heat_capacity_water: Fallback calculation triggered for {Twater_degC}C')
229-
230-
Twater = (Twater_degC + 273.15) / 1000
231-
A = -203.6060
232-
B = 1523.290
233-
C = -3196.413
234-
D = 2474.455
235-
E = 3.855326
236-
# water specific heat capacity in J/(kg·K)
237-
cpwater = (A + B * Twater + C * Twater ** 2 + D * Twater ** 3 + E / (Twater ** 2)) / 18.02 * 1000
238-
239-
return cpwater
240-
241-
raise ValueError(f'Input temperature {Twater_degC} is out of range or otherwise not implemented') from e
211+
raise ValueError(f'Input temperature & pressure ({Twater_degC}, {pressure}) '
212+
f'are out of range or otherwise could not be used to calculate') from e
242213

243214

244215
@lru_cache
@@ -273,15 +244,15 @@ def RecoverableHeat(Twater_degC: float) -> float:
273244

274245

275246
@lru_cache
276-
def vapor_pressure_water_kPa(Twater_degC: float, enable_fallback_calculation=False) -> float:
247+
def vapor_pressure_water_kPa(
248+
Twater_degC: float,
249+
pressure: Optional[PlainQuantity] = None) -> float:
277250
"""
278251
Calculate the vapor pressure of water as a function of temperature.
279252
280-
TODO accept pressure as parameter https://github.com/NREL/GEOPHIRES-X/issues/118
281-
282253
Args:
283254
Twater_degC: the temperature of water in degrees C
284-
enable_fallback_calculation: deprecation shim, do not use, see https://github.com/NREL/GEOPHIRES-X/issues/110
255+
pressure: Pressure - should be provided
285256
Returns:
286257
The vapor pressure of water as a function of temperature in kPa
287258
Raises:
@@ -295,34 +266,19 @@ def vapor_pressure_water_kPa(Twater_degC: float, enable_fallback_calculation=Fal
295266
raise ValueError(f'Twater_degC ({Twater_degC}) must be greater than or equal to 0')
296267

297268
try:
298-
return (quantity(CP.PropsSI('P', 'T', celsius_to_kelvin(Twater_degC), 'Q', 0, 'Water'), 'Pa')
299-
.to('kPa').magnitude)
300-
except (NotImplementedError, ValueError) as e:
301-
if enable_fallback_calculation:
302-
_logger.warning(f'vapor_pressure_water: Fallback calculation triggered for {Twater_degC}C')
303-
return _vapor_pressure_antoine_equation_kPa(Twater_degC)
269+
if pressure is not None:
270+
return (quantity(
271+
CP.PropsSI('P', 'T', celsius_to_kelvin(Twater_degC), 'P', pressure.to('Pa').magnitude, 'Water'), 'Pa')
272+
.to('kPa').magnitude)
273+
else:
274+
_logger.warning(f'vapor_pressure_water: No pressure provided, using vapor quality=0 instead')
275+
return (quantity(CP.PropsSI('P', 'T', celsius_to_kelvin(Twater_degC), 'Q', 0, 'Water'), 'Pa')
276+
.to('kPa').magnitude)
304277

305278

279+
except (NotImplementedError, ValueError) as e:
306280
raise ValueError(f'Input temperature {Twater_degC} is out of range or otherwise not implemented') from e
307281

308-
def _vapor_pressure_antoine_equation_kPa(Twater_degC: float) -> float:
309-
"""
310-
water vapor pressure in kPa using Antione Equation
311-
Do not add additional consumers, use geophires_x.GeoPHIRESUtils.vapor_pressure_water_kPa instead.
312-
"""
313-
314-
if Twater_degC < 100:
315-
A = 8.07131
316-
B = 1730.63
317-
C = 233.426
318-
else:
319-
A = 8.14019
320-
B = 1810.94
321-
C = 244.485
322-
vp = 133.322 * (
323-
10 ** (A - B / (C + Twater_degC))) / 1000
324-
return vp
325-
326282

327283
@lru_cache
328284
def entropy_water_kJ_per_kg_per_K(temperature_degC: float) -> float:

src/geophires_x/Parameter.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class boolParameter(Parameter):
120120
DefaultValue (bool, True): The default value of that parameter
121121
"""
122122

123-
value: bool = True
123+
value: bool = True # FIXME set from DefaultValue
124124
DefaultValue: bool = value
125125
json_parameter_type: str = 'boolean'
126126

@@ -137,7 +137,7 @@ class intParameter(Parameter):
137137
AllowableRange (list): A list of the valid values
138138
"""
139139

140-
value: int = 0
140+
value: int = 0 # FIXME set from DefaultValue
141141
DefaultValue: int = value
142142
AllowableRange: List[int] = field(default_factory=list)
143143
json_parameter_type: str = 'integer'
@@ -158,8 +158,13 @@ class floatParameter(Parameter):
158158
which means that any value is valid by default
159159
"""
160160

161-
value: float = 0.0
162-
DefaultValue: float = value
161+
def __post_init__(self):
162+
if self.value is None:
163+
self.value = self.DefaultValue
164+
165+
value: float = None
166+
167+
DefaultValue: float = 0.0
163168
Min: float = -1.8e30
164169
Max: float = 1.8e30
165170
json_parameter_type: str = 'number'
@@ -176,7 +181,7 @@ class strParameter(Parameter):
176181
DefaultValue (str, ""): The default value of that parameter
177182
"""
178183

179-
value: str = ""
184+
value: str = "" # FIXME set from DefaultValue
180185
DefaultValue: str = value
181186
json_parameter_type: str = 'string'
182187

@@ -196,7 +201,7 @@ class listParameter(Parameter):
196201
which means that any value is valid by default
197202
"""
198203

199-
value: List[float] = field(default_factory=list)
204+
value: List[float] = field(default_factory=list) # FIXME set from DefaultValue
200205
DefaultValue: List[float] = field(default_factory=list)
201206
Min: float = -1.8e308
202207
Max: float = 1.8e308

0 commit comments

Comments
 (0)