Input and indexing contracts
The workbook’sScenarios sheet selects segments. Technology sheets define system sizes, CAPEX, OPEX, maximum markets, incentives, profiles, financing and adoption parameters. Parameter sheets use Input; annual sheets use Year. Sector Selector and the newer storage-incentive sheets have optional handling; absence of other directly indexed sheets or required segment columns raises lookup errors.
Each acquisition year has a lifetime cash-flow column, including time zero. Forecast arrays include an initial installed-system observation plus subsequent adoption years. The number of forecast positions, project-life rows and tariff years must align; tariff and cost series must cover late purchases’ lifetime slices.
The CLI parses
--inputs-folder but main passes the module’s configured workbook constant directly to import_data. Changing the flag does not change that imported path. Programmatic import accepts a path. This specification does not assume that the parsed CLI option is connected to execution.
Solar generation and compensation
For acquisition year , interval profile and PV size : is export and self-consumption. Lifetime production multipliers are calculated with-npf.pv(r, age, 0, 1), equivalent to ; this is not algebraically identical to . Net metering values exports and self-consumption at the selected time-dependent tariff before applying the lifetime multiplier and tax handling. Net billing distinguishes exported and consumed energy; feed-in compensation uses the selected contractual compensation branch. Tariff periods use month/hour masks and annual escalation series rather than a single annual blended price.
Capital, operating and financing cash flows
PV installation cost is size × CAPEX × . Storage cost includes storage kW × discharge-duration hours × CAPEX and applicable replacement costs. The solar-plus-storage branch explicitly handles zero, one or two storage replacements using future CAPEX positions and the storage-life interval. Cost coverage beyond the forecast is therefore required. Direct purchase, loan and other financing branches build different lifetime cash flows. Financing terms, down payments, interest, taxes, incentives and annual operation are not interchangeable. The cash-flow components are combined before payback and adoption; incentives must not be subtracted a second time in downstream analysis.Exact financing branches
Let be the installation cost for acquisition year , its downpayment fraction, payment duration and rate. With positive principal , annualnpf.pmt uses for nonzero , and at zero rate.
Direct Purchase: financing is at time zero and zero in subsequent project-life rows.Lease: time zero is ; the next rows contain the lease payment. The financed principal is , where these OPEX cash flows are negative. The code uses the OPEX slice after the lease duration in this principal. This is the implemented calculation, not a conventional lease valuation assumption.- Any other financing string enters the loan branch: time zero is ; the next rows contain . The rate is selected by acquisition-year label and customer type from
Loan_Rate, rather than one scalar rate for all purchases.
purchase frame. Payment durations can therefore extend the aligned output if they exceed project life. Operating cash flow is calculated separately; the lease-specific removal of early OPEX must be retained when reproducing the combined cash flows.
Storage applications and limitations
Storage revenues and demand-charge savings follow the selected application and technology branches. The self-consumption branch uses the first supplied storage-size row, converts kW × duration to energy capacity, charges from PV exports and discharges into imports subject to the kW limit. Its recurrence is: This expression assumes the one-hour intervals used by the implementation. State of charge resets at the simulated year’s start. The recurrence does not include an explicit round-trip-efficiency multiplier. Actual delivered benefits are derived from changes in bounded state of charge, not the unconstrained requested flow. Do not describe this branch as an optimized tariff-arbitrage dispatch. Other application branches calculate peak/demand-response revenues separately and must not be silently added as unconstrained simultaneous uses.Financial response and maximum market
For purchase and loan cases, the adoption response uses alternative payback , clipped to project life. Residential purchase-payback reporting instead locates the last upward zero crossing in cumulative cash flow and interpolates the crossing. Non-residential purchase-payback uses after clipping negative IRR to zero. Standalone storage scales clipped 15-year payback to the configured project life. This exponential response is not additionally clipped to one in that branch. Coefficients must yield meaningful fractions. For other financing options, let be year-one net bill savings divided by the original bill. Then: The exact-zero result follows strict branch masks.nan_to_num is applied to the resulting financing-market fraction; this does not validate zero original bills or undefined financial metrics elsewhere.
Diffusion and pre-competition adoption
Set equivalent time initially fromTime in Market, then advance it by one every forecast step, including when maximum market declines. The Bass fraction includes a two-period offset:
None or No leaves unchanged. Low, Moderate and High use with per array step. Other transformation strings raise an error. Candidate cumulative adoption is , with existing installations prepended. Apply a running maximum to keep the pre-competition series nondecreasing.