diff --git a/.gitignore b/.gitignore index 5ccd7a2b2..7cf1ec9e6 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ nosetests.xml *.iml *.komodoproject .idea +.junie .project .pydevproject .vscode @@ -124,6 +125,9 @@ src/geophires_docs/fervo_project_red-2026_graph-data-extraction.xcf /Useful sites for Sphinx docstrings.txt /.github/workflows/workflows.7z tmp.patch +project-structure.txt +geophires-aliases.sh +*message.txt # Mypy Cache .mypy_cache/ diff --git a/README.rst b/README.rst index 26ec2530e..5a4df29d8 100644 --- a/README.rst +++ b/README.rst @@ -384,6 +384,10 @@ Example-specific web interface deeplinks are listed in the Link column. - `example_SAM-single-owner-PPA-9_cooling.txt `__ - `.out `__ - `link `__ + * - SAM Single Owner PPA: S-DAC + - `S-DAC-GT-2.txt `__ + - `.out `__ + - `link `__ .. raw:: html diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index 071733c43..fd502b0b7 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -2901,6 +2901,18 @@ def Calculate(self, model: Model) -> None: if self.DoSDACGTCalculations.value: model.sdacgteconomics.Calculate(model) + # Consolidate S-DAC-GT CAPEX and OPEX into the main plant ledgers + max_carbon_capacity_tonnes = np.max(model.sdacgteconomics.CarbonExtractedAnnually.value) + sdac_overnight_capex_musd = ( + model.sdacgteconomics.CAPEX.value * model.sdacgteconomics.CAPEX_mult.value * max_carbon_capacity_tonnes) / 1_000_000.0 + self.CCap.value += sdac_overnight_capex_musd + + avg_carbon_extracted_tonnes = np.average(model.sdacgteconomics.CarbonExtractedAnnually.value) + sdac_annual_opex_musd = (( + model.sdacgteconomics.OPEX.value + model.sdacgteconomics.storage.value + model.sdacgteconomics.transport.value) + * avg_carbon_extracted_tonnes) / 1_000_000.0 + self.Coam.value += sdac_annual_opex_musd + self.calculate_cashflow(model) # Calculate more financial values using numpy financials @@ -3723,6 +3735,13 @@ def calculate_cashflow(self, model: Model) -> None: self.TotalRevenue.value[i] = self.TotalRevenue.value[i] + self.CarbonRevenue.value[i] #self.TotalCummRevenue.value[i] = self.TotalCummRevenue.value[i] + self.CarbonCummCashFlow.value[i] + if self.DoSDACGTCalculations.value: + for i in range(model.surfaceplant.construction_years.value, + model.surfaceplant.plant_lifetime.value + model.surfaceplant.construction_years.value, + 1): + sdac_index = i - model.surfaceplant.construction_years.value + self.TotalRevenue.value[i] += (model.sdacgteconomics.CarbonRevenue.value[sdac_index] / 1_000_000.0) + # for the sake of display, insert zeros at the beginning of the pricing arrays for i in range(0, model.surfaceplant.construction_years.value, 1): self.ElecPrice.value.insert(0, 0.0) diff --git a/src/geophires_x/EconomicsS_DAC_GT.py b/src/geophires_x/EconomicsS_DAC_GT.py index 78cf9a5c1..2e4371786 100644 --- a/src/geophires_x/EconomicsS_DAC_GT.py +++ b/src/geophires_x/EconomicsS_DAC_GT.py @@ -219,6 +219,31 @@ def __init__(self, model: Model): ErrMessage="assume default Percent Energy Devoted To Process (50%)", ToolTipText="Percent Energy Devoted To Process (%)" ) + self.carbon_credit_price = self.ParameterDict[self.carbon_credit_price.Name] = floatParameter( + "S-DAC-GT Carbon Credit Price", + value=180.0, + DefaultValue=180.0, + Min=0.0, + Max=1000.0, + UnitType=Units.COSTPERMASS, + PreferredUnits=CostPerMassUnit.DOLLARSPERTONNE, + CurrentUnits=CostPerMassUnit.DOLLARSPERTONNE, + ErrMessage="assume default Carbon Credit Price (180 USD per tonne CO2)", + ToolTipText="Carbon Credit or Market Price (USD per tonne CO2)" + ) + + self.carbon_credit_duration = self.ParameterDict[self.carbon_credit_duration.Name] = floatParameter( + "S-DAC-GT Carbon Credit Duration", + value=12.0, + DefaultValue=12.0, + Min=0.0, + Max=100.0, + UnitType=Units.TIME, + PreferredUnits=TimeUnit.YEAR, + CurrentUnits=TimeUnit.YEAR, + ErrMessage="assume default Carbon Credit Duration (12 years)", + ToolTipText="Duration for which the carbon credit can be claimed (e.g., 12 years for US 45Q)" + ) # local variable initiation # Capital Recovery Rate or Fixed Charge Factor - set initially for definitions @@ -335,6 +360,21 @@ def __init__(self, model: Model): PreferredUnits=CostPerMassUnit.DOLLARSPERTONNE, CurrentUnits=CostPerMassUnit.DOLLARSPERTONNE ) + self.CarbonRevenue = OutputParameter( + Name="Annual Carbon Revenue", + UnitType=Units.CURRENCYFREQUENCY, + PreferredUnits=CurrencyFrequencyUnit.DOLLARSPERYEAR, + CurrentUnits=CurrencyFrequencyUnit.DOLLARSPERYEAR + ) + self.OutputParameterDict[self.CarbonRevenue.Name] = self.CarbonRevenue + + self.CarbonCummCashFlow = OutputParameter( + Name="Cumulative Carbon Revenue", + UnitType=Units.CURRENCY, + PreferredUnits=CurrencyUnit.DOLLARS, + CurrentUnits=CurrencyUnit.DOLLARS + ) + self.OutputParameterDict[self.CarbonCummCashFlow.Name] = self.CarbonCummCashFlow model.logger.info(f"Complete {str(__class__)}: {sys._getframe().f_code.co_name}") @@ -483,6 +523,13 @@ def range_check(self) -> tuple: storage_max) return True, error_message + if not (self.carbon_credit_duration.Min + <= self.carbon_credit_duration.value + <= self.carbon_credit_duration.Max): + error_message = "S-DAC-GT ERROR: Carbon Credit Duration should be between {} and {}".format( + self.carbon_credit_duration.Min, self.carbon_credit_duration.Max) + return True, error_message + return False, "" def geo_therm_cost(self, power_cost: float, CAPEX_mult: float, OPEX_mult: float, depth: float, @@ -599,12 +646,13 @@ def Calculate(self, model: Model) -> None: # Convert from $/McF to $/kWh_th, but don't change any parameters value directly - it will throw off the rehydration NG_price = self.NG_price.value / self.NG_EnergyDensity.value NG_totalcost = self.therm.value * NG_price - self.LCOH.value, self.kWh_e_per_kWh_th.value = self.geo_therm_cost(model.surfaceplant.electricity_cost_to_buy.value, - self.CAPEX_mult.value, self.OPEX_mult.value, - model.reserv.depth.value * 3280.84, - np.average(model.wellbores.ProducedTemperature.value), - model.wellbores.Tinj.value, - model.wellbores.nprod.value * model.wellbores.prodwellflowrate.value) + self.LCOH.value, self.kWh_e_per_kWh_th.value = self.geo_therm_cost( + model.surfaceplant.electricity_cost_to_buy.value, + self.CAPEX_mult.value, self.OPEX_mult.value, + model.reserv.depth.value * 3280.84, + np.average(model.wellbores.ProducedTemperature.value), + model.wellbores.Tinj.value, + model.wellbores.nprod.value * model.wellbores.prodwellflowrate.value) geothermal_totalcost = self.LCOH.value * self.therm.value co2_power = self.elec.value / 1000 * self.power_co2intensity.value co2_elec_heat = self.therm.value / 1000 * self.power_co2intensity.value @@ -621,7 +669,8 @@ def Calculate(self, model: Model) -> None: # calculate the net impact of S-DAC-GT on the annual production of the model avg_first_law_eff = np.average(model.surfaceplant.FirstLawEfficiency.value) - self.tot_heat_energy_consumed_per_tonne.value = (self.elec.value / avg_first_law_eff) + self.therm.value # kWh_th/tonne + self.tot_heat_energy_consumed_per_tonne.value = ( + self.elec.value / avg_first_law_eff) + self.therm.value # kWh_th/tonne self.tot_cost_per_tonne.value = CAPEX + self.OPEX.value + self.storage.value + self.transport.value # USD/tonne self.percent_thermal_energy_going_to_heat.value = self.therm.value / self.tot_heat_energy_consumed_per_tonne.value @@ -637,18 +686,22 @@ def Calculate(self, model: Model) -> None: # That then gives us the revenue, since we have a carbon price model # We can also get annual cash flow from it. for i in range(0, model.surfaceplant.plant_lifetime.value, 1): - self.CarbonExtractedAnnually.value[i] = (self.EnergySplit.value * model.surfaceplant.HeatkWhExtracted.value[i]) / self.tot_heat_energy_consumed_per_tonne.value + self.CarbonExtractedAnnually.value[i] = (self.EnergySplit.value * model.surfaceplant.HeatkWhExtracted.value[ + i]) / self.tot_heat_energy_consumed_per_tonne.value if i == 0: self.S_DAC_GTCummCarbonExtracted.value[i] = self.CarbonExtractedAnnually.value[i] else: - self.S_DAC_GTCummCarbonExtracted.value[i] = self.S_DAC_GTCummCarbonExtracted.value[i - 1] + self.CarbonExtractedAnnually.value[i] + self.S_DAC_GTCummCarbonExtracted.value[i] = self.S_DAC_GTCummCarbonExtracted.value[i - 1] + \ + self.CarbonExtractedAnnually.value[i] self.CarbonExtractedTotal.value = self.CarbonExtractedTotal.value + self.CarbonExtractedAnnually.value[i] self.S_DAC_GTAnnualCost.value[i] = self.CarbonExtractedAnnually.value[i] * self.tot_cost_per_tonne.value if i == 0: self.S_DAC_GTCummCashFlow.value[i] = self.S_DAC_GTAnnualCost.value[i] else: - self.S_DAC_GTCummCashFlow.value[i] = self.S_DAC_GTCummCashFlow.value[i - 1] + self.S_DAC_GTAnnualCost.value[i] - self.CummCostPerTonne.value[i] = self.S_DAC_GTCummCashFlow.value[i] / self.S_DAC_GTCummCarbonExtracted.value[i] + self.S_DAC_GTCummCashFlow.value[i] = self.S_DAC_GTCummCashFlow.value[i - 1] + \ + self.S_DAC_GTAnnualCost.value[i] + self.CummCostPerTonne.value[i] = self.S_DAC_GTCummCashFlow.value[i] / \ + self.S_DAC_GTCummCarbonExtracted.value[i] # We need to update the heat and electricity generated because we have consumed # some (all) of it to do the capture, so when they get used in the final economic calculation (below), @@ -657,28 +710,31 @@ def Calculate(self, model: Model) -> None: if model.surfaceplant.enduse_option.value is not EndUseOptions.HEAT: # all these end-use options have an electricity generation component model.surfaceplant.TotalkWhProduced.value[i] = model.surfaceplant.TotalkWhProduced.value[i] - ( - self.CarbonExtractedAnnually.value[i] * self.elec.value) + self.CarbonExtractedAnnually.value[i] * self.elec.value) model.surfaceplant.NetkWhProduced.value[i] = model.surfaceplant.NetkWhProduced.value[i] - ( - self.CarbonExtractedAnnually.value[i] * self.elec.value) + self.CarbonExtractedAnnually.value[i] * self.elec.value) if model.surfaceplant.enduse_option.value is not EndUseOptions.ELECTRICITY: model.surfaceplant.HeatkWhProduced.value[i] = model.surfaceplant.HeatkWhProduced.value[i] - ( - self.CarbonExtractedAnnually.value[i] * self.therm.value) + self.CarbonExtractedAnnually.value[i] * self.therm.value) else: # all the end-use option of direct-use only component model.surfaceplant.HeatkWhProduced.value[i] = (model.surfaceplant.HeatkWhProduced.value[i] - - (self.CarbonExtractedAnnually.value[i] * self.therm.value)) - - # FIXME TODO https://github.com/NREL/GEOPHIRES-X/issues/341?title=S-DAC+does+not+calculate+carbon+revenue - # Build a revenue generation model for the carbon capture, assuming the capture is being sequestered and that - # there is some sort of credit involved for doing that sequestering - # note that there may already be values in the CarbonRevenue array, so we need to - # add to them, not just set them. If there isn't values, there, the array will be filed with zeros, so adding won't be a problem - #total_duration = model.surfaceplant.plant_lifetime.value - #for i in range(0, total_duration, 1): - # model.sdacgteconomics.CarbonRevenue.value[i] = (model.sdacgteconomics.CarbonRevenue.value[i] + - # (self.CarbonExtractedAnnually.value[i] * model.economics.CarbonPrice.value[i])) - # if i > 0: - # model.economics.CarbonCummCashFlow.value[i] = model.economics.CarbonCummCashFlow.value[i - 1] + model.economics.CarbonRevenue.value[i] + (self.CarbonExtractedAnnually.value[ + i] * self.therm.value)) + + # Calculate Carbon Revenue based on S-DAC-GT specific credit price and duration + self.CarbonRevenue.value = [0.0] * model.surfaceplant.plant_lifetime.value + self.CarbonCummCashFlow.value = [0.0] * model.surfaceplant.plant_lifetime.value + + for i in range(0, model.surfaceplant.plant_lifetime.value, 1): + # Enforce the parameterized statutory limit for tax credits + applicable_price = self.carbon_credit_price.value if i < self.carbon_credit_duration.value else 0.0 + self.CarbonRevenue.value[i] = self.CarbonExtractedAnnually.value[i] * applicable_price + if i == 0: + self.CarbonCummCashFlow.value[i] = self.CarbonRevenue.value[i] + else: + self.CarbonCummCashFlow.value[i] = self.CarbonCummCashFlow.value[i - 1] + \ + self.CarbonRevenue.value[i] self._calculate_derived_outputs(model) - model.logger.info(f'Complete {str(__class__)}: {sys._getframe().f_code.co_name}') + model.logger.info(f'Complete {str(__class__)}: {sys._getframe().f_code.co_name}') \ No newline at end of file diff --git a/src/geophires_x/EconomicsSam.py b/src/geophires_x/EconomicsSam.py index aca41ff19..daac092d5 100644 --- a/src/geophires_x/EconomicsSam.py +++ b/src/geophires_x/EconomicsSam.py @@ -678,15 +678,59 @@ def _get_single_owner_parameters(model: Model) -> dict[str, Any]: ret['federal_tax_rate'], ret['state_tax_rate'] = _get_fed_and_state_tax_rates(econ.CTR.value) geophires_itc_tenths = Decimal(econ.RITC.value) - ret['itc_fed_percent'] = [float(geophires_itc_tenths * Decimal(100))] - if econ.PTCElec.Provided: - ret['ptc_fed_amount'] = [econ.PTCElec.quantity().to(convertible_unit('USD/kWh')).magnitude] + if econ.DoSDACGTCalculations.value and geophires_itc_tenths > 0: + # Shield DAC CAPEX from ITC to prevent unlawful MACRS basis reduction + max_carbon_capacity_tonnes = max(model.sdacgteconomics.CarbonExtractedAnnually.value) + sdac_capex_usd = ( + model.sdacgteconomics.CAPEX.value * model.sdacgteconomics.CAPEX_mult.value * max_carbon_capacity_tonnes + ) + + # Geothermal eligible basis = Total Installed Cost - DAC CAPEX + eligible_geothermal_basis_usd = ret['total_installed_cost'] - sdac_capex_usd + itc_fed_amount_usd = float(Decimal(eligible_geothermal_basis_usd) * geophires_itc_tenths) - ret['ptc_fed_term'] = econ.PTCDuration.quantity().to(convertible_unit('yr')).magnitude + ret['itc_fed_percent'] = [0.0] # Disable percentage-based ITC on the whole project + ret['itc_fed_amount'] = [itc_fed_amount_usd] # Inject fixed ITC amount for geothermal only + else: + ret['itc_fed_percent'] = [float(geophires_itc_tenths * Decimal(100))] + + # Build a year-by-year schedule for the Federal Production Tax Credit + ptc_fed_amount_schedule = [0.0] * model.surfaceplant.plant_lifetime.value - if econ.PTCInflationAdjusted.value: - ret['ptc_fed_escal'] = _pct(econ.RINFL) + # 1. Base Electricity PTC + if econ.PTCElec.Provided: + base_ptc_rate = econ.PTCElec.quantity().to(convertible_unit('USD/kWh')).magnitude + ptc_term = int(econ.PTCDuration.quantity().to(convertible_unit('yr')).magnitude) + for i in range(min(ptc_term, model.surfaceplant.plant_lifetime.value)): + escalation = (1.0 + _pct(econ.RINFL) / 100.0) ** i if econ.PTCInflationAdjusted.value else 1.0 + ptc_fed_amount_schedule[i] = base_ptc_rate * escalation + + # 2. S-DAC 45Q Equivalent (Mapped as Non-Taxable PBI to avoid MACRS/Exclusivity issues) + if econ.DoSDACGTCalculations.value: + pbi_oth_amount_schedule = [0.0] * model.surfaceplant.plant_lifetime.value + + for i in range(model.surfaceplant.plant_lifetime.value): + # The statutory duration cutoff (e.g., 12 years) is already handled inside EconomicsS_DAC_GT.py + # so CarbonRevenue will naturally be 0.0 for years > 12. + sdac_revenue_usd = model.sdacgteconomics.CarbonRevenue.value[i] + net_kwh_produced = model.surfaceplant.NetkWhProduced.value[i] + + # Convert absolute S-DAC revenue (USD) into an equivalent USD/kWh PBI rate for SAM + if net_kwh_produced > 0: + pbi_oth_amount_schedule[i] = sdac_revenue_usd / net_kwh_produced + + if any(rate > 0.0 for rate in pbi_oth_amount_schedule): + ret['pbi_oth_amount'] = pbi_oth_amount_schedule + ret['pbi_oth_term'] = model.surfaceplant.plant_lifetime.value + ret['pbi_oth_tax_fed'] = 0.0 # Strictly exclude from Federal taxable gross income + ret['pbi_oth_tax_sta'] = 0.0 # Strictly exclude from State taxable gross income + + # Inject the combined array into SAM + if any(rate > 0.0 for rate in ptc_fed_amount_schedule): + ret['ptc_fed_amount'] = ptc_fed_amount_schedule + ret['ptc_fed_term'] = model.surfaceplant.plant_lifetime.value + ret['ptc_fed_escal'] = 0.0 # Escalation is already manually calculated in the array above # 'Property Tax Rate' geophires_ptr_tenths = Decimal(econ.PTR.value) diff --git a/src/geophires_x/OutputsS_DAC_GT.py b/src/geophires_x/OutputsS_DAC_GT.py index ba2838587..b12fef9c7 100644 --- a/src/geophires_x/OutputsS_DAC_GT.py +++ b/src/geophires_x/OutputsS_DAC_GT.py @@ -81,21 +81,26 @@ def PrintOutputs(self, model) -> tuple: model.sdacgteconomics.S_DAC_GTCummCashFlow.value sdac_df[f'Cum. Cost Per Tonne ({model.sdacgteconomics.CummCostPerTonne.PreferredUnits.value})|:,.2f'] = \ model.sdacgteconomics.CummCostPerTonne.value + sdac_df[f'Carbon Revenue ({model.sdacgteconomics.CarbonRevenue.PreferredUnits.value})|:,.2f'] = \ + model.sdacgteconomics.CarbonRevenue.value + sdac_df[f'Cum. Carbon Revenue ({model.sdacgteconomics.CarbonCummCashFlow.PreferredUnits.value})|:,.2f'] = \ + model.sdacgteconomics.CarbonCummCashFlow.value f.write(NL) f.write(" **********************" + NL) f.write(" * S-DAC-GT PROFILE *" + NL) f.write(" **********************" + NL) - f.write("Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost" + NL) - f.write("Since Captured Captured Annual Cost Cash Flow Cost Per Tonne" + NL) + f.write("Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost Annual Carbon" + NL) + f.write("Since Captured Captured Annual Cost Cash Flow Cost Per Tonne Revenue" + NL) f.write("Start ("+model.sdacgteconomics.CarbonExtractedAnnually.PreferredUnits.value + ") ("+model.sdacgteconomics.S_DAC_GTCummCarbonExtracted.PreferredUnits.value + ") ("+model.sdacgteconomics.S_DAC_GTAnnualCost.PreferredUnits.value + ") ("+model.sdacgteconomics.S_DAC_GTCummCashFlow.PreferredUnits.value + - ") ("+model.sdacgteconomics.CummCostPerTonne.PreferredUnits.value + ")" +NL) + ") ("+model.sdacgteconomics.CummCostPerTonne.PreferredUnits.value + + ") (" + model.sdacgteconomics.CarbonRevenue.PreferredUnits.value + ")" + NL) i = 0 for i in range(0, model.surfaceplant.plant_lifetime.value, 1): - f.write(f" {i+1:3.0f} {model.sdacgteconomics.CarbonExtractedAnnually.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTCummCarbonExtracted.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTAnnualCost.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTCummCashFlow.value[i]:,.2f} {model.sdacgteconomics.CummCostPerTonne.value[i]:.2f}" + NL) + f.write(f" {i+1:3.0f} {model.sdacgteconomics.CarbonExtractedAnnually.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTCummCarbonExtracted.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTAnnualCost.value[i]:,.2f} {model.sdacgteconomics.S_DAC_GTCummCashFlow.value[i]:,.2f} {model.sdacgteconomics.CummCostPerTonne.value[i]:.2f} {model.sdacgteconomics.CarbonRevenue.value[i]:,.2f}" + NL) i = i + 1 except BaseException as ex: @@ -106,9 +111,9 @@ def PrintOutputs(self, model) -> tuple: print(msg) model.logger.critical(str(ex)) model.logger.critical(msg) - raise RuntimeError(msg, e) + raise RuntimeError(msg, ex) model.logger.info(f'Complete {str(__class__)}: {__name__}') sdac_df = sdac_df.reset_index() - return sdac_df, sdac_results + return sdac_df, sdac_results \ No newline at end of file diff --git a/src/geophires_x_client/geophires_x_result.py b/src/geophires_x_client/geophires_x_result.py index 7ed141cc5..e139d3ba3 100644 --- a/src/geophires_x_client/geophires_x_result.py +++ b/src/geophires_x_client/geophires_x_result.py @@ -804,6 +804,7 @@ def extract_table_header(lines: list) -> list: 'S-DAC-GT Annual Cost (USD/yr)', 'S-DAC-GT Cumm. Cash Flow (USD)', 'Cumm. Cost Per Tonne (USD/tonne)', + 'Annual Carbon Revenue (USD/yr)', ] try: diff --git a/src/geophires_x_schema_generator/.gitignore b/src/geophires_x_schema_generator/.gitignore index e739df7bb..87fa87203 100644 --- a/src/geophires_x_schema_generator/.gitignore +++ b/src/geophires_x_schema_generator/.gitignore @@ -3,3 +3,4 @@ all_messages_conf.log !geophires-request.json !geophires-result.json !hip-ra-x-request.json +!hip-ra-x-reult.json diff --git a/src/geophires_x_schema_generator/__init__.py b/src/geophires_x_schema_generator/__init__.py index 1342f822a..1471fd469 100644 --- a/src/geophires_x_schema_generator/__init__.py +++ b/src/geophires_x_schema_generator/__init__.py @@ -1,8 +1,10 @@ +from __future__ import annotations + import json import os import sys from pathlib import Path -from typing import Tuple, Any +from typing import Any, Callable # Ruff disabled because imports are order-dependent # ruff: noqa: I001 @@ -38,7 +40,8 @@ class GeophiresXSchemaGenerator: def __init__(self): - pass + # noinspection PyProtectedMember + self.result_fields_by_category: dict[str, list[Any]] = GeophiresXResult._RESULT_FIELDS_BY_CATEGORY @staticmethod def _get_dummy_model(): @@ -85,7 +88,7 @@ def get_parameter_sources(self) -> list: def get_schema_title(self) -> str: return 'GEOPHIRES' - def get_parameters_json(self) -> Tuple[str, str]: + def get_parameters_json(self) -> tuple[str, str]: def with_category(param_dict: dict, category: str): def _with_cat(p: Parameter, cat: str): @@ -103,7 +106,7 @@ def _with_cat(p: Parameter, cat: str): return json_dumpse(input_params), json_dumpse(output_params) - def generate_json_schema(self) -> Tuple[dict, dict]: + def generate_json_schema(self) -> tuple[dict, dict]: """ :return: request schema, result schema :rtype: Tuple[dict, dict] @@ -153,6 +156,10 @@ def get_result_json_schema(self, output_params_json) -> dict: properties = {} required = [] + # if result_fields_by_category is None: + # # noinspection PyProtectedMember + # result_fields_by_category = GeophiresXResult._RESULT_FIELDS_BY_CATEGORY + output_params = json.loads(output_params_json) display_name_aliases = {} for param_name in output_params: @@ -165,11 +172,10 @@ def get_result_json_schema(self, output_params_json) -> dict: output_params = {**output_params, **display_name_aliases} - # noinspection PyProtectedMember - for category in GeophiresXResult._RESULT_FIELDS_BY_CATEGORY: + for category in self.result_fields_by_category: cat_properties = {} - # noinspection PyProtectedMember - for field in GeophiresXResult._RESULT_FIELDS_BY_CATEGORY[category]: + + for field in self.result_fields_by_category[category]: param_name = field if isinstance(field, str) else field.field_name ignored_output_param_names = ['After-Tax IRR'] # Silently ignored in favor of "After-tax IRR" @@ -357,7 +363,7 @@ def _get_key(param: dict, k: str, default_val='') -> Any: return default_val -def _get_min_and_max(param: dict, default_val='') -> Tuple: +def _get_min_and_max(param: dict, default_val='') -> tuple: min_val = _get_key(param, 'Min', default_val=default_val) max_val = _get_key(param, 'Max', default_val=default_val) @@ -377,8 +383,30 @@ def _fix_floating_point_error(val: Any) -> Any: class HipRaXSchemaGenerator(GeophiresXSchemaGenerator): + + def __init__(self): + dummy_model = HIP_RA_X() + + def _get_result_fields_for_category( + output_config: list[tuple[Parameter, Callable[[Parameter], str]]], + ) -> list[Any]: + return [it[0].Name for it in output_config] + + # noinspection PyProtectedMember + self.result_fields_by_category: dict[str, list[Any]] = { + HIP_RA_X._SUMMARY_OF_RESULTS_OUTPUT_CATEGORY: _get_result_fields_for_category( + dummy_model._get_output_config_for_summary_of_results_category(None, None) + ), + HIP_RA_X._SUMMARY_OF_INPUTS_OUTPUT_CATEGORY: _get_result_fields_for_category( + dummy_model._get_output_config_for_summary_of_inputs_category(None, None) + ), + } + def get_parameter_sources(self) -> list: """ + Single implicit input category used to keep the result schema shape consistent + with the GEOPHIRES result schema (top-level properties -> category -> properties -> fields). + :rtype: list[Tuple[Any, str]] """ dummy_model = HIP_RA_X() @@ -388,7 +416,37 @@ def get_schema_title(self) -> str: return 'HIP-RA-X' def get_result_json_schema(self, output_params_json) -> dict: - return None # FIXME TODO + output_params = json.loads(output_params_json) + + properties = {} + + # noinspection PyProtectedMember + for category in [HIP_RA_X._SUMMARY_OF_RESULTS_OUTPUT_CATEGORY, HIP_RA_X._SUMMARY_OF_INPUTS_OUTPUT_CATEGORY]: + cat_properties = {} + for param_name, output_param in output_params.items(): + description = _get_key(output_param, 'ToolTipText', default_val=None) or None + units_val = output_param['CurrentUnits'] if isinstance(output_param.get('CurrentUnits'), str) else None + cat_properties[param_name] = { + 'type': _get_key(output_param, 'json_parameter_type', default_val=None) or None, + 'description': description, + 'units': units_val, + } + + properties[category] = { + 'type': 'object', + 'properties': cat_properties, + } + + result_schema = { + 'definitions': {}, + '$schema': 'http://json-schema.org/draft-04/schema#', + 'type': 'object', + 'title': f'{self.get_schema_title()} Result Schema', + 'required': [], + 'properties': properties, + } + + return result_schema def get_output_params_table_rst(self, output_params_json) -> str: """ @@ -426,4 +484,4 @@ def get_input_schema_reference(self) -> str: return 'hip-ra-x-request.json' def get_output_schema_reference(self) -> str: - return None + return 'hip-ra-x-result.json' diff --git a/src/geophires_x_schema_generator/hip-ra-x-result.json b/src/geophires_x_schema_generator/hip-ra-x-result.json new file mode 100644 index 000000000..410c933ae --- /dev/null +++ b/src/geophires_x_schema_generator/hip-ra-x-result.json @@ -0,0 +1,369 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "HIP-RA-X Result Schema", + "required": [], + "properties": { + "SUMMARY OF RESULTS": { + "type": "object", + "properties": { + "Reservoir Volume (reservoir)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Reservoir Volume (rock)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Recoverable Volume (recoverable fluid)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Stored Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Stored Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Stored Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Mass of Reservoir (total)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Mass of Reservoir (rock)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Mass of Reservoir (fluid)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Specific Enthalpy (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Specific Enthalpy (rock)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Specific Enthalpy (fluid)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Wellhead Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Wellhead Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Wellhead Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Recovery Factor (reservoir)": { + "type": "number", + "description": null, + "units": "%" + }, + "Recovery Factor (rock)": { + "type": "number", + "description": null, + "units": "%" + }, + "Recovery Factor (fluid)": { + "type": "number", + "description": null, + "units": "%" + }, + "Available Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Available Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Available Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Electricity (reservoir)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Electricity (rock)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Electricity (fluid)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Heat/Unit Area (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Area (rock)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Area (fluid)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Volume (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/km**3" + }, + "Producible Electricity/Unit Area (reservoir)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Area (rock)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Area (fluid)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Volume (reservoir)": { + "type": "number", + "description": null, + "units": "MW/km**3" + } + } + }, + "SUMMARY OF INPUTS": { + "type": "object", + "properties": { + "Reservoir Volume (reservoir)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Reservoir Volume (rock)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Recoverable Volume (recoverable fluid)": { + "type": "number", + "description": null, + "units": "km**3" + }, + "Stored Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Stored Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Stored Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Mass of Reservoir (total)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Mass of Reservoir (rock)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Mass of Reservoir (fluid)": { + "type": "number", + "description": null, + "units": "kilogram" + }, + "Specific Enthalpy (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Specific Enthalpy (rock)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Specific Enthalpy (fluid)": { + "type": "number", + "description": null, + "units": "kJ/kg" + }, + "Wellhead Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Wellhead Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Wellhead Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Recovery Factor (reservoir)": { + "type": "number", + "description": null, + "units": "%" + }, + "Recovery Factor (rock)": { + "type": "number", + "description": null, + "units": "%" + }, + "Recovery Factor (fluid)": { + "type": "number", + "description": null, + "units": "%" + }, + "Available Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Available Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Available Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (reservoir)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (rock)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Heat (fluid)": { + "type": "number", + "description": null, + "units": "kJ" + }, + "Producible Electricity (reservoir)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Electricity (rock)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Electricity (fluid)": { + "type": "number", + "description": null, + "units": "MW" + }, + "Producible Heat/Unit Area (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Area (rock)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Area (fluid)": { + "type": "number", + "description": null, + "units": "kJ/km**2" + }, + "Producible Heat/Unit Volume (reservoir)": { + "type": "number", + "description": null, + "units": "kJ/km**3" + }, + "Producible Electricity/Unit Area (reservoir)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Area (rock)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Area (fluid)": { + "type": "number", + "description": null, + "units": "MW/km**2" + }, + "Producible Electricity/Unit Volume (reservoir)": { + "type": "number", + "description": null, + "units": "MW/km**3" + } + } + } + } +} diff --git a/src/hip_ra_x/__init__.py b/src/hip_ra_x/__init__.py index 1028fd3e7..015c2d907 100644 --- a/src/hip_ra_x/__init__.py +++ b/src/hip_ra_x/__init__.py @@ -6,6 +6,7 @@ from hip_ra import HipRaInputParameters from hip_ra import HipRaResult from hip_ra_x import hip_ra_x +from hip_ra_x.hip_ra_x_result import HipRaXResult class HipRaXClient: @@ -20,9 +21,9 @@ def get_hip_ra_result(self, input_params: HipRaInputParameters) -> HipRaResult: try: hip_ra_x.main(enable_hip_ra_logging_config=False) except Exception as e: - raise RuntimeError(f'HIP-RA encountered an exception: {e!s}') from e + raise RuntimeError(f'HIP-RA-X encountered an exception: {e!s}') from e except SystemExit: - raise RuntimeError('HIP-RA exited without giving a reason') from None + raise RuntimeError('HIP-RA-X exited without giving a reason') from None finally: # Undo HIP-RA internal global settings changes sys.argv = stash_sys_argv @@ -31,3 +32,6 @@ def get_hip_ra_result(self, input_params: HipRaInputParameters) -> HipRaResult: self._logger.info(f'HIP-RA output file: {input_params.output_file_path}') return HipRaResult(input_params.output_file_path) + + def get_hip_ra_x_result(self, input_params: HipRaInputParameters) -> HipRaXResult: + return HipRaXResult.from_hip_ra_result(self.get_hip_ra_result(input_params)) diff --git a/src/hip_ra_x/hip_ra_x.py b/src/hip_ra_x/hip_ra_x.py index ae1ced7b4..c2089213b 100644 --- a/src/hip_ra_x/hip_ra_x.py +++ b/src/hip_ra_x/hip_ra_x.py @@ -6,6 +6,8 @@ import sys import traceback from pathlib import Path +from typing import Callable +from typing import ClassVar import pint from rich.console import Console @@ -79,6 +81,9 @@ class HIP_RA_X: _ureg = pint.get_application_registry() + _SUMMARY_OF_RESULTS_OUTPUT_CATEGORY: ClassVar[str] = 'SUMMARY OF RESULTS' + _SUMMARY_OF_INPUTS_OUTPUT_CATEGORY: ClassVar[str] = 'SUMMARY OF INPUTS' + def __init__(self, enable_hip_ra_logging_config=True): # get logging started self.logger = logging.getLogger('root') @@ -827,66 +832,38 @@ def render_scientific(p: Parameter) -> str: summary_of_inputs = {} summary_of_results = {} - inputs = [ - (self.reservoir_temperature, render_default), - (self.rejection_temperature, render_default), - (self.reservoir_porosity, render_default), - (self.reservoir_area, render_default), - (self.reservoir_thickness, render_default), - (self.reservoir_life_cycle, render_default), - (self.rock_heat_capacity, render_scientific), - (self.fluid_heat_capacity, render_default), - (self.fluid_density, render_scientific), - (self.rock_density, render_scientific), - (self.recoverable_fluid_factor, render_default), - (self.recoverable_rock_heat, render_default), - ] - + inputs = self._get_output_config_for_summary_of_inputs_category(render_default, render_scientific) # If depth and/or pressure are provided, report them as inputs. If not, as outputs if self.reservoir_depth.Provided: - inputs.append((self.reservoir_depth, render_default)) + # inputs.append((self.reservoir_depth, render_default)) + reservoir_pressure_idx = [it[0].Name for it in inputs].index(self.reservoir_pressure.Name) + inputs.pop(reservoir_pressure_idx) if self.reservoir_pressure.Provided: - inputs.append((self.reservoir_pressure, render_default)) + # inputs.append((self.reservoir_pressure, render_default)) + reservoir_depth_idx = [it[0].Name for it in inputs].index(self.reservoir_depth.Name) + inputs.pop(reservoir_depth_idx) for param, render in inputs: summary_of_inputs[param.Name] = render(param) - case_data_inputs = {'SUMMARY OF INPUTS': summary_of_inputs} - - outputs = [ - (self.reservoir_volume, render_default), - (self.volume_rock, render_default), - (self.volume_recoverable_fluid, render_default), - (self.reservoir_stored_heat, render_scientific), - (self.stored_heat_rock, render_scientific), - (self.stored_heat_fluid, render_scientific), - (self.mass_rock, render_scientific), - (self.mass_recoverable_fluid, render_scientific), - (self.reservoir_enthalpy, render_default), - (self.enthalpy_rock, render_default), - (self.enthalpy_fluid, render_default), - ( - self.reservoir_recovery_factor, - lambda rg: f'{(100 * rg.value):10.2f} {self.reservoir_recovery_factor.CurrentUnits.value}', - ), - (self.reservoir_available_heat, render_scientific), - (self.reservoir_producible_heat, render_scientific), - (self.producible_heat_per_unit_area, render_scientific), - (self.heat_per_unit_volume_reservoir, render_scientific), - (self.reservoir_producible_electricity, render_default), - (self.producible_electricity_per_unit_area, render_default), - (self.electricity_per_unit_volume_reservoir, render_default), - ] + case_data_inputs = {self._SUMMARY_OF_INPUTS_OUTPUT_CATEGORY: summary_of_inputs} + + outputs = self._get_output_config_for_summary_of_results_category(render_default, render_scientific) # If depth and/or pressure are provided, report them as inputs. If not, as outputs if not self.reservoir_depth.Provided: - outputs.insert(0, (self.reservoir_depth, render_default)) + # outputs.insert(0, (self.reservoir_depth, render_default)) + reservoir_pressure_idx = [it[0].Name for it in outputs].index(self.reservoir_pressure.Name) + outputs.pop(reservoir_pressure_idx) if not self.reservoir_pressure.Provided: - outputs.insert(0, (self.reservoir_pressure, render_default)) + # outputs.insert(0, (self.reservoir_pressure, render_default)) + reservoir_depth_idx = [it[0].Name for it in outputs].index(self.reservoir_depth.Name) + outputs.pop(reservoir_depth_idx) + for param, render in outputs: summary_of_results[param.Name] = render(param) - case_data_results = {'SUMMARY OF RESULTS': summary_of_results} + case_data_results = {self._SUMMARY_OF_RESULTS_OUTPUT_CATEGORY: summary_of_results} with open(outputfile, 'w', encoding='UTF-8') as f: nl = '\n' @@ -895,17 +872,17 @@ def render_scientific(p: Parameter) -> str: f.write(f' ***HIP CASE REPORT***{nl}') f.write(f' *********************{nl}') f.write(nl) - f.write(f' ***SUMMARY OF INPUTS***{nl}') + f.write(f' ***{self._SUMMARY_OF_INPUTS_OUTPUT_CATEGORY}***{nl}') - for k, v in case_data_inputs['SUMMARY OF INPUTS'].items(): + for k, v in case_data_inputs[self._SUMMARY_OF_INPUTS_OUTPUT_CATEGORY].items(): # align space between value and units to same column kv_spaces = max(1, (24 - (len(v.split(' ')[0]) + len(k)))) * ' ' f.write(f' {k}:{kv_spaces}{v}{nl}') f.write(nl) - f.write(f' ***SUMMARY OF RESULTS***{nl}') - for k, v in case_data_results['SUMMARY OF RESULTS'].items(): + f.write(f' ***{self._SUMMARY_OF_RESULTS_OUTPUT_CATEGORY}***{nl}') + for k, v in case_data_results[self._SUMMARY_OF_RESULTS_OUTPUT_CATEGORY].items(): # align space between value and units to same column kv_spaces = max(1, (24 - (len(v.split(' ')[0]) + len(k)))) * ' ' @@ -944,6 +921,60 @@ def render_scientific(p: Parameter) -> str: for line in content: sys.stdout.write(line) + def _get_output_config_for_summary_of_inputs_category( + self, render_default: Callable[[Parameter], str], render_scientific: Callable[[Parameter], str] + ) -> list[tuple[Parameter, Callable[[Parameter], str]]]: + return [ + (self.reservoir_temperature, render_default), + (self.rejection_temperature, render_default), + (self.reservoir_porosity, render_default), + (self.reservoir_area, render_default), + (self.reservoir_thickness, render_default), + (self.reservoir_life_cycle, render_default), + (self.rock_heat_capacity, render_scientific), + (self.fluid_heat_capacity, render_default), + (self.fluid_density, render_scientific), + (self.rock_density, render_scientific), + (self.recoverable_fluid_factor, render_default), + (self.recoverable_rock_heat, render_default), + # Note: If depth and/or pressure are provided, they are reported as inputs. + # If not, they are reported as outputs. + (self.reservoir_depth, render_default), + (self.reservoir_pressure, render_default), + ] + + def _get_output_config_for_summary_of_results_category( + self, render_default: Callable[[Parameter], str], render_scientific: Callable[[Parameter], str] + ) -> list[tuple[Parameter, Callable[[Parameter], str]]]: + return [ + # Note: If depth and/or pressure are provided, they are reported as inputs. + # If not, they are reported as outputs. + (self.reservoir_depth, render_default), + (self.reservoir_pressure, render_default), + (self.reservoir_volume, render_default), + (self.volume_rock, render_default), + (self.volume_recoverable_fluid, render_default), + (self.reservoir_stored_heat, render_scientific), + (self.stored_heat_rock, render_scientific), + (self.stored_heat_fluid, render_scientific), + (self.mass_rock, render_scientific), + (self.mass_recoverable_fluid, render_scientific), + (self.reservoir_enthalpy, render_default), + (self.enthalpy_rock, render_default), + (self.enthalpy_fluid, render_default), + ( + self.reservoir_recovery_factor, + lambda rg: f'{(100 * rg.value):10.2f} {self.reservoir_recovery_factor.CurrentUnits.value}', + ), + (self.reservoir_available_heat, render_scientific), + (self.reservoir_producible_heat, render_scientific), + (self.producible_heat_per_unit_area, render_scientific), + (self.heat_per_unit_volume_reservoir, render_scientific), + (self.reservoir_producible_electricity, render_default), + (self.producible_electricity_per_unit_area, render_default), + (self.electricity_per_unit_volume_reservoir, render_default), + ] + def PrintOutputsHTML(self, inputs, outputs, output_filename: str = 'HIP.html'): """ PrintOutputs writes the standard outputs to the output file as HTML. The inputs and outputs are already prepared diff --git a/src/hip_ra_x/hip_ra_x_result.py b/src/hip_ra_x/hip_ra_x_result.py new file mode 100644 index 000000000..69cc731db --- /dev/null +++ b/src/hip_ra_x/hip_ra_x_result.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass +from typing import Any + +from hip_ra import HipRaResult + + +@dataclass +class HipRaXResult: + result: dict[str, dict[str, dict[str, Any]]] + caseReportText: str # pylint: disable=invalid-name + + @staticmethod + def from_hip_ra_result(hip_ra_result: HipRaResult) -> Any: + """ + :rtype: HipRaXResult + """ + with open(hip_ra_result.output_file_path, encoding='UTF-8') as f: + case_report_text = ''.join(f.readlines()) + + result_by_category: dict[str, dict[str, dict[str, Any]]] = {} + category_split = case_report_text.split('\n ***')[1:] + category_split.reverse() # Put results before inputs, for better UX if UIs are too lazy to sort + for category_text in category_split: + lines = category_text.split('\n') + category_name = lines[0].split('***')[0] + for k, v in hip_ra_result.result.items(): + if category_name not in result_by_category: + result_by_category[category_name] = {} + + if k in category_text: + result_by_category[category_name][k] = v + + return HipRaXResult(result=result_by_category, caseReportText=case_report_text) diff --git a/tests/examples/S-DAC-GT-2.out b/tests/examples/S-DAC-GT-2.out new file mode 100644 index 000000000..adb8ba8a0 --- /dev/null +++ b/tests/examples/S-DAC-GT-2.out @@ -0,0 +1,517 @@ + ***************** + ***CASE REPORT*** + ***************** + +Simulation Metadata +---------------------- + GEOPHIRES Version: 3.13.8 + Simulation Date: 2026-05-20 + Simulation Time: 08:24 + Calculation Time: 0.194 sec + + ***SUMMARY OF RESULTS*** + + End-Use Option: Cogeneration Topping Cycle, Heat sales considered as extra income + Average Net Electricity Production: 19.62 MW + Average Direct-Use Heat Production: 13.19 MW + Electricity breakeven price: 2.77 cents/kWh + Direct-Use heat breakeven price (LCOH): 0.00 USD/MMBTU + Total CAPEX: 214.79 MUSD + Electricity CAPEX ($/kWe): 9447 USD/kW + Heat CAPEX ($/kWth): 1184 USD/kW + Number of production wells: 3 + Number of injection wells: 3 + Flowrate per production well: 70.0 kg/sec + Well depth: 3.1 kilometer + Geothermal gradient: 70 degC/km + + + ***ECONOMIC PARAMETERS*** + + Economic Model = SAM Single Owner PPA + Real Discount Rate: 7.00 % + Nominal Discount Rate: 9.14 % + WACC: 6.37 % + Project lifetime: 30 yr + Capacity factor: 90.0 % + Project NPV: 40.11 MUSD + After-tax IRR: 16.85 % + Project VIR=PI=PIR: 1.33 + Project MOIC: 1.23 + Project Payback Period: 5.88 yr + CHP: Percent cost allocation for electrical plant: 92.25 % + + ***ENGINEERING PARAMETERS*** + + Number of Production Wells: 3 + Number of Injection Wells: 3 + Well depth: 3.1 kilometer + Water loss rate: 2.0 % + Pump efficiency: 80.0 % + Injection temperature: 70.0 degC + User-provided production well temperature drop + Constant production well temperature drop: 5.0 degC + Flowrate per production well: 70.0 kg/sec + Injection well casing ID: 8.500 in + Production well casing ID: 8.500 in + Number of times redrilling: 0 + Power plant type: Double-Flash + + + ***RESOURCE CHARACTERISTICS*** + + Maximum reservoir temperature: 400.0 degC + Number of segments: 1 + Geothermal gradient: 70 degC/km + + + ***RESERVOIR PARAMETERS*** + + Reservoir Model = Single Fracture m/A Thermal Drawdown Model + m/A Drawdown Parameter: 0.00002 1/year + Bottom-hole temperature: 232.00 degC + Reservoir volume calculated with fracture separation and number of fractures as input + Number of fractures: 12 + Fracture separation: 80.00 meter + Reservoir volume: 176000000 m**3 + Reservoir hydrostatic pressure: 29019.48 kPa + Plant outlet pressure: 100.00 kPa + Injectivity Index: 5.00 kg/sec/bar + Reservoir density: 2700.00 kg/m**3 + Reservoir thermal conductivity: 3.00 W/m/K + Reservoir heat capacity: 1000.00 J/kg/K + + + ***RESERVOIR SIMULATION RESULTS*** + + Maximum Production Temperature: 227.0 degC + Average Production Temperature: 220.6 degC + Minimum Production Temperature: 207.6 degC + Initial Production Temperature: 227.0 degC + Average Reservoir Heat Extraction: 133.05 MW + Wellbore Heat Transmission Model = Constant Temperature Drop: 5.0 degC + Average Injection Well Pump Pressure Drop: 687.0 kPa + + + ***CAPITAL COSTS (M$)*** + + Exploration costs: 4.42 MUSD + Drilling and completion costs: 25.55 MUSD + Drilling and completion costs per well: 4.26 MUSD + Stimulation costs: 4.53 MUSD + Surface power plant costs: 64.90 MUSD + of which Electrical Plant Cost: 59.87 MUSD + of which Heat Plant Cost: 5.03 MUSD + Field gathering system costs: 3.16 MUSD + Total surface equipment costs: 68.06 MUSD + Overnight Capital Cost: 210.58 MUSD + Inflation costs during construction: 4.21 MUSD + Total CAPEX: 214.79 MUSD + + + ***OPERATING AND MAINTENANCE COSTS (M$/yr)*** + + Wellfield maintenance costs: 0.74 MUSD/yr + Power plant maintenance costs: 2.34 MUSD/yr + Water costs: 0.11 MUSD/yr + Total operating and maintenance costs: 8.90 MUSD/yr + + + ***SURFACE EQUIPMENT SIMULATION RESULTS*** + Initial geofluid availability: 0.23 MW/(kg/s) + Maximum Total Electricity Generation: 21.16 MW + Average Total Electricity Generation: 19.80 MW + Minimum Total Electricity Generation: 17.14 MW + Initial Total Electricity Generation: 21.16 MW + Maximum Net Electricity Generation: 20.98 MW + Average Net Electricity Generation: 19.62 MW + Minimum Net Electricity Generation: 16.96 MW + Initial Net Electricity Generation: 20.98 MW + Average Annual Total Electricity Generation: 87.28 GWh + Average Annual Net Electricity Generation: 85.81 GWh + Initial pumping power/net installed power: 0.89 % + Maximum Net Heat Production: 14.05 MW + Average Net Heat Production: 13.19 MW + Minimum Net Heat Production: 11.35 MW + Initial Net Heat Production: 14.05 MW + Average Annual Heat Production: -4.76 GWh + Average Pumping Power: 0.19 MW + Heat to Power Conversion Efficiency: 16.55 % + + ************************************************************ + * HEATING, COOLING AND/OR ELECTRICITY PRODUCTION PROFILE * + ************************************************************ + YEAR THERMAL GEOFLUID PUMP NET NET FIRST LAW + DRAWDOWN TEMPERATURE POWER POWER HEAT EFFICIENCY + (deg C) (MW) (MW) (MW) (%) + 0 1.0000 227.00 0.1857 20.9750 14.0539 17.0370 + 1 1.0000 227.00 0.1857 20.9750 14.0539 17.0370 + 2 1.0000 227.00 0.1857 20.9750 14.0539 17.0370 + 3 1.0000 227.00 0.1857 20.9750 14.0538 17.0369 + 4 1.0000 227.00 0.1857 20.9743 14.0534 17.0367 + 5 0.9999 226.98 0.1857 20.9700 14.0509 17.0352 + 6 0.9996 226.92 0.1857 20.9566 14.0432 17.0306 + 7 0.9991 226.79 0.1857 20.9285 14.0268 17.0209 + 8 0.9981 226.57 0.1857 20.8811 13.9992 17.0046 + 9 0.9967 226.26 0.1857 20.8121 13.9588 16.9807 + 10 0.9949 225.84 0.1857 20.7210 13.9051 16.9492 + 11 0.9926 225.32 0.1857 20.6087 13.8385 16.9102 + 12 0.9899 224.71 0.1857 20.4769 13.7597 16.8643 + 13 0.9869 224.02 0.1857 20.3281 13.6697 16.8122 + 14 0.9835 223.26 0.1857 20.1645 13.5697 16.7546 + 15 0.9799 222.44 0.1857 19.9885 13.4608 16.6925 + 16 0.9761 221.57 0.1857 19.8026 13.3442 16.6264 + 17 0.9720 220.65 0.1857 19.6086 13.2209 16.5571 + 18 0.9678 219.70 0.1857 19.4085 13.0919 16.4852 + 19 0.9635 218.72 0.1857 19.2038 12.9580 16.4111 + 20 0.9591 217.72 0.1857 18.9961 12.8200 16.3355 + 21 0.9547 216.71 0.1857 18.7865 12.6787 16.2587 + 22 0.9501 215.68 0.1857 18.5760 12.5345 16.1810 + 23 0.9456 214.65 0.1857 18.3655 12.3881 16.1028 + 24 0.9410 213.61 0.1857 18.1557 12.2399 16.0244 + 25 0.9365 212.58 0.1857 17.9472 12.0904 15.9459 + 26 0.9319 211.54 0.1857 17.7406 11.9398 15.8675 + 27 0.9274 210.51 0.1857 17.5362 11.7886 15.7894 + 28 0.9229 209.49 0.1857 17.3344 11.6370 15.7118 + 29 0.9184 208.47 0.1857 17.1353 11.4853 15.6347 + + + ******************************************************************* + * ANNUAL HEATING, COOLING AND/OR ELECTRICITY PRODUCTION PROFILE * + ******************************************************************* + YEAR HEAT ELECTRICITY HEAT RESERVOIR PERCENTAGE OF + PROVIDED PROVIDED EXTRACTED HEAT CONTENT TOTAL HEAT MINED + (GWh/year) (GWh/year) (GWh/year) (10^15 J) (%) + 1 -2.5 93.6 1093.75 73.04 5.11 + 2 -2.5 93.6 1093.75 69.11 10.23 + 3 -2.5 93.6 1093.75 65.17 15.34 + 4 -2.5 93.6 1093.74 61.23 20.46 + 5 -2.5 93.6 1093.67 57.30 25.57 + 6 -2.6 93.6 1093.41 53.36 30.69 + 7 -2.6 93.4 1092.76 49.42 35.80 + 8 -2.6 93.2 1091.57 45.50 40.90 + 9 -2.7 92.9 1089.72 41.57 46.00 + 10 -2.8 92.4 1087.17 37.66 51.08 + 11 -3.0 91.8 1083.91 33.76 56.15 + 12 -3.1 91.1 1079.99 29.87 61.20 + 13 -3.3 90.3 1075.47 26.00 66.23 + 14 -3.5 89.4 1070.41 22.14 71.24 + 15 -3.8 88.4 1064.89 18.31 76.22 + 16 -4.1 87.4 1058.98 14.50 81.17 + 17 -4.4 86.3 1052.73 10.71 86.09 + 18 -4.7 85.2 1046.22 6.94 90.98 + 19 -5.0 84.0 1039.50 3.20 95.84 + 20 -5.4 82.8 1032.60 -0.52 100.67 + 21 -5.8 81.7 1025.58 -4.21 105.47 + 22 -6.2 80.5 1018.47 -7.88 110.23 + 23 -6.6 79.3 1011.30 -11.52 114.96 + 24 -7.0 78.1 1004.09 -15.13 119.66 + 25 -7.4 76.9 996.87 -18.72 124.32 + 26 -7.8 75.8 989.66 -22.28 128.95 + 27 -8.3 74.6 982.47 -25.82 133.54 + 28 -8.7 73.5 975.32 -29.33 138.10 + 29 -9.2 72.4 968.21 -32.82 142.63 + 30 -9.6 71.3 961.52 -36.28 147.13 + + *************************** + * SAM CASH FLOW PROFILE * + *************************** +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Year 0 Year 1 Year 2 Year 3 Year 4 Year 5 Year 6 Year 7 Year 8 Year 9 Year 10 Year 11 Year 12 Year 13 Year 14 Year 15 Year 16 Year 17 Year 18 Year 19 Year 20 Year 21 Year 22 Year 23 Year 24 Year 25 Year 26 Year 27 Year 28 Year 29 Year 30 +CONSTRUCTION +Capital expenditure schedule [construction] (%) 100.0 +Overnight capital expenditure [construction] ($) -210,575,751 +plus: +Inflation cost [construction] ($) -4,211,515 +plus: +Royalty supplemental payments [construction] ($) 0 +equals: +Nominal capital expenditure [construction] ($) -214,787,267 + +Issuance of equity [construction] ($) 107,393,633 +Issuance of debt [construction] ($) 107,393,633 +Debt balance [construction] ($) 107,393,633 +Debt interest payment [construction] ($) 0 + +Installed cost [construction] ($) -214,787,267 +After-tax net cash flow [construction] ($) -107,393,633 + +ENERGY +Electricity to grid (kWh) 0.0 164,262,593 164,262,593 164,262,523 164,259,927 164,237,860 164,153,030 163,946,512 163,565,140 162,974,410 162,160,536 161,126,671 159,887,568 158,464,763 156,882,914 155,167,311 153,342,313 151,430,456 149,452,029 147,424,931 145,364,714 143,284,728 141,196,317 139,109,029 137,030,835 134,968,328 132,926,914 130,910,978 128,924,033 126,968,851 125,142,526 +Electricity from grid (kWh) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +Electricity to grid net (kWh) 0.0 164,262,593 164,262,593 164,262,523 164,259,927 164,237,860 164,153,030 163,946,512 163,565,140 162,974,410 162,160,536 161,126,671 159,887,568 158,464,763 156,882,914 155,167,311 153,342,313 151,430,456 149,452,029 147,424,931 145,364,714 143,284,728 141,196,317 139,109,029 137,030,835 134,968,328 132,926,914 130,910,978 128,924,033 126,968,851 125,142,526 + +REVENUE +PPA price (cents/kWh) 0.0 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 5.50 +PPA revenue ($) 0 9,034,443 9,034,443 9,034,439 9,034,296 9,033,082 9,028,417 9,017,058 8,996,083 8,963,593 8,918,829 8,861,967 8,793,816 8,715,562 8,628,560 8,534,202 8,433,827 8,328,675 8,219,862 8,108,371 7,995,059 7,880,660 7,765,797 7,650,997 7,536,696 7,423,258 7,310,980 7,200,104 7,090,822 6,983,287 6,882,839 +Curtailment payment revenue ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Capacity payment revenue ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Salvage value ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 107,393,633 +Total revenue ($) 0 9,034,443 9,034,443 9,034,439 9,034,296 9,033,082 9,028,417 9,017,058 8,996,083 8,963,593 8,918,829 8,861,967 8,793,816 8,715,562 8,628,560 8,534,202 8,433,827 8,328,675 8,219,862 8,108,371 7,995,059 7,880,660 7,765,797 7,650,997 7,536,696 7,423,258 7,310,980 7,200,104 7,090,822 6,983,287 114,276,472 + +Property tax net assessed value ($) 0 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 214,787,267 + +OPERATING EXPENSES +O&M fixed expense ($) 0 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 +O&M production-based expense ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +O&M capacity-based expense ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Fuel expense ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Electricity purchase ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Property tax expense ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Insurance expense ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Total operating expenses ($) 0 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 8,897,504 + +EBITDA ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 + +OPERATING ACTIVITIES +EBITDA ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 +Interest earned on reserves ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +plus PBI if not available for debt service: +Federal PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Utility PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Other PBI income ($) 0 24,739,584 24,739,584 24,739,579 24,739,396 24,737,839 24,731,853 24,717,273 24,690,318 24,648,489 24,590,708 24,517,054 24,428,398 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Debt interest payment ($) 0 5,369,682 5,288,860 5,203,998 5,114,892 5,021,331 4,923,092 4,819,941 4,711,633 4,597,909 4,478,499 4,353,119 4,221,469 4,083,237 3,938,093 3,785,692 3,625,672 3,457,650 3,281,227 3,095,983 2,901,476 2,697,244 2,482,801 2,257,636 2,021,212 1,772,967 1,512,310 1,238,620 951,246 649,502 332,672 +Cash flow from operating activities ($) 0 19,506,841 19,587,663 19,672,516 19,761,296 19,852,087 19,939,674 20,016,886 20,077,264 20,116,669 20,133,535 20,128,398 20,103,241 -4,265,179 -4,207,037 -4,148,994 -4,089,348 -4,026,478 -3,958,869 -3,885,115 -3,803,921 -3,714,088 -3,614,507 -3,504,143 -3,382,020 -3,247,213 -3,098,833 -2,936,020 -2,757,927 -2,563,719 105,046,297 + +INVESTING ACTIVITIES +Total installed cost ($) -214,787,267 +Debt closing costs ($) 0 +Debt up-front fee ($) 0 +minus: +Total IBI income ($) 0 +Total CBI income ($) 0 +equals: +Purchase of property ($) -214,787,267 +plus: +Reserve (increase)/decrease debt service ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve (increase)/decrease working capital ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve (increase)/decrease receivables ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve (increase)/decrease major equipment 1 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve (increase)/decrease major equipment 2 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve (increase)/decrease major equipment 3 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve capital spending major equipment 1 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve capital spending major equipment 2 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserve capital spending major equipment 3 ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +equals: +Cash flow from investing activities ($) -214,787,267 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +FINANCING ACTIVITIES +Issuance of equity ($) 107,393,633 +Size of debt ($) 107,393,633 +minus: +Debt principal payment ($) 0 1,616,428 1,697,250 1,782,112 1,871,218 1,964,779 2,063,018 2,166,169 2,274,477 2,388,201 2,507,611 2,632,991 2,764,641 2,902,873 3,048,017 3,200,417 3,360,438 3,528,460 3,704,883 3,890,127 4,084,634 4,288,865 4,503,309 4,728,474 4,964,898 5,213,143 5,473,800 5,747,490 6,034,864 6,336,608 6,653,438 +equals: +Cash flow from financing activities ($) 214,787,267 -1,616,428 -1,697,250 -1,782,112 -1,871,218 -1,964,779 -2,063,018 -2,166,169 -2,274,477 -2,388,201 -2,507,611 -2,632,991 -2,764,641 -2,902,873 -3,048,017 -3,200,417 -3,360,438 -3,528,460 -3,704,883 -3,890,127 -4,084,634 -4,288,865 -4,503,309 -4,728,474 -4,964,898 -5,213,143 -5,473,800 -5,747,490 -6,034,864 -6,336,608 -6,653,438 + +PROJECT RETURNS +Pre-tax Cash Flow: +Cash flow from operating activities ($) 0 19,506,841 19,587,663 19,672,516 19,761,296 19,852,087 19,939,674 20,016,886 20,077,264 20,116,669 20,133,535 20,128,398 20,103,241 -4,265,179 -4,207,037 -4,148,994 -4,089,348 -4,026,478 -3,958,869 -3,885,115 -3,803,921 -3,714,088 -3,614,507 -3,504,143 -3,382,020 -3,247,213 -3,098,833 -2,936,020 -2,757,927 -2,563,719 105,046,297 +Cash flow from investing activities ($) -214,787,267 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Cash flow from financing activities ($) 214,787,267 -1,616,428 -1,697,250 -1,782,112 -1,871,218 -1,964,779 -2,063,018 -2,166,169 -2,274,477 -2,388,201 -2,507,611 -2,632,991 -2,764,641 -2,902,873 -3,048,017 -3,200,417 -3,360,438 -3,528,460 -3,704,883 -3,890,127 -4,084,634 -4,288,865 -4,503,309 -4,728,474 -4,964,898 -5,213,143 -5,473,800 -5,747,490 -6,034,864 -6,336,608 -6,653,438 +Total pre-tax cash flow ($) 0 17,890,413 17,890,413 17,890,404 17,890,078 17,887,308 17,876,656 17,850,718 17,802,787 17,728,468 17,625,924 17,495,407 17,338,600 -7,168,052 -7,255,053 -7,349,411 -7,449,786 -7,554,939 -7,663,752 -7,775,242 -7,888,554 -8,002,954 -8,117,816 -8,232,617 -8,346,918 -8,460,356 -8,572,633 -8,683,510 -8,792,792 -8,900,327 98,392,859 + +Pre-tax Returns: +Issuance of equity ($) 107,393,633 +Total pre-tax cash flow ($) 0 17,890,413 17,890,413 17,890,404 17,890,078 17,887,308 17,876,656 17,850,718 17,802,787 17,728,468 17,625,924 17,495,407 17,338,600 -7,168,052 -7,255,053 -7,349,411 -7,449,786 -7,554,939 -7,663,752 -7,775,242 -7,888,554 -8,002,954 -8,117,816 -8,232,617 -8,346,918 -8,460,356 -8,572,633 -8,683,510 -8,792,792 -8,900,327 98,392,859 +Total pre-tax returns ($) -107,393,633 17,890,413 17,890,413 17,890,404 17,890,078 17,887,308 17,876,656 17,850,718 17,802,787 17,728,468 17,625,924 17,495,407 17,338,600 -7,168,052 -7,255,053 -7,349,411 -7,449,786 -7,554,939 -7,663,752 -7,775,242 -7,888,554 -8,002,954 -8,117,816 -8,232,617 -8,346,918 -8,460,356 -8,572,633 -8,683,510 -8,792,792 -8,900,327 98,392,859 + +After-tax Returns: +Total pre-tax returns ($) -107,393,633 17,890,413 17,890,413 17,890,404 17,890,078 17,887,308 17,876,656 17,850,718 17,802,787 17,728,468 17,625,924 17,495,407 17,338,600 -7,168,052 -7,255,053 -7,349,411 -7,449,786 -7,554,939 -7,663,752 -7,775,242 -7,888,554 -8,002,954 -8,117,816 -8,232,617 -8,346,918 -8,460,356 -8,572,633 -8,683,510 -8,792,792 -8,900,327 98,392,859 +Federal ITC total income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Federal PTC income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Federal tax benefit (liability) ($) 0 2,026,123 3,036,824 3,020,608 3,003,607 2,985,960 2,968,078 2,950,536 2,933,847 2,918,323 2,904,058 2,890,964 2,878,830 2,867,368 2,856,257 2,845,165 2,833,767 2,821,752 2,808,832 2,794,738 2,779,222 1,735,908 690,732 669,642 646,304 620,542 592,187 561,073 527,040 489,927 -20,074,347 +State ITC total income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State PTC income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State tax benefit (liability) ($) 0 954,218 1,430,216 1,422,578 1,414,572 1,406,260 1,397,839 1,389,578 1,381,718 1,374,407 1,367,688 1,361,522 1,355,807 1,350,409 1,345,176 1,339,952 1,334,584 1,328,926 1,322,841 1,316,203 1,308,896 817,539 325,306 315,373 304,382 292,249 278,895 264,242 248,213 230,735 -9,454,167 +Total after-tax returns ($) -107,393,633 20,870,754 22,357,453 22,333,591 22,308,257 22,279,528 22,242,573 22,190,831 22,118,351 22,021,198 21,897,671 21,747,893 21,573,237 -2,950,275 -3,053,620 -3,164,294 -3,281,436 -3,404,260 -3,532,079 -3,664,302 -3,800,437 -5,449,506 -7,101,778 -7,247,602 -7,396,232 -7,547,564 -7,701,551 -7,858,195 -8,017,538 -8,179,665 68,864,345 + +After-tax net cash flow ($) -107,393,633 20,870,754 22,357,453 22,333,591 22,308,257 22,279,528 22,242,573 22,190,831 22,118,351 22,021,198 21,897,671 21,747,893 21,573,237 -2,950,275 -3,053,620 -3,164,294 -3,281,436 -3,404,260 -3,532,079 -3,664,302 -3,800,437 -5,449,506 -7,101,778 -7,247,602 -7,396,232 -7,547,564 -7,701,551 -7,858,195 -8,017,538 -8,179,665 68,864,345 +After-tax cumulative IRR (%) NaN -80.57 -43.63 -20.95 -7.50 0.84 6.28 9.96 12.53 14.38 15.73 16.74 17.51 17.42 17.35 17.28 17.22 17.16 17.11 17.07 17.03 16.98 -14.19 -11.80 -9.89 -8.32 -6.99 -5.85 -4.85 -3.99 16.85 +After-tax cumulative NPV ($) -107,393,633 -88,270,714 -69,501,139 -52,321,790 -36,598,992 -22,211,462 -9,050,691 2,979,871 13,966,922 23,989,638 33,121,481 41,431,341 48,984,140 48,037,748 47,140,237 46,288,084 45,478,390 44,708,736 43,977,060 43,281,561 42,620,632 41,752,284 40,715,423 39,745,888 38,839,330 37,991,697 37,199,204 36,458,309 35,765,697 35,118,255 40,112,570 + +AFTER-TAX LCOE AND PPA PRICE +Annual costs ($) -107,393,633 11,836,312 13,323,010 13,299,152 13,273,961 13,246,446 13,214,156 13,173,773 13,122,269 13,057,605 12,978,841 12,885,926 12,779,420 -11,665,837 -11,682,181 -11,698,496 -11,715,263 -11,732,936 -11,751,941 -11,772,673 -11,795,497 -13,330,166 -14,867,576 -14,898,599 -14,932,928 -14,970,822 -15,012,532 -15,058,298 -15,108,360 -15,162,952 61,981,506 +PPA revenue ($) 0 9,034,443 9,034,443 9,034,439 9,034,296 9,033,082 9,028,417 9,017,058 8,996,083 8,963,593 8,918,829 8,861,967 8,793,816 8,715,562 8,628,560 8,534,202 8,433,827 8,328,675 8,219,862 8,108,371 7,995,059 7,880,660 7,765,797 7,650,997 7,536,696 7,423,258 7,310,980 7,200,104 7,090,822 6,983,287 6,882,839 +Electricity to grid (kWh) 0 164,262,593 164,262,593 164,262,523 164,259,927 164,237,860 164,153,030 163,946,512 163,565,140 162,974,410 162,160,536 161,126,671 159,887,568 158,464,763 156,882,914 155,167,311 153,342,313 151,430,456 149,452,029 147,424,931 145,364,714 143,284,728 141,196,317 139,109,029 137,030,835 134,968,328 132,926,914 130,910,978 128,924,033 126,968,851 125,142,526 + +Present value of annual costs ($) 48,355,665 + +Present value of annual energy costs ($) 44,609,256 +Present value of annual energy nominal (kWh) 1,608,513,342 +LCOE Levelized cost of energy nominal (cents/kWh) 2.77 + +Present value of PPA revenue ($) 88,468,234 +Present value of annual energy nominal (kWh) 1,608,513,342 +LPPA Levelized PPA price nominal (cents/kWh) 5.50 + +PROJECT STATE INCOME TAXES +EBITDA ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 +State taxable PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Interest earned on reserves ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State taxable IBI income ($) 0 +State taxable CBI income ($) 0 +minus: +Debt interest payment ($) 0 5,369,682 5,288,860 5,203,998 5,114,892 5,021,331 4,923,092 4,819,941 4,711,633 4,597,909 4,478,499 4,353,119 4,221,469 4,083,237 3,938,093 3,785,692 3,625,672 3,457,650 3,281,227 3,095,983 2,901,476 2,697,244 2,482,801 2,257,636 2,021,212 1,772,967 1,512,310 1,238,620 951,246 649,502 332,672 +Total state tax depreciation ($) 0 5,369,682 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 5,369,682 0 0 0 0 0 0 0 0 0 +equals: +State taxable income ($) 0 -10,602,424 -15,891,285 -15,806,426 -15,717,463 -15,625,116 -15,531,543 -15,439,750 -15,352,417 -15,271,184 -15,196,537 -15,128,019 -15,064,520 -15,004,542 -14,946,400 -14,888,357 -14,828,711 -14,765,842 -14,698,232 -14,624,478 -14,543,284 -9,083,770 -3,614,507 -3,504,143 -3,382,020 -3,247,213 -3,098,833 -2,936,020 -2,757,927 -2,563,719 105,046,297 + +State income tax rate (frac) 0.0 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 0.09 +State tax benefit (liability) ($) 0 954,218 1,430,216 1,422,578 1,414,572 1,406,260 1,397,839 1,389,578 1,381,718 1,374,407 1,367,688 1,361,522 1,355,807 1,350,409 1,345,176 1,339,952 1,334,584 1,328,926 1,322,841 1,316,203 1,308,896 817,539 325,306 315,373 304,382 292,249 278,895 264,242 248,213 230,735 -9,454,167 + +PROJECT FEDERAL INCOME TAXES +EBITDA ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 +Interest earned on reserves ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State tax benefit (liability) ($) 0 954,218 1,430,216 1,422,578 1,414,572 1,406,260 1,397,839 1,389,578 1,381,718 1,374,407 1,367,688 1,361,522 1,355,807 1,350,409 1,345,176 1,339,952 1,334,584 1,328,926 1,322,841 1,316,203 1,308,896 817,539 325,306 315,373 304,382 292,249 278,895 264,242 248,213 230,735 -9,454,167 +State ITC total income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State PTC income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Federal taxable IBI income ($) 0 +Federal taxable CBI income ($) 0 +Federal taxable PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +minus: +Debt interest payment ($) 0 5,369,682 5,288,860 5,203,998 5,114,892 5,021,331 4,923,092 4,819,941 4,711,633 4,597,909 4,478,499 4,353,119 4,221,469 4,083,237 3,938,093 3,785,692 3,625,672 3,457,650 3,281,227 3,095,983 2,901,476 2,697,244 2,482,801 2,257,636 2,021,212 1,772,967 1,512,310 1,238,620 951,246 649,502 332,672 +Total federal tax depreciation ($) 0 5,369,682 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 10,739,363 5,369,682 0 0 0 0 0 0 0 0 0 +equals: +Federal taxable income ($) 0 -9,648,206 -14,461,069 -14,383,848 -14,302,891 -14,218,855 -14,133,704 -14,050,173 -13,970,700 -13,896,777 -13,828,848 -13,766,497 -13,708,713 -13,654,133 -13,601,224 -13,548,405 -13,494,127 -13,436,916 -13,375,391 -13,308,275 -13,234,388 -8,266,230 -3,289,202 -3,188,770 -3,077,638 -2,954,964 -2,819,938 -2,671,778 -2,509,714 -2,332,984 95,592,130 + +Federal income tax rate (frac) 0.0 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 0.21 +Federal tax benefit (liability) ($) 0 2,026,123 3,036,824 3,020,608 3,003,607 2,985,960 2,968,078 2,950,536 2,933,847 2,918,323 2,904,058 2,890,964 2,878,830 2,867,368 2,856,257 2,845,165 2,833,767 2,821,752 2,808,832 2,794,738 2,779,222 1,735,908 690,732 669,642 646,304 620,542 592,187 561,073 527,040 489,927 -20,074,347 + +CASH INCENTIVES +Federal IBI income ($) 0 +State IBI income ($) 0 +Utility IBI income ($) 0 +Other IBI income ($) 0 +Total IBI income ($) 0 + +Federal CBI income ($) 0 +State CBI income ($) 0 +Utility CBI income ($) 0 +Other CBI income ($) 0 +Total CBI income ($) 0 + +Federal PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Utility PBI income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Other PBI income ($) 0 24,739,584 24,739,584 24,739,579 24,739,396 24,737,839 24,731,853 24,717,273 24,690,318 24,648,489 24,590,708 24,517,054 24,428,398 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Total PBI income ($) 0 24,739,584 24,739,584 24,739,579 24,739,396 24,737,839 24,731,853 24,717,273 24,690,318 24,648,489 24,590,708 24,517,054 24,428,398 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +TAX CREDITS +Federal PTC income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State PTC income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Federal ITC amount income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Federal ITC percent income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Federal ITC total income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +State ITC amount income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State ITC percent income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +State ITC total income ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +DEBT REPAYMENT +Debt balance ($) 107,393,633 105,777,205 104,079,955 102,297,843 100,426,625 98,461,847 96,398,829 94,232,660 91,958,183 89,569,983 87,062,372 84,429,380 81,664,740 78,761,867 75,713,850 72,513,432 69,152,994 65,624,534 61,919,651 58,029,523 53,944,889 49,656,024 45,152,715 40,424,241 35,459,343 30,246,200 24,772,400 19,024,910 12,990,046 6,653,438 0 +Debt interest payment ($) 0 5,369,682 5,288,860 5,203,998 5,114,892 5,021,331 4,923,092 4,819,941 4,711,633 4,597,909 4,478,499 4,353,119 4,221,469 4,083,237 3,938,093 3,785,692 3,625,672 3,457,650 3,281,227 3,095,983 2,901,476 2,697,244 2,482,801 2,257,636 2,021,212 1,772,967 1,512,310 1,238,620 951,246 649,502 332,672 +Debt principal payment ($) 0 1,616,428 1,697,250 1,782,112 1,871,218 1,964,779 2,063,018 2,166,169 2,274,477 2,388,201 2,507,611 2,632,991 2,764,641 2,902,873 3,048,017 3,200,417 3,360,438 3,528,460 3,704,883 3,890,127 4,084,634 4,288,865 4,503,309 4,728,474 4,964,898 5,213,143 5,473,800 5,747,490 6,034,864 6,336,608 6,653,438 +Debt total payment ($) 0 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 + +DSCR (DEBT FRACTION) +EBITDA ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 +minus: +Reserves major equipment 1 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 2 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 3 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves receivables funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +equals: +Cash available for debt service (CAFDS) ($) 0 136,939 136,939 136,935 136,792 135,579 130,913 119,555 98,579 66,089 21,326 -35,537 -103,687 -181,942 -268,943 -363,302 -463,676 -568,829 -677,642 -789,132 -902,444 -1,016,844 -1,131,706 -1,246,507 -1,360,808 -1,474,246 -1,586,523 -1,697,400 -1,806,682 -1,914,217 105,378,969 +Debt total payment ($) 0 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 6,986,110 +DSCR (pre-tax) 0.0 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.01 0.01 0.0 -0.01 -0.01 -0.03 -0.04 -0.05 -0.07 -0.08 -0.10 -0.11 -0.13 -0.15 -0.16 -0.18 -0.19 -0.21 -0.23 -0.24 -0.26 -0.27 15.08 + +RESERVES +Reserves working capital funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves working capital disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves working capital balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves debt service funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves debt service disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves debt service balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves receivables funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves receivables disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves receivables balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves major equipment 1 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 1 disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 1 balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves major equipment 2 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 2 disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 2 balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves major equipment 3 funding ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 3 disbursement ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Reserves major equipment 3 balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +Reserves total reserves balance ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +Interest on reserves (%/year) 1.75 +Interest earned on reserves ($) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + + ***S-DAC-GT ECONOMICS*** + + + S-DAC-GT Report: Levelized Cost of Direct Air Capture (LCOD) + LCOD using grid-based electricity only: 387.69 USD/tonne + LCOD using natural gas only: 312.00 USD/tonne + LCOD using geothermal energy only: 288.87 USD/tonne + + S-DAC-GT Report: CO2 Intensity of process (percent of CO2 mitigated that is emitted by S-DAC process) + CO2 Intensity using grid-based electricity only: 94.52 % + CO2 Intensity using natural gas only: 64.85 % + CO2 Intensity using geothermal energy only: 36.91 % + + Geothermal LCOH: 0.0017 USD/kWh + Geothermal Ratio (electricity vs heat): 20.7259 % + Percent Energy Devoted To Process: 50.0000 % + + Total Tonnes of CO2 Captured: 2,253,170.17 tonne + Total Cost of Capture: 500,842,063.38 USD + + + ********************** + * S-DAC-GT PROFILE * + ********************** +Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost Annual Carbon +Since Captured Captured Annual Cost Cash Flow Cost Per Tonne Revenue +Start (tonne/yr) (tonne) (USD/yr) (USD) (USD/tonne) (USD/yr) + 1 78,330.80 78,330.80 17,411,627.98 17,411,627.98 222.28 14,099,544.46 + 2 78,330.80 156,661.61 17,411,627.98 34,823,255.96 222.28 14,099,544.46 + 3 78,330.79 234,992.39 17,411,624.49 52,234,880.45 222.28 14,099,541.64 + 4 78,330.21 313,322.60 17,411,495.60 69,646,376.05 222.28 14,099,437.26 + 5 78,325.28 391,647.88 17,410,399.97 87,056,776.02 222.28 14,098,550.05 + 6 78,306.33 469,954.20 17,406,187.21 104,462,963.23 222.28 14,095,138.65 + 7 78,260.16 548,214.36 17,395,925.55 121,858,888.78 222.28 14,086,828.98 + 8 78,174.81 626,389.18 17,376,954.53 139,235,843.31 222.28 14,071,466.68 + 9 78,042.38 704,431.56 17,347,515.71 156,583,359.02 222.28 14,047,627.79 + 10 77,859.43 782,290.99 17,306,849.76 173,890,208.78 222.28 14,014,697.42 + 11 77,626.22 859,917.21 17,255,012.02 191,145,220.80 222.28 13,972,720.38 + 12 77,345.52 937,262.73 17,192,616.14 208,337,836.94 222.28 13,922,193.60 + 13 77,021.56 1,014,284.29 17,120,605.40 225,458,442.34 222.28 0.00 + 14 76,659.30 1,090,943.59 17,040,081.18 242,498,523.53 222.28 0.00 + 15 76,263.89 1,167,207.48 16,952,186.81 259,450,710.33 222.28 0.00 + 16 75,840.32 1,243,047.80 16,858,034.91 276,308,745.24 222.28 0.00 + 17 75,393.28 1,318,441.08 16,758,665.93 293,067,411.17 222.28 0.00 + 18 74,927.04 1,393,368.11 16,655,027.43 309,722,438.60 222.28 0.00 + 19 74,445.39 1,467,813.51 16,547,966.62 326,270,405.23 222.28 0.00 + 20 73,951.72 1,541,765.22 16,438,231.02 342,708,636.25 222.28 0.00 + 21 73,448.95 1,615,214.17 16,326,473.66 359,035,109.91 222.28 0.00 + 22 72,939.63 1,688,153.81 16,213,260.66 375,248,370.57 222.28 0.00 + 23 72,425.96 1,760,579.76 16,099,079.76 391,347,450.33 222.28 0.00 + 24 71,909.81 1,832,489.57 15,984,349.02 407,331,799.35 222.28 0.00 + 25 71,392.80 1,903,882.37 15,869,425.07 423,201,224.42 222.28 0.00 + 26 70,876.27 1,974,758.64 15,754,610.85 438,955,835.27 222.28 0.00 + 27 70,361.40 2,045,120.04 15,640,162.58 454,595,997.86 222.28 0.00 + 28 69,849.14 2,114,969.18 15,526,295.96 470,122,293.82 222.28 0.00 + 29 69,340.31 2,184,309.49 15,413,191.67 485,535,485.49 222.28 0.00 + 30 68,860.68 2,253,170.17 15,306,577.89 500,842,063.38 222.28 0.00 diff --git a/tests/examples/S-DAC-GT-2.txt b/tests/examples/S-DAC-GT-2.txt new file mode 100644 index 000000000..86b17b052 --- /dev/null +++ b/tests/examples/S-DAC-GT-2.txt @@ -0,0 +1,52 @@ +# Geothermal Combined Heat and Power Problem using a Thermal Drawdown Reservoir Model and SAM Economic Model and +# Solid Sorbent Direct Air Capture powered by geothermal +# Based on Example 3 description: This example problem considers an EGS reservoir at 3.1km depth. +# The heat is used in a combined heat and power topping cycle model with double flash as +# topping cycle and electricity considered as the main product. +# But only lists those parameters that are different than their default values + +Do S-DAC-GT Calculations, True + +***Subsurface technical parameters*** +************************************* +Reservoir Model,3, ---m/A Single Fracture Thermal Drawdown +Reservoir Depth,3.1, ---[km] +Number of Segments,1, ---[-] +Maximum Temperature,400, ---[deg.C] +Drawdown Parameter,.00002, ---[kg/s/m2] +Gradient 1,70, ---[deg.C/km] +Number of Production Wells,3, ---[-] +Number of Injection Wells,3, ---[-] +Production Well Diameter,8.5, ---[inch] +Injection Well Diameter,8.5, ---[inch] +Ramey Production Wellbore Model,0, ---Should be 0 (disabled) or 1 (enabled) +Production Flow Rate per Well,70, ---[kg/s] +Reservoir Volume Option,1, ---Should be 1 2 3 or 4. See manual for details. +Fracture Shape,1, ---Should be 1 2 3 or 4 +Fracture Area,200000, ---[m2] +Number of Fractures,12, ---[-] +Fracture Separation,80, ---[m] +Injectivity Index,5, ---[kg/s/bar] +Water Loss Fraction,0.02, ---[-] + +***Surface Technical Parameters*** +********************************** + +End-Use Option,31, ---CHP Topping Cycle with electricity as the main product +Power Plant Type,4, ---Double-Flash +Circulation Pump Efficiency,.80, ---[-] + +***Financial Parameters*** +************************** + +Economic Model, 5, -- SAM Single Owner PPA ---BICYCLE Levelized Cost Model +Inflated Equity Interest Rate,.08, ---[-] Required for BICYCLE model +Combined Income Tax Rate,.3, ---[-] Required for BICYCLE model +Gross Revenue Tax Rate,0, ---[-] Required for BICYCLE model +S-DAC-GT Carbon Credit Price, 180.0, ---[USD/tonne CO2] 45Q tax credit rate or voluntary market price + +***Simulation Parameters*** +*************************** + +Print Output to Console,1, ---Should be 1 (to print) or 0 (to not print) +Time steps per year,10, ---[-] diff --git a/tests/examples/S-DAC-GT.out b/tests/examples/S-DAC-GT.out index 75170830c..3ecead048 100644 --- a/tests/examples/S-DAC-GT.out +++ b/tests/examples/S-DAC-GT.out @@ -4,18 +4,18 @@ Simulation Metadata ---------------------- - GEOPHIRES Version: 3.12.1 - Simulation Date: 2026-04-07 - Simulation Time: 10:46 - Calculation Time: 0.135 sec + GEOPHIRES Version: 3.13.8 + Simulation Date: 2026-05-19 + Simulation Time: 13:57 + Calculation Time: 0.137 sec ***SUMMARY OF RESULTS*** End-Use Option: Cogeneration Topping Cycle, Heat sales considered as extra income Average Net Electricity Production: 19.62 MW Average Direct-Use Heat Production: 13.19 MW - Electricity breakeven price: 10.68 cents/kWh - Direct-Use heat breakeven price (LCOH): -56.08 USD/MMBTU + Electricity breakeven price: 24.39 cents/kWh + Direct-Use heat breakeven price (LCOH): -128.08 USD/MMBTU Number of production wells: 3 Number of injection wells: 3 Flowrate per production well: 70.0 kg/sec @@ -29,11 +29,11 @@ Simulation Metadata Accrued financing during construction: 0.00 % Project lifetime: 30 yr Capacity factor: 90.0 % - Project NPV: -82.17 MUSD - Project IRR: -5.86 % - Project VIR=PI=PIR: 0.20 - Project MOIC: -0.30 - Project Payback Period: N/A + Project NPV: -89.80 MUSD + Project IRR: 1.99 % + Project VIR=PI=PIR: 0.57 + Project MOIC: 0.14 + Project Payback Period: 22.52 yr CHP: Percent cost allocation for electrical plant: 92.25 % ***ENGINEERING PARAMETERS*** @@ -99,7 +99,7 @@ Simulation Metadata of which Heat Plant Cost: 5.03 MUSD Field gathering system costs: 3.16 MUSD Total surface equipment costs: 68.06 MUSD - Total capital costs: 102.56 MUSD + Total capital costs: 210.58 MUSD ***OPERATING AND MAINTENANCE COSTS (M$/yr)*** @@ -107,7 +107,7 @@ Simulation Metadata Wellfield maintenance costs: 0.74 MUSD/yr Power plant maintenance costs: 2.34 MUSD/yr Water costs: 0.11 MUSD/yr - Total operating and maintenance costs: 3.19 MUSD/yr + Total operating and maintenance costs: 8.90 MUSD/yr ***SURFACE EQUIPMENT SIMULATION RESULTS*** @@ -214,37 +214,37 @@ Year Electricity | Heat | Since Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | OPEX Net Rev. Net Cashflow Start (cents/kWh)(MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(USD/lb) (MUSD/yr) (MUSD) |(MUSD/yr) (MUSD/yr) (MUSD) ________________________________________________________________________________________________________________________________________________________________________________________ - 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -102.56 -102.56 - 1 5.50 5.15 5.15 | 2.50 -0.06 -0.06 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.90 -100.66 - 2 5.50 5.15 10.30 | 2.50 -0.06 -0.13 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.90 -98.77 - 3 5.50 5.15 15.45 | 2.50 -0.06 -0.19 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.90 -96.87 - 4 5.50 5.15 20.60 | 2.50 -0.06 -0.25 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.90 -94.97 - 5 5.50 5.15 25.74 | 2.50 -0.06 -0.32 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.89 -93.08 - 6 5.50 5.15 30.89 | 2.50 -0.06 -0.38 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.89 -91.19 - 7 5.50 5.14 36.03 | 2.50 -0.06 -0.45 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.88 -89.30 - 8 5.50 5.13 41.16 | 2.50 -0.07 -0.51 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.87 -87.43 - 9 5.50 5.11 46.26 | 2.50 -0.07 -0.58 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.85 -85.58 - 10 5.50 5.08 51.35 | 2.50 -0.07 -0.65 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.82 -83.76 - 11 5.50 5.05 56.40 | 2.50 -0.07 -0.72 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.79 -81.97 - 12 5.50 5.01 61.41 | 2.50 -0.08 -0.80 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.74 -80.22 - 13 5.50 4.97 66.38 | 2.50 -0.08 -0.89 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.69 -78.53 - 14 5.50 4.92 71.29 | 2.50 -0.09 -0.97 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.64 -76.89 - 15 5.50 4.86 76.16 | 2.50 -0.09 -1.07 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.58 -75.31 - 16 5.50 4.81 80.96 | 2.50 -0.10 -1.17 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.52 -73.80 - 17 5.50 4.75 85.71 | 2.50 -0.11 -1.28 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.45 -72.35 - 18 5.50 4.68 90.40 | 2.50 -0.12 -1.40 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.38 -70.97 - 19 5.50 4.62 95.02 | 2.50 -0.13 -1.52 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.31 -69.66 - 20 5.50 4.56 99.57 | 2.50 -0.13 -1.66 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.23 -68.43 - 21 5.50 4.49 104.06 | 2.50 -0.14 -1.80 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.16 -67.27 - 22 5.50 4.43 108.49 | 2.50 -0.15 -1.96 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.08 -66.19 - 23 5.50 4.36 112.85 | 2.50 -0.16 -2.12 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 1.01 -65.18 - 24 5.50 4.30 117.15 | 2.50 -0.17 -2.29 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.93 -64.25 - 25 5.50 4.23 121.38 | 2.50 -0.18 -2.48 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.86 -63.40 - 26 5.50 4.17 125.54 | 2.50 -0.20 -2.67 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.78 -62.61 - 27 5.50 4.10 129.65 | 2.50 -0.21 -2.88 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.71 -61.91 - 28 5.50 4.04 133.69 | 2.50 -0.22 -3.10 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.63 -61.27 - 29 5.50 3.98 137.67 | 2.50 -0.23 -3.33 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.56 -60.71 - 30 5.50 3.92 141.59 | 2.50 -0.24 -3.57 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 3.19 0.49 -60.22 + 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -210.58 -210.58 + 1 5.50 5.15 5.15 | 2.50 -0.06 -0.06 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.29 -200.29 + 2 5.50 5.15 10.30 | 2.50 -0.06 -0.13 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.29 -190.00 + 3 5.50 5.15 15.45 | 2.50 -0.06 -0.19 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.29 -179.71 + 4 5.50 5.15 20.60 | 2.50 -0.06 -0.25 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.29 -169.43 + 5 5.50 5.15 25.74 | 2.50 -0.06 -0.32 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.29 -159.14 + 6 5.50 5.15 30.89 | 2.50 -0.06 -0.38 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.28 -148.86 + 7 5.50 5.14 36.03 | 2.50 -0.06 -0.45 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.26 -138.60 + 8 5.50 5.13 41.16 | 2.50 -0.07 -0.51 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.24 -128.36 + 9 5.50 5.11 46.26 | 2.50 -0.07 -0.58 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.19 -118.17 + 10 5.50 5.08 51.35 | 2.50 -0.07 -0.65 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.13 -108.04 + 11 5.50 5.05 56.40 | 2.50 -0.07 -0.72 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 10.05 -97.99 + 12 5.50 5.01 61.41 | 2.50 -0.08 -0.80 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.96 -88.03 + 13 5.50 4.97 66.38 | 2.50 -0.08 -0.89 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.85 -78.18 + 14 5.50 4.92 71.29 | 2.50 -0.09 -0.97 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.73 -68.45 + 15 5.50 4.86 76.16 | 2.50 -0.09 -1.07 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.60 -58.85 + 16 5.50 4.81 80.96 | 2.50 -0.10 -1.17 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.46 -49.39 + 17 5.50 4.75 85.71 | 2.50 -0.11 -1.28 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.31 -40.08 + 18 5.50 4.68 90.40 | 2.50 -0.12 -1.40 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.16 -30.93 + 19 5.50 4.62 95.02 | 2.50 -0.13 -1.52 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 9.00 -21.93 + 20 5.50 4.56 99.57 | 2.50 -0.13 -1.66 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.84 -13.09 + 21 5.50 4.49 104.06 | 2.50 -0.14 -1.80 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.67 -4.42 + 22 5.50 4.43 108.49 | 2.50 -0.15 -1.96 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.50 4.08 + 23 5.50 4.36 112.85 | 2.50 -0.16 -2.12 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.34 12.42 + 24 5.50 4.30 117.15 | 2.50 -0.17 -2.29 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.17 20.58 + 25 5.50 4.23 121.38 | 2.50 -0.18 -2.48 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 8.00 28.58 + 26 5.50 4.17 125.54 | 2.50 -0.20 -2.67 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 7.83 36.42 + 27 5.50 4.10 129.65 | 2.50 -0.21 -2.88 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 7.66 44.08 + 28 5.50 4.04 133.69 | 2.50 -0.22 -3.10 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 7.50 51.58 + 29 5.50 3.98 137.67 | 2.50 -0.23 -3.33 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 7.33 58.91 + 30 5.50 3.92 141.59 | 2.50 -0.24 -3.57 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 8.90 7.18 66.09 @@ -272,36 +272,36 @@ ________________________________________________________________________________ ********************** * S-DAC-GT PROFILE * ********************** -Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost -Since Captured Captured Annual Cost Cash Flow Cost Per Tonne -Start (tonne/yr) (tonne) (USD/yr) (USD) (USD/tonne) - 1 78,330.80 78,330.80 17,411,627.98 17,411,627.98 222.28 - 2 78,330.80 156,661.61 17,411,627.98 34,823,255.96 222.28 - 3 78,330.79 234,992.39 17,411,624.49 52,234,880.45 222.28 - 4 78,330.21 313,322.60 17,411,495.60 69,646,376.05 222.28 - 5 78,325.28 391,647.88 17,410,399.97 87,056,776.02 222.28 - 6 78,306.33 469,954.20 17,406,187.21 104,462,963.23 222.28 - 7 78,260.16 548,214.36 17,395,925.55 121,858,888.78 222.28 - 8 78,174.81 626,389.18 17,376,954.53 139,235,843.31 222.28 - 9 78,042.38 704,431.56 17,347,515.71 156,583,359.02 222.28 - 10 77,859.43 782,290.99 17,306,849.76 173,890,208.78 222.28 - 11 77,626.22 859,917.21 17,255,012.02 191,145,220.80 222.28 - 12 77,345.52 937,262.73 17,192,616.14 208,337,836.94 222.28 - 13 77,021.56 1,014,284.29 17,120,605.40 225,458,442.34 222.28 - 14 76,659.30 1,090,943.59 17,040,081.18 242,498,523.53 222.28 - 15 76,263.89 1,167,207.48 16,952,186.81 259,450,710.33 222.28 - 16 75,840.32 1,243,047.80 16,858,034.91 276,308,745.24 222.28 - 17 75,393.28 1,318,441.08 16,758,665.93 293,067,411.17 222.28 - 18 74,927.04 1,393,368.11 16,655,027.43 309,722,438.60 222.28 - 19 74,445.39 1,467,813.51 16,547,966.62 326,270,405.23 222.28 - 20 73,951.72 1,541,765.22 16,438,231.02 342,708,636.25 222.28 - 21 73,448.95 1,615,214.17 16,326,473.66 359,035,109.91 222.28 - 22 72,939.63 1,688,153.81 16,213,260.66 375,248,370.57 222.28 - 23 72,425.96 1,760,579.76 16,099,079.76 391,347,450.33 222.28 - 24 71,909.81 1,832,489.57 15,984,349.02 407,331,799.35 222.28 - 25 71,392.80 1,903,882.37 15,869,425.07 423,201,224.42 222.28 - 26 70,876.27 1,974,758.64 15,754,610.85 438,955,835.27 222.28 - 27 70,361.40 2,045,120.04 15,640,162.58 454,595,997.86 222.28 - 28 69,849.14 2,114,969.18 15,526,295.96 470,122,293.82 222.28 - 29 69,340.31 2,184,309.49 15,413,191.67 485,535,485.49 222.28 - 30 68,860.68 2,253,170.17 15,306,577.89 500,842,063.38 222.28 +Year Carbon Cumm. Carbon S-DAC-GT S-DAC-GT Cumm. Cumm. Cost Annual Carbon +Since Captured Captured Annual Cost Cash Flow Cost Per Tonne Revenue +Start (tonne/yr) (tonne) (USD/yr) (USD) (USD/tonne) (USD/yr) + 1 78,330.80 78,330.80 17,411,627.98 17,411,627.98 222.28 14,099,544.46 + 2 78,330.80 156,661.61 17,411,627.98 34,823,255.96 222.28 14,099,544.46 + 3 78,330.79 234,992.39 17,411,624.49 52,234,880.45 222.28 14,099,541.64 + 4 78,330.21 313,322.60 17,411,495.60 69,646,376.05 222.28 14,099,437.26 + 5 78,325.28 391,647.88 17,410,399.97 87,056,776.02 222.28 14,098,550.05 + 6 78,306.33 469,954.20 17,406,187.21 104,462,963.23 222.28 14,095,138.65 + 7 78,260.16 548,214.36 17,395,925.55 121,858,888.78 222.28 14,086,828.98 + 8 78,174.81 626,389.18 17,376,954.53 139,235,843.31 222.28 14,071,466.68 + 9 78,042.38 704,431.56 17,347,515.71 156,583,359.02 222.28 14,047,627.79 + 10 77,859.43 782,290.99 17,306,849.76 173,890,208.78 222.28 14,014,697.42 + 11 77,626.22 859,917.21 17,255,012.02 191,145,220.80 222.28 13,972,720.38 + 12 77,345.52 937,262.73 17,192,616.14 208,337,836.94 222.28 13,922,193.60 + 13 77,021.56 1,014,284.29 17,120,605.40 225,458,442.34 222.28 13,863,880.93 + 14 76,659.30 1,090,943.59 17,040,081.18 242,498,523.53 222.28 13,798,674.23 + 15 76,263.89 1,167,207.48 16,952,186.81 259,450,710.33 222.28 13,727,499.34 + 16 75,840.32 1,243,047.80 16,858,034.91 276,308,745.24 222.28 13,651,257.25 + 17 75,393.28 1,318,441.08 16,758,665.93 293,067,411.17 222.28 13,570,790.49 + 18 74,927.04 1,393,368.11 16,655,027.43 309,722,438.60 222.28 13,486,866.37 + 19 74,445.39 1,467,813.51 16,547,966.62 326,270,405.23 222.28 13,400,170.93 + 20 73,951.72 1,541,765.22 16,438,231.02 342,708,636.25 222.28 13,311,309.51 + 21 73,448.95 1,615,214.17 16,326,473.66 359,035,109.91 222.28 13,220,810.92 + 22 72,939.63 1,688,153.81 16,213,260.66 375,248,370.57 222.28 13,129,133.58 + 23 72,425.96 1,760,579.76 16,099,079.76 391,347,450.33 222.28 13,036,672.46 + 24 71,909.81 1,832,489.57 15,984,349.02 407,331,799.35 222.28 12,943,766.08 + 25 71,392.80 1,903,882.37 15,869,425.07 423,201,224.42 222.28 12,850,703.25 + 26 70,876.27 1,974,758.64 15,754,610.85 438,955,835.27 222.28 12,757,729.29 + 27 70,361.40 2,045,120.04 15,640,162.58 454,595,997.86 222.28 12,665,051.65 + 28 69,849.14 2,114,969.18 15,526,295.96 470,122,293.82 222.28 12,572,845.02 + 29 69,340.31 2,184,309.49 15,413,191.67 485,535,485.49 222.28 12,481,255.72 + 30 68,860.68 2,253,170.17 15,306,577.89 500,842,063.38 222.28 12,394,922.28 diff --git a/tests/examples/S-DAC-GT.txt b/tests/examples/S-DAC-GT.txt index 9cf16ec8a..8c5892694 100644 --- a/tests/examples/S-DAC-GT.txt +++ b/tests/examples/S-DAC-GT.txt @@ -43,6 +43,7 @@ Economic Model,3, ---BICYCLE Levelized Cost Model Inflated Equity Interest Rate,.08, ---[-] Required for BICYCLE model Combined Income Tax Rate,.3, ---[-] Required for BICYCLE model Gross Revenue Tax Rate,0, ---[-] Required for BICYCLE model +S-DAC-GT Carbon Credit Price, 180.0, ---[USD/tonne CO2] 45Q tax credit rate or voluntary market price ***Simulation Parameters*** *************************** diff --git a/tests/test_geophires_x_client.py b/tests/test_geophires_x_client.py index f3f8fa873..25e26e5b1 100644 --- a/tests/test_geophires_x_client.py +++ b/tests/test_geophires_x_client.py @@ -590,18 +590,19 @@ def test_parse_sdacgt_profile(self): 'S-DAC-GT Annual Cost (USD/yr)', 'S-DAC-GT Cumm. Cash Flow (USD)', 'Cumm. Cost Per Tonne (USD/tonne)', + 'Annual Carbon Revenue (USD/yr)', ], ) # Values below need to be synchronized if S-DAC-GT example output values change. - self.assertEqual([1, 78330.8, 78330.8, 17411627.98, 17411627.98, 222.28], sdacgt_profile[1]) + self.assertEqual([1, 78330.8, 78330.8, 17411627.98, 17411627.98, 222.28, 14099544.46], sdacgt_profile[1]) self.assertEqual( - [15, 76263.89, 1167207.48, 16952186.81, 259450710.33, 222.28], + [15, 76263.89, 1167207.48, 16952186.81, 259450710.33, 222.28, 13727499.34], sdacgt_profile[15], ) - self.assertEqual([30, 68860.68, 2253170.17, 15306577.89, 500842063.38, 222.28], sdacgt_profile[30]) + self.assertEqual([30, 68860.68, 2253170.17, 15306577.89, 500842063.38, 222.28, 12394922.28], sdacgt_profile[30]) def test_parse_economic_model(self): result = GeophiresXResult(self._get_test_file_path('examples/example3.out'))