Skip to content

Commit b4dcf1e

Browse files
Merge pull request #77 from softwareengineerprogrammer/peaking-boiler-cost-override
Peaking boiler cost override NREL#392
2 parents 243e1fa + 3dc4cd2 commit b4dcf1e

File tree

9 files changed

+69
-11
lines changed

9 files changed

+69
-11
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.9.17
2+
current_version = 3.9.18
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.9.17
57+
version: 3.9.18
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
@@ -56,9 +56,9 @@ Free software: `MIT license <LICENSE>`__
5656
:alt: Supported implementations
5757
:target: https://pypi.org/project/geophires-x
5858

59-
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.9.17.svg
59+
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.9.18.svg
6060
:alt: Commits since latest release
61-
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.9.17...main
61+
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.9.18...main
6262

6363
.. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat
6464
: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 = '2025'
1919
author = 'NREL'
2020
copyright = f'{year}, {author}'
21-
version = release = '3.9.17'
21+
version = release = '3.9.18'
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.9.17',
16+
version='3.9.18',
1717
license='MIT',
1818
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
1919
long_description='{}\n{}'.format(

src/geophires_x/Economics.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,18 @@ def __init__(self, model: Model):
11111111
ErrMessage="assume default peaking boiler efficiency (85%)",
11121112
ToolTipText="Peaking boiler efficiency"
11131113
)
1114+
self._default_peaking_boiler_cost_USD_per_kw = 65
1115+
self.peaking_boiler_cost_per_kw = self.ParameterDict[self.peaking_boiler_cost_per_kw.Name] = floatParameter(
1116+
"Peaking Boiler Cost per KW",
1117+
DefaultValue=self._default_peaking_boiler_cost_USD_per_kw,
1118+
Min=0,
1119+
Max=1000,
1120+
UnitType=Units.ENERGYCOST,
1121+
PreferredUnits=EnergyCostUnit.DOLLARSPERKW,
1122+
CurrentUnits=EnergyCostUnit.DOLLARSPERKW,
1123+
Required=False,
1124+
ToolTipText="Peaking boiler cost per KW of maximum peaking boiler demand"
1125+
)
11141126
self.dhpipingcostrate = self.ParameterDict[self.dhpipingcostrate.Name] = floatParameter(
11151127
"District Heating Piping Cost Rate",
11161128
DefaultValue=1200,
@@ -1689,13 +1701,18 @@ def __init__(self, model: Model):
16891701
PreferredUnits=CurrencyFrequencyUnit.MDOLLARSPERYEAR,
16901702
CurrentUnits=CurrencyFrequencyUnit.MDOLLARSPERYEAR
16911703
)
1704+
16921705
# district heating
16931706
self.peakingboilercost = self.OutputParameterDict[self.peakingboilercost.Name] = OutputParameter(
16941707
Name="Peaking boiler cost",
16951708
UnitType=Units.CURRENCY,
16961709
PreferredUnits=CurrencyUnit.MDOLLARS,
1697-
CurrentUnits=CurrencyUnit.MDOLLARS
1710+
CurrentUnits=CurrencyUnit.MDOLLARS,
1711+
ToolTipText=f'Default cost: ${self._default_peaking_boiler_cost_USD_per_kw}/KW '
1712+
f'of maximum peaking boiler demand. '
1713+
f'Provide {self.peaking_boiler_cost_per_kw.Name} override the default.'
16981714
)
1715+
16991716
self.dhdistrictcost = self.OutputParameterDict[self.dhdistrictcost.Name] = OutputParameter(
17001717
Name="District Heating System Cost",
17011718
UnitType=Units.CURRENCY,
@@ -2381,10 +2398,18 @@ def Calculate(self, model: Model) -> None:
23812398
if self.ccplantfixed.Valid:
23822399
self.Cplant.value = self.ccplantfixed.value
23832400
else:
2401+
# 1.15 for 15% contingency and 1.12 for 12% indirect costs
2402+
# TODO https://github.com/NREL/GEOPHIRES-X/issues/383?title=Parameterize+indirect+cost+factor
23842403
self.Cplant.value = 1.12 * 1.15 * self.ccplantadjfactor.value * 250E-6 * np.max(
2385-
model.surfaceplant.HeatExtracted.value) * 1000. # 1.15 for 15% contingency and 1.12 for 12% indirect costs
2386-
self.peakingboilercost.value = 65 * model.surfaceplant.max_peaking_boiler_demand.value / 1000 # add 65$/KW for peaking boiler
2387-
self.Cplant.value += self.peakingboilercost.value # add peaking boiler cost to surface plant cost
2404+
model.surfaceplant.HeatExtracted.value) * 1000.
2405+
2406+
# add 65$/KW for peaking boiler
2407+
self.peakingboilercost.value = (self.peaking_boiler_cost_per_kw.quantity()
2408+
.to('USD / kilowatt').magnitude
2409+
* model.surfaceplant.max_peaking_boiler_demand.value / 1000)
2410+
2411+
# add peaking boiler cost to surface plant cost
2412+
self.Cplant.value += self.peakingboilercost.value
23882413

23892414

23902415
else: # all other options have power plant

src/geophires_x/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.9.17'
1+
__version__ = '3.9.18'

src/geophires_x_schema_generator/geophires-request.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,15 @@
18611861
"minimum": 0,
18621862
"maximum": 1
18631863
},
1864+
"Peaking Boiler Cost per KW": {
1865+
"description": "Peaking boiler cost per KW of maximum peaking boiler demand",
1866+
"type": "number",
1867+
"units": "USD/kW",
1868+
"category": "Economics",
1869+
"default": 65,
1870+
"minimum": 0,
1871+
"maximum": 1000
1872+
},
18641873
"District Heating Piping Cost Rate": {
18651874
"description": "District heating piping cost rate ($/m)",
18661875
"type": "number",

tests/geophires_x_tests/test_economics.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import os
24
import sys
35
from pathlib import Path
@@ -7,6 +9,7 @@
79
# ruff: noqa: I001 # Successful module initialization is dependent on this specific import order.
810
from geophires_x.Model import Model
911
from geophires_x.Economics import CalculateFinancialPerformance
12+
from geophires_x_client import GeophiresXResult, GeophiresXClient, GeophiresInputParameters
1013
from tests.base_test_case import BaseTestCase
1114

1215

@@ -115,3 +118,24 @@ def _new_model(self) -> Model:
115118
os.chdir(stash_cwd)
116119

117120
return m
121+
122+
def test_peaking_boiler_cost(self):
123+
def _get_result(peaking_boiler_cost_: int) -> GeophiresXResult:
124+
return GeophiresXClient().get_geophires_result(
125+
GeophiresInputParameters(
126+
from_file_path=self._get_test_file_path('../examples/example12_DH.txt'),
127+
params={
128+
'Peaking Boiler Cost per KW': peaking_boiler_cost_,
129+
},
130+
)
131+
)
132+
133+
def _lcoh_pbc(r: GeophiresXResult) -> tuple[float, float]:
134+
return (
135+
r.result['SUMMARY OF RESULTS']['Direct-Use heat breakeven price (LCOH)']['value'],
136+
r.result['CAPITAL COSTS (M$)']['of which Peaking Boiler Cost']['value'],
137+
)
138+
139+
lcoh, peaking_boiler_cost = _lcoh_pbc(_get_result(0))
140+
self.assertLess(lcoh, 13.19)
141+
self.assertEqual(0, peaking_boiler_cost)

0 commit comments

Comments
 (0)