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.16.0
current_version = 3.16.2
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.16.0
version: 3.16.2
version_manager: "bump2version"
website: "https://github.com/NREL"
year_from: "2023"
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ M.m.P: `TITLE <https://github.com/NREL/GEOPHIRES-X/pull/PR-NUMBER>`__ | `release
1. [ ] Push tag(s) to GitHub: `git push origin refs/tags/vM.m.P`
1. [ ] Post a change announcement to the [GEOPHIRES Change Announcements Discussion](https://github.com/NREL/GEOPHIRES-X/discussions/428) ([example](https://github.com/NREL/GEOPHIRES-X/discussions/428#discussioncomment-14593405)). Markdown template:
```markdown
M.m.p: [TITLE](https://github.com/NREL/GEOPHIRES-X/pull/PR-NUMBER) | [release](https://github.com/NREL/GEOPHIRES-X/releases/tag/vM.m.P)
M.m.p: [TITLE](https://github.com/NREL/GEOPHIRES-X/pull/PR-NUMBER) | [release](https://github.com/NREL/GEOPHIRES-X/releases/tag/vM.m.P)
```

---
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ GEOPHIRES v3 (2023-2026)
3.16
^^^^

3.16.2: `Add Number of Multilateral Sections per Vertical Section parameter; Output Annual License Fees Etc in OPEX <https://github.com/NatLabRockies/GEOPHIRES-X/pull/518>`__ | `release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.16.2>`__

3.16: `Fix Beckers_et_al_2023_Tabulated_Database_Coaxial_sCO2_heat and CLGS Pump Power unit display <https://github.com/NREL/GEOPHIRES-X/pull/515>`__ | `release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.16.0>`__

3.15
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ include CONTRIBUTING.rst
include LICENSE
include INSTALL.rst
include README.rst
include SECURITY.md
include How-to-extend-GEOPHIRES-X.md
include geophires-logo.png

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.16.0.svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.16.2.svg
:alt: Commits since latest release
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.16.0...main
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.16.2...main

.. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat
:target: https://softwareengineerprogrammer.github.io/GEOPHIRES
Expand Down
9 changes: 9 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Security Policy

## Reporting a Vulnerability

1. Go to https://github.com/softwareengineerprogrammer/GEOPHIRES/security/advisories
2. Click "Report a vulnerability"
3. Fill out the advisory form

This creates a private discussion visible only to maintainers.
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.16.0'
version = release = '3.16.2'

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.16.0',
version='3.16.2',
license='MIT',
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
long_description='{}\n{}'.format(
Expand Down
9 changes: 9 additions & 0 deletions src/geophires_x/AGSWellBores.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,15 @@ def read_parameters(self, model: Model) -> None:
:return: None
"""
model.logger.info(f'Init {str(__class__)}: {sys._getframe().f_code.co_name}')

# AGS/CLGS models do not model laterals on a per-vertical-section basis, so the total number of multilateral
# sections may not be derived from a per-vertical-section value.
if self.numnonverticalsections_per_vertical_section.Name in model.InputParameters:
msg = (f'{self.numnonverticalsections_per_vertical_section.Name} is not supported by AGS/CLGS models. '
f'Provide {self.numnonverticalsections.Name} instead.')
model.logger.error(msg)
raise NotImplementedError(msg)

super().read_parameters(model) # read the default parameters
# if we call super, we don't need to deal with setting the parameters here, just deal with the special cases
# for the variables in this class because the call to the super.read_parameters will set all the variables,
Expand Down
4 changes: 4 additions & 0 deletions src/geophires_x/Outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ def _render_additional_capital_cost_modifiers(additional_modifiers: list[tuple[P
redrill_label = Outputs._field_label(econ.redrilling_annual_cost.display_name, 47)
f.write(f' {redrill_label}{econ.redrilling_annual_cost.value:10.2f} {econ.redrilling_annual_cost.CurrentUnits.value}\n')

if econ.AnnualLicenseEtc.value != 0:
etc_label = Outputs._field_label(econ.AnnualLicenseEtc.Name, 47)
f.write(f' {etc_label}{econ.AnnualLicenseEtc.value:10.2f} {econ.AnnualLicenseEtc.CurrentUnits.value}\n')

if econ.DoAddOnCalculations.value and is_sam_econ_model:
# Non-SAM econ models print this in Extended Economics profile
aoc_label = Outputs._field_label(model.addeconomics.AddOnOPEXTotalPerYear.display_name, 47)
Expand Down
54 changes: 54 additions & 0 deletions src/geophires_x/WellBores.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,26 @@ def __init__(self, model: Model):
'per well should set Number of Multilateral Sections = 2 * 2 * 3 = 12.'
)

# noinspection SpellCheckingInspection
self.numnonverticalsections_per_vertical_section = self.ParameterDict[
self.numnonverticalsections_per_vertical_section.Name] = intParameter(
"Number of Multilateral Sections per Vertical Section",
DefaultValue=0,
AllowableRange=list(range(0, max_allowed_total_wells * max_allowed_laterals_per_well_when_max_wells, 1)),
UnitType=Units.NONE,
ErrMessage="assume default for Number of Multilateral Sections per Vertical Section (0)",
ToolTipText=f'Number of nonvertical wellbore sections (aka laterals or horizontals) per vertical '
f'section, where the number of vertical sections is the total number of wells '
f'({self.nprod.Name} + {self.ninj.Name}). Pass this parameter instead of '
f'{self.numnonverticalsections.Name} to define laterals on a per-well basis - the total '
f'number of multilateral sections for the project is calculated as this value multiplied by '
f'the number of vertical sections. For example, a project with 2 injectors and 2 producers '
f'with 3 laterals per well may set Number of Multilateral Sections per Vertical Section = 3, '
f'which is equivalent to {self.numnonverticalsections.Name} = 2 * 2 * 3 = 12. '
f'May not be provided in combination with {self.numnonverticalsections.Name}. '
f'Not supported by AGS/CLGS models.'
)

self.NonverticalsCased = self.ParameterDict[self.NonverticalsCased.Name] = boolParameter(
"Multilaterals Cased",
DefaultValue=False,
Expand Down Expand Up @@ -1439,6 +1459,7 @@ def read_parameters(self, model: Model) -> None:
coerce_int_params_to_enum_values(self.ParameterDict)

self._set_well_counts_from_parameters(model)
self._set_multilateral_section_count_from_parameters(model)

model.logger.info(f"read parameters complete {self.__class__.__name__}: {__name__}")

Expand Down Expand Up @@ -1468,6 +1489,39 @@ def _raise_incompatible_param_error(incompatible_param: intParameter, with_param

self.ninj.value = int(math.ceil(self.nprod.value * self.ninj_per_production_well.value))

def _set_multilateral_section_count_from_parameters(self, model: Model):
"""
Calculates the total number of multilateral sections from the number of multilateral sections per vertical
section, if the latter is provided. Must be called after well counts have been set.
"""
sections_per_vertical_section = self.numnonverticalsections_per_vertical_section
if not sections_per_vertical_section.Provided:
return

if self.numnonverticalsections.Provided:
msg = (f'{self.numnonverticalsections.Name} may not be provided when '
f'{sections_per_vertical_section.Name} is provided.')
model.logger.error(msg)
raise ValueError(msg)

vertical_sections = self.nprod.value + self.ninj.value
total_sections = sections_per_vertical_section.value * vertical_sections
max_total_sections = max(self.numnonverticalsections.AllowableRange)
if total_sections > max_total_sections:
msg = (f'Calculated {self.numnonverticalsections.Name} ({total_sections}) exceeds the maximum allowable '
f'value ({max_total_sections}) '
f'({sections_per_vertical_section.Name}: {sections_per_vertical_section.value}, '
f'number of vertical sections: {vertical_sections}).')
model.logger.error(msg)
raise ValueError(msg)

self.numnonverticalsections.value = total_sections
self.numnonverticalsections.Provided = True

model.logger.info(f'Calculated {self.numnonverticalsections.Name} ({total_sections}) from '
f'{sections_per_vertical_section.Name} ({sections_per_vertical_section.value}) and '
f'number of vertical sections ({vertical_sections}).')

def Calculate(self, model: Model) -> None:
"""
The Calculate function is where all the calculations are done.
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.16.0'
__version__ = '3.16.2'
1 change: 1 addition & 0 deletions src/geophires_x_client/geophires_x_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ class GeophiresXResult:
'Average annual auxiliary fuel cost',
'Average annual pumping cost',
'Redrilling costs',
'Annual License Fees Etc',
'Total Add-on OPEX',
'Total average annual O&M costs',
'Total operating and maintenance costs',
Expand Down
9 changes: 9 additions & 0 deletions src/geophires_x_schema_generator/geophires-request.json
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,15 @@
"minimum": 0,
"maximum": 1199
},
"Number of Multilateral Sections per Vertical Section": {
"description": "Number of nonvertical wellbore sections (aka laterals or horizontals) per vertical section, where the number of vertical sections is the total number of wells (Number of Production Wells + Number of Injection Wells). Pass this parameter instead of Number of Multilateral Sections to define laterals on a per-well basis - the total number of multilateral sections for the project is calculated as this value multiplied by the number of vertical sections. For example, a project with 2 injectors and 2 producers with 3 laterals per well may set Number of Multilateral Sections per Vertical Section = 3, which is equivalent to Number of Multilateral Sections = 2 * 2 * 3 = 12. May not be provided in combination with Number of Multilateral Sections. Not supported by AGS/CLGS models.",
"type": "integer",
"units": null,
"category": "Well Bores",
"default": 0,
"minimum": 0,
"maximum": 1199
},
"Multilaterals Cased": {
"description": "If set to True, casing & cementing are assumed to comprise 50% of drilling costs (doubling cost compared to uncased).",
"type": "boolean",
Expand Down
1 change: 1 addition & 0 deletions src/geophires_x_schema_generator/geophires-result.json
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@
"description": "Total redrilling costs over the Plant Lifetime are calculated as (Drilling and completion costs + Stimulation costs) \u00d7 Number of times redrilling. The total is then divided over Plant Lifetime years to calculate Redrilling costs per year.",
"units": "MUSD/yr"
},
"Annual License Fees Etc": {},
"Total Add-on OPEX": {
"type": "number",
"description": "AddOn OPEX Total Per Year",
Expand Down
Loading