h2integrate.finances.numpy_financial_npv#

Classes

NumpyFinancialNPV(**kwargs)

OpenMDAO component for calculating Net Present Value (NPV) using the NumPy Financial.

NumpyFinancialNPVFinanceConfig(*, ...[, ...])

Configuration for NumpyFinancialNPVFinance.

class h2integrate.finances.numpy_financial_npv.NumpyFinancialNPVFinanceConfig(*, plant_life, real_discount_rate, debt_rate=0.0, debt_equity_ratio=0.0, inflation_rate=0.0, commodity_sell_price=0.0, commodity_sell_price_units, save_cost_breakdown=False, save_npv_breakdown=False, cost_breakdown_file_description='default')#

Configuration for NumpyFinancialNPVFinance.

Future cash flows are discounted using the nominal, pre-tax weighted average cost of capital (WACC):

WACC = equity_weight * equity_rate + debt_weight * debt_rate

where the equity and debt weights are derived from debt_equity_ratio (D/E) as equity_weight = 1 / (1 + D/E) and debt_weight = (D/E) / (1 + D/E). real_discount_rate is treated as the real equity rate and debt_rate as the real debt rate; both are converted from real to nominal via the Fisher equation before being combined:

(1 + nominal_rate) = (1 + real_rate) * (1 + inflation_rate)

The WACC is pre-tax: no interest tax shield is applied to the debt leg, which keeps the discount rate consistent with the pre-tax cash flows used by this component (revenues and costs are not tax-adjusted).

The multiplicative (Fisher) form is the exact relationship between real and nominal rates and matches how ProFAST combines its real rates and general_inflation inputs, keeping the two finance backends consistent. When inflation_rate is 0 (the default), the real rates are used as-is (and should be nominal rates if inflation effects are desired).

Variables:
  • plant_life (int) -- operating life of plant in years

  • real_discount_rate (float) -- real equity rate (cost of equity), expressed as a fraction between 0 and 1. Can be either a real or nominal rate depending on how inflation_rate is specified. A pre-computed WACC can also be supplied directly here by leaving debt_equity_ratio at 0.0 (so the WACC reduces to this rate) and setting inflation_rate to 0.0 (so it is used as-is without further Fisher adjustment).

  • debt_rate (float, optional) -- real debt rate (cost of debt), expressed as a fraction between 0 and 1. Converted to nominal via the Fisher equation when inflation_rate is provided. Defaults to 0.0.

  • debt_equity_ratio (float, optional) -- ratio of debt to equity (D/E) used to weight the debt and equity contributions to the WACC. Defaults to 0.0, in which case the WACC reduces to the equity rate.

  • inflation_rate (float, optional) -- inflation rate, expressed as a fraction between 0 and 1. Combined with the real equity and debt rates via the Fisher equation to form the nominal rates used in the WACC. Defaults to 0.0, in which case the real rates are used as-is (and should be nominal rates if inflation effects are desired).

  • commodity_sell_price (int | float, optional) -- sell price of commodity in USD/unit of commodity. Defaults to 0.0

  • commodity_sell_price_units (str) -- OpenMDAO unit string for commodity_sell_price (e.g. "USD/(kW*h)" for electricity or "USD/kg" for hydrogen). Required.

  • save_cost_breakdown (bool, optional) -- whether to save the cost breakdown per year. Defaults to False.

  • save_npv_breakdown (bool, optional) -- whether to save the npv breakdown per technology. Defaults to False.

  • cost_breakdown_file_description (str, optional) -- description to include in filename of cost breakdown file or npv breakdown file if either save_cost_breakdown or save_npv_breakdown is True. Defaults to 'default'.

Parameters:
  • plant_life (int)

  • real_discount_rate (float)

  • debt_rate (float)

  • debt_equity_ratio (float)

  • inflation_rate (float)

  • commodity_sell_price (int | float)

  • commodity_sell_price_units (str)

  • save_cost_breakdown (bool)

  • save_npv_breakdown (bool)

  • cost_breakdown_file_description (str)

plant_life: int#
real_discount_rate: float#
debt_rate: float#
debt_equity_ratio: float#
inflation_rate: float#
commodity_sell_price: int | float#
commodity_sell_price_units: str#
save_cost_breakdown: bool#
save_npv_breakdown: bool#
cost_breakdown_file_description: str#
class h2integrate.finances.numpy_financial_npv.NumpyFinancialNPV(**kwargs)#

OpenMDAO component for calculating Net Present Value (NPV) using the NumPy Financial.

This component computes the NPV of a given commodity-producing plant over its operational lifetime, accounting for capital expenditures (CAPEX), operating expenditures (OPEX), refurbishment/replacement costs, and commodity revenues.

NPV is calculated using the discount rate and plant life defined in the plant_config. By convention, investments (CAPEX, OPEX, refurbishment) are treated as negative cash flows, while revenues from commodity sales are positive. This follows the NumPy Financial convention:

Reference:

NumPy Financial NPV documentation: https://numpy.org/numpy-financial/latest/npv.html#numpy_financial.npv

By convention:
  • Investments or "deposits" are negative.

  • Income or "withdrawals" are positive.

  • Values typically start with the initial investment, so values[0] is often negative.

Variables:
  • NPV_str (str) -- The dynamically generated name of the NPV output variable, based on commodity_type and optional description.

  • tech_config (dict) -- Technology-specific configuration dictionary.

  • config (NumpyFinancialNPVConfig) -- Parsed financial configuration parameters (e.g., discount rate, plant life, save options).

initialize()#

Perform any one-time initialization run at instantiation.

setup()#

Declare inputs and outputs.

Available attributes:

name pathname comm options

compute(inputs, outputs)#

Compute the Net Present Value (NPV).

Calculates discounted cash flows over the plant lifetime, accounting for:
  • Revenue from annual commodity production and sale.

  • CAPEX and OPEX for all technologies.

  • Replacement or refurbishment costs if provided.

Optionally saves cost breakdowns and NPV breakdowns to CSV files if enabled in configuration.

NPV that is positive indicates a profitable investment, while negative NPV indicates a loss.

Parameters:
  • inputs (dict-like) -- Dictionary of input values, including production, CAPEX, OPEX, and optional replacement periods.

  • outputs (dict-like) -- Dictionary for storing computed outputs, including the NPV result.

Produces:
  • outputs[self.NPV_str]: The total NPV in USD.

Side Effects

  • Writes annual cost breakdown and NPV breakdown CSVs to the configured output directory if save_cost_breakdown or save_npv_breakdown is enabled.

Raises:
  • FileNotFoundError -- If the specified output directory cannot be created.

  • ValueError -- If refurbishment schedules cannot be derived from inputs.

_real_to_nominal_rate(real_rate)#

Convert a real rate to a nominal rate via the Fisher equation.

The Fisher equation is the exact multiplicative relationship between real and nominal rates (rather than the additive approximation r_nominal ~= r_real + inflation):

(1 + nominal_rate) = (1 + real_rate) * (1 + inflation_rate)

When inflation_rate is 0 (the default), the rate is returned unchanged. In that case no inflation adjustment is applied, so the effective rate remains the real rate rather than a nominal rate.

Parameters:

real_rate (float) -- The real rate to convert, expressed as a fraction.

Returns:

float -- The equivalent nominal rate.

_compute_wacc()#

Compute the nominal, pre-tax weighted average cost of capital (WACC).

The equity rate (real_discount_rate) and debt rate (debt_rate) are treated as real rates and converted to nominal rates via the Fisher equation using inflation_rate.

The nominal rates are then combined into the WACC using weights derived from the debt/equity ratio (D/E):

equity_weight = 1 / (1 + D/E) debt_weight = (D/E) / (1 + D/E) WACC = equity_weight * equity_rate + debt_weight * debt_rate

The WACC is pre-tax: no interest tax shield is applied to the debt leg, so the discount rate stays consistent with the pre-tax cash flows discounted by this component.

When debt_equity_ratio is 0 (the default), the WACC reduces to the equity rate. Note that when inflation_rate is 0, the Fisher conversion leaves the rates unchanged, so the resulting WACC is a real rate rather than a nominal one.

Returns:

float --

The WACC used to discount future cash flows. It is nominal when

inflation_rate is nonzero and real when inflation_rate is 0.

_save_cost_breakdown_files(cost_breakdown, npv_cost_breakdown, total_npv)#

Save cost breakdown and/or NPV breakdown to CSV files.

Creates CSV files containing detailed breakdowns of costs and NPV calculations for post-processing analysis and reporting.

Parameters:
  • cost_breakdown (dict) -- Dictionary mapping cost categories to annual cost arrays. Keys are category names (e.g., "wind: capital cost"), values are numpy arrays of costs per year (length = plant_life + 1).

  • npv_cost_breakdown (dict) -- Dictionary mapping cost categories to their NPV values. Keys are category names, values are floats representing discounted present value.

  • total_npv (float) -- The total NPV summed across all categories in USD.

File Formats:

NPV breakdown CSV: Single column with cost category as index and NPV as value. Cost breakdown CSV: Rows are cost categories, columns are years (Year 0, Year 1, etc.).