Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.9.53
current_version = 3.9.54
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion .cookiecutterrc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ default_context:
sphinx_doctest: "no"
sphinx_theme: "sphinx-py3doc-enhanced-theme"
test_matrix_separate_coverage: "no"
version: 3.9.53
version: 3.9.54
version_manager: "bump2version"
website: "https://github.com/NREL"
year_from: "2023"
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Free software: `MIT license <LICENSE>`__
:alt: Supported implementations
:target: https://pypi.org/project/geophires-x

.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.9.53.svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.9.54.svg
:alt: Commits since latest release
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.9.53...main
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.9.54...main

.. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat
:target: https://nrel.github.io/GEOPHIRES-X
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
year = '2025'
author = 'NREL'
copyright = f'{year}, {author}'
version = release = '3.9.53'
version = release = '3.9.54'

pygments_style = 'trac'
templates_path = ['./templates']
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def read(*names, **kwargs):

setup(
name='geophires-x',
version='3.9.53',
version='3.9.54',
license='MIT',
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
long_description='{}\n{}'.format(
Expand Down
74 changes: 44 additions & 30 deletions src/geophires_x/Parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def __post_init__(self):
json_parameter_type: str = _JSON_PARAMETER_TYPE_ARRAY


def ReadParameter(ParameterReadIn: ParameterEntry, ParamToModify, model):
def ReadParameter(ParameterReadIn: ParameterEntry, ParamToModify, model) -> None:
"""
ReadParameter: A method to take a single ParameterEntry object and use it to update the associated Parameter.
Does validation as well as Unit and Currency conversion
Expand Down Expand Up @@ -393,35 +393,8 @@ def default_parameter_value_message(new_val: Any, param_to_modify_name: str, def
ParamToModify.Provided = True # set provided to true because we are using a user provide value now
ParamToModify.Valid = True # set Valid to true because it passed the validation tests
elif isinstance(ParamToModify, listParameter):
New_val = float(ParameterReadIn.sValue)
if (New_val < float(ParamToModify.Min)) or (New_val > float(ParamToModify.Max)):
# user provided value is out of range, so announce it, leave set to whatever it was set to (default value)
if len(ParamToModify.ErrMessage) > 0:
msg = (
f'Parameter given ({str(New_val)}) for {ParamToModify.Name} outside of valid range.'
f'GEOPHIRES will {ParamToModify.ErrMessage}'
)
print(f'Warning: {msg}')
model.logger.warning(msg)
model.logger.info(f'Complete {str(__name__)}: {sys._getframe().f_code.co_name}')
return
else:
if ' ' in ParamToModify.Name:
# Some list parameters are read in with enumerated parameter names; in these cases we use the last
# character of the description to get the position i.e., "Gradient 1" is position 0.
parts = ParameterReadIn.Name.split(' ')
position = int(parts[1]) - 1
if position >= len(ParamToModify.value):
ParamToModify.value.append(New_val) # we are adding to the list, so use append
else: # we are replacing a value, so pop the value we want to replace, then insert a new one
ParamToModify.value.pop(position)
ParamToModify.value.insert(position, New_val)
else:
# In an ideal world this would be handled in ParameterEntry such that its sValue and Comment are
# correct; however that would only be practical if ParameterEntry had typing information to know
# whether to treat text after a second comma as a comment or list entry.
ParamToModify.value = [float(x.strip()) for x in ParameterReadIn.raw_entry.split('--')[0].split(',')[1:]
if x.strip() != '']
_read_list_parameter(ParameterReadIn, ParamToModify, model)

elif isinstance(ParamToModify, boolParameter):
if ParameterReadIn.sValue == "0":
New_val = False
Expand Down Expand Up @@ -449,6 +422,47 @@ def default_parameter_value_message(new_val: Any, param_to_modify_name: str, def
model.logger.info(f'Complete {str(__name__)}: {sys._getframe().f_code.co_name}')


def _read_list_parameter(ParameterReadIn: ParameterEntry, ParamToModify, model) -> None:
"""
:type ParamToModify: :class:`~geophires_x.Parameter.Parameter`
:type model: :class:`~geophires_x.Model.Model`
"""

if ' ' in ParamToModify.Name:
New_val = float(ParameterReadIn.sValue)
# Some list parameters are read in with enumerated parameter names; in these cases we use the last
# character of the description to get the position i.e., "Gradient 1" is position 0.
parts = ParameterReadIn.Name.split(' ')
position = int(parts[1]) - 1
if position >= len(ParamToModify.value):
ParamToModify.value.append(New_val) # we are adding to the list, so use append
else: # we are replacing a value, so pop the value we want to replace, then insert a new one
ParamToModify.value.pop(position)
ParamToModify.value.insert(position, New_val)
else:
# In an ideal world this would be handled in ParameterEntry such that its sValue and Comment are
# correct; however that would only be practical if ParameterEntry had typing information to know
# whether to treat text after a second comma as a comment or list entry.
ParamToModify.value = [float(x.strip()) for x in ParameterReadIn.raw_entry.split('--')[0].split(',')[1:]
if x.strip() != '']

ParamToModify.Provided = True

valid = True
for i in range(len(ParamToModify.value)):
New_val = ParamToModify.value[i]
if (New_val < float(ParamToModify.Min)) or (New_val > float(ParamToModify.Max)):
msg = (
f'Value given ({str(New_val)}) for {ParamToModify.Name} outside of valid range '
f'({ParamToModify.Min}–{ParamToModify.Max}).'
)
print(f'Warning: {msg}')
model.logger.warning(msg)
valid = False

ParamToModify.Valid = valid


def ConvertUnits(ParamToModify, strUnit: str, model) -> str:
"""
ConvertUnits gets called if a unit version is needed: either currency or standard units like F to C or m to ft
Expand Down
9 changes: 8 additions & 1 deletion src/geophires_x/Reservoir.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,14 @@ def read_parameters(self, model: Model) -> None:
elif ParameterToModify.Name.startswith('Thickness '):
parts = ParameterReadIn.Name.split(' ')
position = int(parts[1]) - 1
model.reserv.layerthickness.value[position] = ParameterToModify.value
num_segments = len(model.reserv.layerthickness.value)
if position < num_segments:
model.reserv.layerthickness.value[position] = ParameterToModify.value
else:
model.logger.error(f'Cannot set {ParameterToModify.Name} to {ParameterToModify.value} '
f'because only {num_segments} segments are defined.')
# Don't raise exception since we can ignore and the user will see the incorrectly configured
# segment(s) in the result.

elif ParameterToModify.Name.startswith("Fracture Separation"):
self.fracsepcalc.value = self.fracsep.value
Expand Down
2 changes: 1 addition & 1 deletion src/geophires_x/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.9.53'
__version__ = '3.9.54'
65 changes: 65 additions & 0 deletions tests/geophires_x_tests/test_reservoir.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,68 @@ def _fractures_lcoe_net(r: GeophiresXResult) -> tuple[int, float, float]:

self.assertGreater(net_production, 0)
self.assertLess(net_production, 500)

def test_thicknesses_param(self):
def _get_result() -> GeophiresXResult:
return GeophiresXClient().get_geophires_result(
GeophiresInputParameters(
from_file_path=self._get_test_file_path('generic-egs-case.txt'),
params={
'Number of Segments': 3,
'Gradient 2': '40',
'Gradient 3': '40',
'Thicknesses': '2.5,0.49,0.87',
},
)
)

r = _get_result()
summary = r.result['SUMMARY OF RESULTS']

expected = {
'Segment 1 Geothermal gradient': {'unit': 'degC/km', 'value': 36.7},
'Segment 1 Thickness': {'unit': 'kilometer', 'value': 2.5},
'Segment 2 Geothermal gradient': {'unit': 'degC/km', 'value': 40},
'Segment 2 Thickness': {'unit': 'kilometer', 'value': 0.49},
'Segment 3 Geothermal gradient': {'unit': 'degC/km', 'value': 40},
'Segment 3 Thickness': None,
'Segment 4 Geothermal gradient': None,
}

for k, v in expected.items():
self.assertEqual(summary[k], v)

def test_number_of_segments(self):
def _get_result() -> GeophiresXResult:
return GeophiresXClient().get_geophires_result(
GeophiresInputParameters(
from_file_path=self._get_test_file_path('generic-egs-case.txt'),
params={
'Number of Segments': 3,
'Gradient 2': '40',
'Gradient 3': '40',
'Gradient 4': '40',
'Thickness 1': '2.5',
'Thickness 2': '0.49',
'Thicknesses': '2.5,0.49,0.87',
'Thickness 3': '0.65',
'Thickness 4': '0.85',
},
)
)

r = _get_result()
summary = r.result['SUMMARY OF RESULTS']

expected = {
'Segment 1 Geothermal gradient': {'unit': 'degC/km', 'value': 36.7},
'Segment 1 Thickness': {'unit': 'kilometer', 'value': 2.5},
'Segment 2 Geothermal gradient': {'unit': 'degC/km', 'value': 40},
'Segment 2 Thickness': {'unit': 'kilometer', 'value': 0.49},
'Segment 3 Geothermal gradient': {'unit': 'degC/km', 'value': 40},
'Segment 3 Thickness': None,
'Segment 4 Geothermal gradient': None,
}

for k, v in expected.items():
self.assertEqual(summary[k], v)
Loading