Skip to content

Commit

Permalink
Merge pull request #333 from softwareengineerprogrammer/main
Browse files Browse the repository at this point in the history
Sync well drilling and completion adjustment factors [v3.7.5]
  • Loading branch information
softwareengineerprogrammer authored Jan 31, 2025
2 parents 7303de4 + dc1e0d6 commit 8102fb3
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 53 deletions.
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.7.3
current_version = 3.7.5
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.7.3
version: 3.7.5
version_manager: "bump2version"
website: "https://github.com/NREL"
year_from: "2023"
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ GEOPHIRES-X (2023-2025)

3.7.3: Heat to Power Conversion Efficiency output added.

3.7.5: Injection Well Drilling and Completion Capital Cost Adjustment Factor, if not provided, is now automatically set to the provided value of Well Drilling and Completion Capital Cost Adjustment Factor.


3.6
^^^
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,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.7.3.svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.7.5.svg
:alt: Commits since latest release
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.7.3...main
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.7.5...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.7.3'
version = release = '3.7.5'

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.7.3',
version='3.7.5',
license='MIT',
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
long_description='{}\n{}'.format(
Expand Down
79 changes: 47 additions & 32 deletions src/geophires_x/Economics.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@ def __init__(self, model: Model):
Valid=False,
ToolTipText="Injection Well Drilling and Completion Capital Cost"
)

# TODO parameterize/document default 5% indirect cost factor that is applied when neither of the well
# drilling/completion capital cost adjustment factors are provided
injection_well_cost_adjustment_factor_name = "Injection Well Drilling and Completion Capital Cost Adjustment Factor"
self.production_well_cost_adjustment_factor = self.ParameterDict[self.production_well_cost_adjustment_factor.Name] = floatParameter(
"Well Drilling and Completion Capital Cost Adjustment Factor",
DefaultValue=1.0,
Expand All @@ -657,19 +661,23 @@ def __init__(self, model: Model):
CurrentUnits=PercentUnit.TENTH,
Provided=False,
Valid=True,
ToolTipText="Well Drilling and Completion Capital Cost Adjustment Factor"
ToolTipText="Well Drilling and Completion Capital Cost Adjustment Factor. Applies to production wells; "
f"also applies to injection wells unless a value is provided for "
f"{injection_well_cost_adjustment_factor_name}."
)
self.injection_well_cost_adjustment_factor = self.ParameterDict[self.injection_well_cost_adjustment_factor.Name] = floatParameter(
"Injection Well Drilling and Completion Capital Cost Adjustment Factor",
DefaultValue=self.production_well_cost_adjustment_factor.value,
Min=0,
Max=10,
injection_well_cost_adjustment_factor_name,
DefaultValue=self.production_well_cost_adjustment_factor.DefaultValue,
Min=self.production_well_cost_adjustment_factor.Min,
Max=self.production_well_cost_adjustment_factor.Max,
UnitType=Units.PERCENT,
PreferredUnits=PercentUnit.TENTH,
CurrentUnits=PercentUnit.TENTH,
Provided=False,
Valid=True,
ToolTipText="Injection Well Drilling and Completion Capital Cost Adjustment Factor"
ToolTipText="Injection Well Drilling and Completion Capital Cost Adjustment Factor. "
f"If not provided, this value will be set automatically to the same value as "
f"{self.production_well_cost_adjustment_factor.Name}."
)
self.oamwellfixed = self.ParameterDict[self.oamwellfixed.Name] = floatParameter(
"Wellfield O&M Cost",
Expand Down Expand Up @@ -1753,7 +1761,8 @@ def __init__(self, model: Model):
CurrentUnits=PercentUnit.TENTH
)
self.ProjectMOIC = self.OutputParameterDict[self.ProjectMOIC.Name] = OutputParameter(
"Project Multiple of Invested Capital",
"Project MOIC",
ToolTipText="Project Multiple of Invested Capital",
UnitType=Units.PERCENT,
PreferredUnits=PercentUnit.TENTH,
CurrentUnits=PercentUnit.TENTH
Expand Down Expand Up @@ -1910,35 +1919,30 @@ def read_parameters(self, model: Model) -> None:
ParameterToModify.value = 1.0
elif ParameterToModify.Name == "Well Drilling and Completion Capital Cost Adjustment Factor":
if self.per_production_well_cost.Valid and ParameterToModify.Valid:
print("Warning: Provided well drilling and completion cost adjustment factor not" +
" considered because valid total well drilling and completion cost provided.")
model.logger.warning("Provided well drilling and completion cost adjustment factor not" +
" considered because valid total well drilling and completion cost provided.")
msg = ('Provided well drilling and completion cost adjustment factor not considered '
'because valid total well drilling and completion cost provided.')
print(f'Warning: {msg}')
model.logger.warning(msg)
elif not self.per_production_well_cost.Provided and not self.production_well_cost_adjustment_factor.Provided:
ParameterToModify.value = 1.0
print("Warning: No valid well drilling and completion total cost or adjustment" +
" factor provided. GEOPHIRES will assume default built-in well drilling and" +
" completion cost correlation with adjustment factor = 1.")
model.logger.warning(
"No valid well drilling and completion total cost or adjustment factor" +
" provided. GEOPHIRES will assume default built-in well drilling and completion cost" +
" correlation with adjustment factor = 1.")
msg = ("No valid well drilling and completion total cost or adjustment factor provided. "
"GEOPHIRES will assume default built-in well drilling and completion cost "
"correlation with adjustment factor = 1.")
print(f'Warning: {msg}')
model.logger.warning(msg)
elif self.per_production_well_cost.Provided and not self.per_production_well_cost.Valid:
print("Warning: Provided well drilling and completion cost outside of range 0-1000." +
" GEOPHIRES will assume default built-in well drilling and completion cost correlation" +
" with adjustment factor = 1.")
model.logger.warning("Provided well drilling and completion cost outside of range 0-1000." +
" GEOPHIRES will assume default built-in well drilling and completion cost correlation with" +
" adjustment factor = 1.")
msg = ("Provided well drilling and completion cost outside of range 0-1000. GEOPHIRES "
"will assume default built-in well drilling and completion cost correlation "
"with adjustment factor = 1.")
print(f'Warning: {msg}')
model.logger.warning(msg)
self.production_well_cost_adjustment_factor.value = 1.0
elif not self.per_production_well_cost.Provided and self.production_well_cost_adjustment_factor.Provided and not self.production_well_cost_adjustment_factor.Valid:
print("Warning: Provided well drilling and completion cost adjustment factor outside" +
" of range 0-10. GEOPHIRES will assume default built-in well drilling and completion" +
" cost correlation with adjustment factor = 1.")
model.logger.warning(
"Provided well drilling and completion cost adjustment factor outside" +
" of range 0-10. GEOPHIRES will assume default built-in well drilling and completion" +
" cost correlation with adjustment factor = 1.")
msg = ("Provided well drilling and completion cost adjustment factor outside of range "
"0-10. GEOPHIRES will assume default built-in well drilling and completion cost "
"correlation with adjustment factor = 1.")
print(f'Warning: {msg}')
model.logger.warning(msg)
self.production_well_cost_adjustment_factor.value = 1.0
elif ParameterToModify.Name == "Wellfield O&M Cost Adjustment Factor":
if self.oamtotalfixed.Valid:
Expand Down Expand Up @@ -2169,6 +2173,7 @@ def read_parameters(self, model: Model) -> None:

coerce_int_params_to_enum_values(self.ParameterDict)
self.sync_interest_rate(model)
self.sync_well_drilling_and_completion_capital_cost_adjustment_factor(model)

model.logger.info(f'complete {__class__!s}: {sys._getframe().f_code.co_name}')

Expand Down Expand Up @@ -2198,6 +2203,16 @@ def discount_rate_display() -> str:

self.interest_rate.value = self.discountrate.quantity().to(convertible_unit(self.interest_rate.CurrentUnits)).magnitude

def sync_well_drilling_and_completion_capital_cost_adjustment_factor(self, model):
if (self.production_well_cost_adjustment_factor.Provided
and not self.injection_well_cost_adjustment_factor.Provided):
factor = self.production_well_cost_adjustment_factor.value
self.injection_well_cost_adjustment_factor.value = factor
model.logger.info(
f'Set {self.injection_well_cost_adjustment_factor.Name} to {factor} because '
f'{self.production_well_cost_adjustment_factor.Name} was provided.')


def Calculate(self, model: Model) -> None:
"""
The Calculate function is where all the calculations are done.
Expand Down Expand Up @@ -2281,7 +2296,7 @@ def Calculate(self, model: Model) -> None:
else:
self.cost_lateral_section.value = 0.0
# cost of the well field
# 1.05 for 5% indirect costs
# 1.05 for 5% indirect costs - see TODO re:parameterizing at src/geophires_x/Economics.py:652
self.Cwell.value = 1.05 * ((self.cost_one_production_well.value * model.wellbores.nprod.value) +
(self.cost_one_injection_well.value * model.wellbores.ninj.value) +
self.cost_lateral_section.value)
Expand Down
2 changes: 1 addition & 1 deletion src/geophires_x/Outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@ def PrintOutputs(self, model: Model):
f.write(f' Project NPV: {model.economics.ProjectNPV.value:10.2f} ' + model.economics.ProjectNPV.PreferredUnits.value + NL)
f.write(f' Project IRR: {model.economics.ProjectIRR.value:10.2f} ' + model.economics.ProjectIRR.PreferredUnits.value + NL)
f.write(f' Project VIR=PI=PIR: {model.economics.ProjectVIR.value:10.2f}' + NL)
f.write(f' Project MOIC: {model.economics.ProjectMOIC.value:10.2f}' + NL)
f.write(f' {model.economics.ProjectMOIC.Name}: {model.economics.ProjectMOIC.value:10.2f}' + NL)

payback_period_val = model.economics.ProjectPaybackPeriod.value
project_payback_period_display = f'{payback_period_val:10.2f} {model.economics.ProjectPaybackPeriod.PreferredUnits.value}' \
Expand Down
2 changes: 1 addition & 1 deletion src/geophires_x/OutputsCCUS.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def PrintOutputs(self, model):
f.write(f" Project NPV (including carbon credit): {model.ccuseconomics.ProjectNPV.value:10.2f} " + model.ccuseconomics.ProjectNPV.PreferredUnits.value + NL)
f.write(f" Project IRR (including carbon credit): {model.ccuseconomics.ProjectIRR.value:10.2f} " + model.ccuseconomics.ProjectIRR.PreferredUnits.value + NL)
f.write(f" Project VIR=IR=PIR (including carbon credit): {model.ccuseconomics.ProjectVIR.value:10.2f}" + NL)
f.write(f" Project MOIC (including carbon credit): {model.ccuseconomics.ProjectMOIC.value:10.2f}" + NL)
f.write(f" {model.economics.ProjectMOIC.Name} (including carbon credit): {model.ccuseconomics.ProjectMOIC.value:10.2f}" + NL)
f.write(NL)
f.write(NL)
f.write(" ******************" + NL)
Expand Down
4 changes: 2 additions & 2 deletions src/geophires_x/Reservoir.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ def __init__(self, model: Model):
CurrentUnits=TemperatureUnit.CELSIUS,
Required=True,
ErrMessage="assume default surface temperature (15 deg.C)",
ToolTipText="Surface temperature used for calculating bottom-hole temperature \
(with geothermal gradient and reservoir depth)"
ToolTipText="Surface temperature used for calculating bottom-hole temperature "
"(with geothermal gradient and reservoir depth)"
)

self.usebuiltintough2model = False
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.7.3'
__version__ = '3.7.5'
3 changes: 3 additions & 0 deletions src/geophires_x_client/geophires_x_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ def _get_data_from_profile_lines(self, profile_lines):
return data

def _parse_number(self, number_str, field='string') -> int | float:
if number_str == 'N/A':
return None

try:
if '.' in number_str:
# TODO should probably ideally use decimal.Decimal to preserve precision,
Expand Down
16 changes: 9 additions & 7 deletions src/geophires_x_schema_generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class GeophiresXSchemaGenerator:
def __init__(self):
pass

def _get_dummy_model(self):
@staticmethod
def _get_dummy_model():
stash_cwd = Path.cwd()
stash_sys_argv = sys.argv
sys.argv = ['']
Expand Down Expand Up @@ -146,9 +147,9 @@ def generate_parameters_reference_rst(self) -> str:

input_params_by_category[category][input_param_name] = input_param

def get_input_params_table(category_params, category_name) -> str:
def get_input_params_table(_category_params, category_name) -> str:
category_display = category_name if category_name is not None else ''
input_rst = f"""
_input_rst = f"""
{category_display}
{'-' * len(category_display)}
.. list-table:: {category_display}{' ' if len(category_display) > 0 else ''}Parameters
Expand All @@ -162,7 +163,7 @@ def get_input_params_table(category_params, category_name) -> str:
- Min
- Max"""

for param_name in category_params:
for param_name in _category_params:
param = input_params[param_name]

# if param['Required']:
Expand All @@ -172,15 +173,15 @@ def get_input_params_table(category_params, category_name) -> str:

min_val, max_val = _get_min_and_max(param)

input_rst += f"""\n * - {param['Name']}
_input_rst += f"""\n * - {param['Name']}
- {_get_key(param, 'ToolTipText')}
- {_get_key(param, 'PreferredUnits')}
- {_get_key(param, 'json_parameter_type')}
- {default_value}
- {min_val}
- {max_val}"""

return input_rst
return _input_rst

input_rst = ''
for category, category_params in input_params_by_category.items():
Expand All @@ -204,7 +205,8 @@ def get_input_params_table(category_params, category_name) -> str:

return rst

def get_output_params_table_rst(self, output_params_json) -> str:
@staticmethod
def get_output_params_table_rst(output_params_json) -> str:
output_params = json.loads(output_params_json)

output_rst = """
Expand Down
6 changes: 3 additions & 3 deletions src/geophires_x_schema_generator/geophires-request.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@
"maximum": 0.99
},
"Surface Temperature": {
"description": "Surface temperature used for calculating bottom-hole temperature (with geothermal gradient and reservoir depth)",
"description": "Surface temperature used for calculating bottom-hole temperature (with geothermal gradient and reservoir depth)",
"type": "number",
"units": "degC",
"category": "Reservoir",
Expand Down Expand Up @@ -1392,7 +1392,7 @@
"maximum": 200
},
"Well Drilling and Completion Capital Cost Adjustment Factor": {
"description": "Well Drilling and Completion Capital Cost Adjustment Factor",
"description": "Well Drilling and Completion Capital Cost Adjustment Factor. Applies to production wells; also applies to injection wells unless a value is provided for Injection Well Drilling and Completion Capital Cost Adjustment Factor.",
"type": "number",
"units": "",
"category": "Economics",
Expand All @@ -1401,7 +1401,7 @@
"maximum": 10
},
"Injection Well Drilling and Completion Capital Cost Adjustment Factor": {
"description": "Injection Well Drilling and Completion Capital Cost Adjustment Factor",
"description": "Injection Well Drilling and Completion Capital Cost Adjustment Factor. If not provided, this value will be set automatically to the same value as Well Drilling and Completion Capital Cost Adjustment Factor.",
"type": "number",
"units": "",
"category": "Economics",
Expand Down
Loading

0 comments on commit 8102fb3

Please sign in to comment.