From 4606e03833ebb548bdf3345263443bb23cabd4c5 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Tue, 28 Jan 2025 05:32:11 -0800 Subject: [PATCH 01/13] address linting hints in schema generator --- src/geophires_x_schema_generator/__init__.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/geophires_x_schema_generator/__init__.py b/src/geophires_x_schema_generator/__init__.py index 12707379..d83b4a63 100644 --- a/src/geophires_x_schema_generator/__init__.py +++ b/src/geophires_x_schema_generator/__init__.py @@ -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 = [''] @@ -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 @@ -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']: @@ -172,7 +173,7 @@ 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')} @@ -180,7 +181,7 @@ def get_input_params_table(category_params, category_name) -> str: - {min_val} - {max_val}""" - return input_rst + return _input_rst input_rst = '' for category, category_params in input_params_by_category.items(): @@ -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 = """ From 3d4877cd8fa8788a2ad587f789482478ddf0d587 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:05:31 -0800 Subject: [PATCH 02/13] Don't attempt to parse 'N/A' as number - eliminates needless log warning re: N/A project payback period --- src/geophires_x_client/geophires_x_result.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/geophires_x_client/geophires_x_result.py b/src/geophires_x_client/geophires_x_result.py index 9b547f9e..21a21195 100644 --- a/src/geophires_x_client/geophires_x_result.py +++ b/src/geophires_x_client/geophires_x_result.py @@ -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, From 4f4cad5dce09b2254ecbf4980ed4ac3cc7118384 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:05:39 -0800 Subject: [PATCH 03/13] =?UTF-8?q?Bump=20version:=203.7.3=20=E2=86=92=203.7?= =?UTF-8?q?.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- .cookiecutterrc | 2 +- README.rst | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- src/geophires_x/__init__.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index abe21e9a..48d46dbb 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.7.3 +current_version = 3.7.4 commit = True tag = True diff --git a/.cookiecutterrc b/.cookiecutterrc index 8d23c40b..f51d38f2 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -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.4 version_manager: "bump2version" website: "https://github.com/NREL" year_from: "2023" diff --git a/README.rst b/README.rst index 16b643f5..5fab975d 100644 --- a/README.rst +++ b/README.rst @@ -56,9 +56,9 @@ Free software: `MIT 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.4.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.4...main .. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat :target: https://nrel.github.io/GEOPHIRES-X diff --git a/docs/conf.py b/docs/conf.py index 1bc78af7..16a44381 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ year = '2025' author = 'NREL' copyright = f'{year}, {author}' -version = release = '3.7.3' +version = release = '3.7.4' pygments_style = 'trac' templates_path = ['./templates'] diff --git a/setup.py b/setup.py index a6e3821b..7edb0a24 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(*names, **kwargs): setup( name='geophires-x', - version='3.7.3', + version='3.7.4', license='MIT', description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.', long_description='{}\n{}'.format( diff --git a/src/geophires_x/__init__.py b/src/geophires_x/__init__.py index 87c08592..e604a8e1 100644 --- a/src/geophires_x/__init__.py +++ b/src/geophires_x/__init__.py @@ -1 +1 @@ -__version__ = '3.7.3' +__version__ = '3.7.4' From 2029282b0f56096480abac05f6b0d47ba7259999 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:01:38 -0800 Subject: [PATCH 04/13] Apply drilling cost adjustment to both production and injection wells if injection well factor is not specified https://github.com/NREL/GEOPHIRES-X/issues/332 --- src/geophires_x/Economics.py | 57 +++++++++++++---------- src/geophires_x/Outputs.py | 2 +- src/geophires_x/OutputsCCUS.py | 2 +- tests/drilling-adjustment-factor.txt | 68 ++++++++++++++++++++++++++++ tests/test_geophires_x.py | 52 +++++++++++++++++++++ 5 files changed, 154 insertions(+), 27 deletions(-) create mode 100644 tests/drilling-adjustment-factor.txt diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index 7f1da0f9..ea205617 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -1753,7 +1753,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 @@ -1910,35 +1911,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: @@ -2169,6 +2165,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}') @@ -2198,6 +2195,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. diff --git a/src/geophires_x/Outputs.py b/src/geophires_x/Outputs.py index 1a5ce3af..ff4e9055 100644 --- a/src/geophires_x/Outputs.py +++ b/src/geophires_x/Outputs.py @@ -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}' \ diff --git a/src/geophires_x/OutputsCCUS.py b/src/geophires_x/OutputsCCUS.py index e187c5a4..60935240 100644 --- a/src/geophires_x/OutputsCCUS.py +++ b/src/geophires_x/OutputsCCUS.py @@ -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) diff --git a/tests/drilling-adjustment-factor.txt b/tests/drilling-adjustment-factor.txt new file mode 100644 index 00000000..d7c6b1d9 --- /dev/null +++ b/tests/drilling-adjustment-factor.txt @@ -0,0 +1,68 @@ +Reservoir Model, 1 +Reservoir Volume Option, 1 +Reservoir Density, 2800 +#Reservoir Depth, 8500 feet, -- https://pangea.stanford.edu/ERE/db/GeoConf/papers/SGW/2024/Fercho.pdf +Reservoir Heat Capacity, 790 +Reservoir Thermal Conductivity, 3.05 +Reservoir Porosity, 0.0118 +Reservoir Impedance, 0.001 + +Number of Fractures, 149 +Fracture Shape, 4 +Fracture Height, 2000 +Fracture Width, 10000 +Fracture Separation, 30 + +Number of Segments, 1 + +Production Well Diameter, 7 +Injection Well Diameter, 7 +Well Separation, 365 feet +Injection Temperature, 60 degC +Injection Wellbore Temperature Gain, 3 +Plant Outlet Pressure, 1000 psi +#Production Wellhead Pressure, 325 psi +Ramey Production Wellbore Model, 1 +Utilization Factor, .9 +Water Loss Fraction, 0.05 +Maximum Drawdown, 1 +Ambient Temperature, 10 degC +#Surface Temperature, 10 degC +End-Use Option, 1 + +Plant Lifetime, 25 + +#Power Plant Type, 3 +Circulation Pump Efficiency, 0.80 + +#Exploration Capital Cost, 30 +#Reservoir Stimulation Capital Cost, 234, -- 78 wells @ $3M/well +Economic Model, 3 +Starting Electricity Sale Price, 0.15 +Ending Electricity Sale Price, 1.00 +Electricity Escalation Rate Per Year, 0.004053223 +Electricity Escalation Start Year, 1 +Fraction of Investment in Bonds, .5 +Combined Income Tax Rate, .3 +Gross Revenue Tax Rate, 0 +Inflated Bond Interest Rate, .05 +Inflated Equity Interest Rate, .08 +Inflation Rate, .02 +Investment Tax Credit Rate, .3, -- https://programs.dsireusa.org/system/program/detail/658 +Production Tax Credit Electricity, 0.0275, -- https://programs.dsireusa.org/system/program/detail/734 +Inflation Rate During Construction, 0.05 +Property Tax Rate, 0 +Time steps per year, 10 +Maximum Temperature, 500 + + +Print Output to Console, 0 +Surface Temperature, 12 +Reservoir Depth, 5.4 +Gradient 1, 36.7 +Power Plant Type, 4 + +# Well Drilling and Completion Capital Cost Adjustment Factor, 1.175 +Number of Injection Wells, 73 +Number of Production Wells, 73 +Production Flow Rate per Well, 80 diff --git a/tests/test_geophires_x.py b/tests/test_geophires_x.py index 75a4ae6a..50a1f7d4 100644 --- a/tests/test_geophires_x.py +++ b/tests/test_geophires_x.py @@ -595,3 +595,55 @@ def test_transmission_pipeline_cost(self): self.assertAlmostEqual( result.result['CAPITAL COSTS (M$)']['Transmission pipeline cost']['value'], 3.75, delta=0.5 ) + + def test_well_drilling_and_completion_capital_cost_adjustment_factor(self): + base_file = self._get_test_file_path('drilling-adjustment-factor.txt') + r_no_adj = GeophiresXClient().get_geophires_result(GeophiresInputParameters(from_file_path=base_file)) + + r_noop_adj = GeophiresXClient().get_geophires_result( + GeophiresInputParameters( + from_file_path=base_file, + params={'Well Drilling and Completion Capital Cost Adjustment Factor': 1.0}, + ) + ) + + r_adj = GeophiresXClient().get_geophires_result( + GeophiresInputParameters( + from_file_path=base_file, + params={'Well Drilling and Completion Capital Cost Adjustment Factor': 1.175}, + ) + ) + + def c_well(r, prod: bool = False, inj: bool = False): + well_type = 'production ' if prod else 'injection ' if inj else '' + try: + c = r.result['CAPITAL COSTS (M$)'][f'Drilling and completion costs per {well_type}well']['value'] + + if not prod and not inj: + # indirect cost is not applied to prod/inj-specific per-well cost + default_indirect_cost_factor = 1.05 + c = c / default_indirect_cost_factor + + return c + except TypeError: + return None + + self.assertEqual(c_well(r_no_adj), c_well(r_noop_adj)) + + self.assertAlmostEqual(1.175 * c_well(r_no_adj), c_well(r_adj), delta=0.1) + + r_adj_diff_prod_inj = GeophiresXClient().get_geophires_result( + GeophiresInputParameters( + from_file_path=base_file, + params={ + 'Well Drilling and Completion Capital Cost Adjustment Factor': 1.175, + 'Injection Well Drilling and Completion Capital Cost Adjustment Factor': 3, + }, + ) + ) + + c_well_no_adj = c_well(r_no_adj) + c_prod_well_adj = c_well(r_adj_diff_prod_inj, prod=True) + c_inj_well_adj = c_well(r_adj_diff_prod_inj, inj=True) + self.assertAlmostEqual(1.175 * c_well_no_adj, c_prod_well_adj, delta=0.1) + self.assertAlmostEqual(3 * c_well_no_adj, c_inj_well_adj, delta=0.1) From d32dc6f91c941c122f7d2adb1363675b36d6c50b Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:03:55 -0800 Subject: [PATCH 05/13] move test input file to geophires_x_tests/ to reduce clutter --- tests/{ => geophires_x_tests}/drilling-adjustment-factor.txt | 0 tests/test_geophires_x.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{ => geophires_x_tests}/drilling-adjustment-factor.txt (100%) diff --git a/tests/drilling-adjustment-factor.txt b/tests/geophires_x_tests/drilling-adjustment-factor.txt similarity index 100% rename from tests/drilling-adjustment-factor.txt rename to tests/geophires_x_tests/drilling-adjustment-factor.txt diff --git a/tests/test_geophires_x.py b/tests/test_geophires_x.py index 50a1f7d4..9cfdb5cc 100644 --- a/tests/test_geophires_x.py +++ b/tests/test_geophires_x.py @@ -597,7 +597,7 @@ def test_transmission_pipeline_cost(self): ) def test_well_drilling_and_completion_capital_cost_adjustment_factor(self): - base_file = self._get_test_file_path('drilling-adjustment-factor.txt') + base_file = self._get_test_file_path('geophires_x_tests/drilling-adjustment-factor.txt') r_no_adj = GeophiresXClient().get_geophires_result(GeophiresInputParameters(from_file_path=base_file)) r_noop_adj = GeophiresXClient().get_geophires_result( From 83c5c79ce218f7a2090aac87761eaa91418c094b Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:06:26 -0800 Subject: [PATCH 06/13] clean up input file comments --- tests/geophires_x_tests/drilling-adjustment-factor.txt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/geophires_x_tests/drilling-adjustment-factor.txt b/tests/geophires_x_tests/drilling-adjustment-factor.txt index d7c6b1d9..80f50240 100644 --- a/tests/geophires_x_tests/drilling-adjustment-factor.txt +++ b/tests/geophires_x_tests/drilling-adjustment-factor.txt @@ -1,7 +1,6 @@ Reservoir Model, 1 Reservoir Volume Option, 1 Reservoir Density, 2800 -#Reservoir Depth, 8500 feet, -- https://pangea.stanford.edu/ERE/db/GeoConf/papers/SGW/2024/Fercho.pdf Reservoir Heat Capacity, 790 Reservoir Thermal Conductivity, 3.05 Reservoir Porosity, 0.0118 @@ -21,7 +20,6 @@ Well Separation, 365 feet Injection Temperature, 60 degC Injection Wellbore Temperature Gain, 3 Plant Outlet Pressure, 1000 psi -#Production Wellhead Pressure, 325 psi Ramey Production Wellbore Model, 1 Utilization Factor, .9 Water Loss Fraction, 0.05 @@ -32,11 +30,8 @@ End-Use Option, 1 Plant Lifetime, 25 -#Power Plant Type, 3 Circulation Pump Efficiency, 0.80 -#Exploration Capital Cost, 30 -#Reservoir Stimulation Capital Cost, 234, -- 78 wells @ $3M/well Economic Model, 3 Starting Electricity Sale Price, 0.15 Ending Electricity Sale Price, 1.00 @@ -62,7 +57,6 @@ Reservoir Depth, 5.4 Gradient 1, 36.7 Power Plant Type, 4 -# Well Drilling and Completion Capital Cost Adjustment Factor, 1.175 -Number of Injection Wells, 73 -Number of Production Wells, 73 +Number of Injection Wells, 54 +Number of Production Wells, 54 Production Flow Rate per Well, 80 From 51864317876c8b5a46014dfccf55a7e2e7254a36 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:20:40 -0800 Subject: [PATCH 07/13] Fix formatting issue with Surface Temperature tooltip --- src/geophires_x/Reservoir.py | 4 ++-- src/geophires_x_schema_generator/geophires-request.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/geophires_x/Reservoir.py b/src/geophires_x/Reservoir.py index 8c33b4e7..841e4546 100644 --- a/src/geophires_x/Reservoir.py +++ b/src/geophires_x/Reservoir.py @@ -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 diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index 395fa8d6..85d3dc29 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -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", From fc5bd8ed6344079e4bc4b992020972a1d52f9229 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:20:40 -0800 Subject: [PATCH 08/13] Fix formatting issue with Surface Temperature tooltip --- src/geophires_x/Reservoir.py | 4 ++-- src/geophires_x_schema_generator/geophires-request.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/geophires_x/Reservoir.py b/src/geophires_x/Reservoir.py index 8c33b4e7..841e4546 100644 --- a/src/geophires_x/Reservoir.py +++ b/src/geophires_x/Reservoir.py @@ -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 diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index 395fa8d6..85d3dc29 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -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", From 8d12bd87df83472b81ca7d9b89d14f492f8bcbbc Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:28:02 -0800 Subject: [PATCH 09/13] Set injection adjustment factor default/min/max from production adjustment default/min/max --- src/geophires_x/Economics.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index ea205617..0cfff1e7 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -661,9 +661,9 @@ def __init__(self, model: Model): ) 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, + 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, From 23800d04b7b200f994568fc333fb7364bdfd3879 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:46:37 -0800 Subject: [PATCH 10/13] Document adjustment factors relationship in tooltip text --- src/geophires_x/Economics.py | 12 +++++++++--- .../geophires-request.json | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index 0cfff1e7..a94832a0 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -647,6 +647,8 @@ def __init__(self, model: Model): Valid=False, ToolTipText="Injection Well Drilling and Completion Capital Cost" ) + + 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, @@ -657,10 +659,12 @@ 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", + 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, @@ -669,7 +673,9 @@ def __init__(self, model: Model): 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", diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index 85d3dc29..f660ae1f 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -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", @@ -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", From 6863b64da7e11ea63fc23ace963a34bd83ad46fe Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:56:24 -0800 Subject: [PATCH 11/13] TODO re: parameterizing/documenting default 5% indirect cost factor --- src/geophires_x/Economics.py | 4 +++- tests/test_geophires_x.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index a94832a0..adffbf6c 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -648,6 +648,8 @@ def __init__(self, model: Model): 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", @@ -2294,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) diff --git a/tests/test_geophires_x.py b/tests/test_geophires_x.py index 9cfdb5cc..adec0984 100644 --- a/tests/test_geophires_x.py +++ b/tests/test_geophires_x.py @@ -620,7 +620,8 @@ def c_well(r, prod: bool = False, inj: bool = False): c = r.result['CAPITAL COSTS (M$)'][f'Drilling and completion costs per {well_type}well']['value'] if not prod and not inj: - # indirect cost is not applied to prod/inj-specific per-well cost + # indirect cost is not applied to prod/inj-specific per-well cost; + # see TODO re:parameterizing at src/geophires_x/Economics.py:652 default_indirect_cost_factor = 1.05 c = c / default_indirect_cost_factor From 3e0d75f773658c36697f89188ad001eda9b725d7 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:56:59 -0800 Subject: [PATCH 12/13] =?UTF-8?q?Bump=20version:=203.7.4=20=E2=86=92=203.7?= =?UTF-8?q?.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- .cookiecutterrc | 2 +- README.rst | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- src/geophires_x/__init__.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 48d46dbb..2f2c0523 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.7.4 +current_version = 3.7.5 commit = True tag = True diff --git a/.cookiecutterrc b/.cookiecutterrc index f51d38f2..363e0c23 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -54,7 +54,7 @@ default_context: sphinx_doctest: "no" sphinx_theme: "sphinx-py3doc-enhanced-theme" test_matrix_separate_coverage: "no" - version: 3.7.4 + version: 3.7.5 version_manager: "bump2version" website: "https://github.com/NREL" year_from: "2023" diff --git a/README.rst b/README.rst index 5fab975d..76623fa9 100644 --- a/README.rst +++ b/README.rst @@ -56,9 +56,9 @@ Free software: `MIT 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.4.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.4...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 diff --git a/docs/conf.py b/docs/conf.py index 16a44381..ec55fbf7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ year = '2025' author = 'NREL' copyright = f'{year}, {author}' -version = release = '3.7.4' +version = release = '3.7.5' pygments_style = 'trac' templates_path = ['./templates'] diff --git a/setup.py b/setup.py index 7edb0a24..a8be14de 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(*names, **kwargs): setup( name='geophires-x', - version='3.7.4', + version='3.7.5', license='MIT', description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.', long_description='{}\n{}'.format( diff --git a/src/geophires_x/__init__.py b/src/geophires_x/__init__.py index e604a8e1..68a57138 100644 --- a/src/geophires_x/__init__.py +++ b/src/geophires_x/__init__.py @@ -1 +1 @@ -__version__ = '3.7.4' +__version__ = '3.7.5' From 460f8fca351a9356b04322b23a8bb52cbe677144 Mon Sep 17 00:00:00 2001 From: softwareengineerprogrammer <4056124+softwareengineerprogrammer@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:59:42 -0800 Subject: [PATCH 13/13] changelog entry for 3.7.5 syncing well cost adjustment factors --- CHANGELOG.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 418a4002..494f8355 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 ^^^