Skip to main content
DERP calculates potential separately by scenario, year and market division. This specification defines the stock and adoption calculations; use the financial calculations for the financial metrics that drive screening and adoption.

Indices and units

Market applicability (MAF) and market availability are separate factors. The former expresses how much of a market a measure can serve; the latter controls when an add-on market becomes available.

Calculation order

  1. Import measures, markets, programs, valuations, adoption curves and scenario selectors. Apply the measure run filter and year/scenario availability.
  2. Characterize savings and calculate per-unit cost-effectiveness for possible installation years.
  3. Form competition groups within divisions. Calculate technical potential with its own market attribution.
  4. Calculate economic potential with jurisdictional screening and a separate market attribution.
  5. Initialize adoption and program competition. Calculate achievable potential with its own attribution and optional screening.
  6. Within each year, calculate replacement/new installations, update markets, then calculate add-on sales.
  7. Aggregate cohort impacts and program results. In connected mode, apply DR writeback before final reporting.
Each potential has a separate market history. Economic and achievable potential are not obtained by multiplying technical totals by one final scalar.

Input and market initialization

The shared reader loads measure characterization and its time series, market characterization and scenario forecasts, program definitions/mappings, run settings, scenario selectors, rates, avoided costs, discount rates, taxes, line losses, emissions factors and adoption parameters. TBE_scenarios.market must select an existing attribute.scenario when market time series are supplied. Market identity includes baseline, region, sector, segment and unit; missing market attribution skips the competition group with an error log. Without a market time series, existing stock is initialized uniformly over the BB pre-study vintages at T0/BT_0/B units each. NEW-vintage market cohorts use growth + teardown in each study year. With cumulative time-series input TyT_y, the installation cohort assigned to year yy is Ty+1−TyT_{y+1}-T_y after forward-filling missing study years. Existing-vintage initial stock is still distributed over pre-study vintages; NEW-vintage input is not seeded that way. For existing-vintage markets without time series, annual growth is added to the current vintage. With positive teardown and more than one positive vintage, older cohorts are reduced by teardown / (count_positive_years - 1) and floored at zero. Time-series markets bypass this extra growth/teardown update. A cumulative forecast and a fixed annual growth assumption must not both be applied externally.

Installation cases and cohorts

Let BB be baseline useful life and btb_t the remaining market attributed to vintage tt. Non-ADD sales consume baseline market. ER sales remove eligible vintages successively using the implementation’s allocation loop. Remaining ROB/new attribution moves forward to the next year. Genuinely new participants enter matching upgrade markets at vintage y−1y-1, enabling downstream measures to use the changed technology stock. For an available non-assumed ROB/ER/new measure, before unit scaling: qm,y,s=max⁡(0,min⁡(Ay,AyMm,y,sam,y,s)).q_{m,y,s}=\max\left(0,\min\left(A_y,A_yM_{m,y,s}a_{m,y,s}\right)\right). Technical and economic calculations use a=1a=1 before their market/competition allocation. Achievable calculations use post-competition adoption for non-DR measures and participation multiplied by opt-in for DR measures. Zero units_per_division forces sales and adoption to zero. Scaled new sales are nnew=qumn^{new}=q u_m. Where re_participate_required applies, expiring participant cohorts contribute re-participation sales in addition to new participants. sales and new_participant_sales therefore need not be equal; market transfers use the latter.

Add-on availability and saturation

For ADD measures outside the achievable WTP/diffusion branch, a custom availability forecast takes precedence. Otherwise: vy=clip⁡(y−y0+1−kyB,0,1),Ay=Tyvy.v_y=\operatorname{clip}\left(\frac{y-y_0+1-k_y}{B},0,1\right),\qquad A_y=T_yv_y. The current code activates its screened-year correction kyk_y through the competition group’s all_measures_screened condition; it is not an unconditional subtraction for every screened year. Achievable WTP/diffusion uses total stock without this additional release factor because diffusion supplies the time dependence. For achievable non-assumed ADD sales, the calculation subtracts previous sales for the measure, current sales consumed within the group, and existing units from the adoption-adjusted addressable market, then floors at zero. Technical/economic ADD sales also cap against remaining group market. These branches are intentionally distinct from replacement sales. Assumed-adoption curves provide annual sales directly, keyed by curve, scenario and potential type.

Economic screening

For an available measure, economic screening passes if its jurisdictional test ratio is at least economic_threshold, or its applicable program screen override is true. Achievable potential applies the same screening only when screen_for_achievable is enabled. The DR dispatch screen uses PACT and is a separate decision.

Adoption curves

For a DOE barrier curve with maximum amaxa_{max}, parameters r,mid,fitr,mid,fit and selected participant benefit-cost ratio bb: a={amax((rb)−1+1)((mid b)−fit+1),b>0,0,b≤0.a=\begin{cases} \displaystyle\frac{a_{max}}{((rb)^{-1}+1)((mid\,b)^{-fit}+1)},&b>0,\\ 0,&b\leq0. \end{cases} Program barrier factors shift the selected barrier level, bounded by zero and the curve-set maximum. The curve configuration determines whether to use adjusted or unadjusted PCT benefit-cost ratio. For willingness-to-pay and diffusion: ey=e−(p+q+Δq)(y−t0),dy=1−ey1+(q/p)ey,wy=eAmin⁡(Py,30)+Bwtp,ay=dywy.e_y=e^{-(p+q+\Delta q)(y-t_0)},\qquad d_y=\frac{1-e_y}{1+(q/p)e_y},\qquad w_y=e^{A\min(P_y,30)+B_{wtp}},\qquad a_y=d_yw_y. Here PyP_y is participant payback. The implementation adds the program factor Δq\Delta q in the exponential while retaining the original q/pq/p in the denominator. Do not replace this with a different Bass formula when reproducing a run. Active program ramp factors multiply the resulting adoption. Within a measure competition group, ordinary non-DR achievable adoption is allocated as: amcomp=am∑jajmax⁡jaj.a_m^{comp}=\frac{a_m}{\sum_j a_j}\max_j a_j. A zero denominator gives zero adoption. DR takes its separate participation path. Winner-takes-all ordering and non-additive program competition are additional configured allocation stages, not interchangeable with this proportional expression. The winner ordering sums lifetime energy or demand savings across the relevant streams; electricity energy is converted from kWh to GJ for energy comparisons. Measures consume the remaining addressable market in descending score order, so a runner-up can serve market left by a higher-ranked measure with limited applicability.

Participation and programs

For the propensity path, annual and annual-per-kW participation incentives supply II. The curve uses (a0ln⁡(I+c0)+b0)/100(a_0\ln(I+c_0)+b_0)/100, clipped to [0,1][0,1], and returns zero when the logarithm domain is invalid. Program marketing factors select the propensity level; active ramp factors multiply participation. Sales use the result times (1−o)(1-o), where oo is the effective program opt-out rate. Programs can be additive or compete under configured groups, algorithms and tie-breakers. Resolve the applicable program mappings for the scenario and year before computing adoption. Counting the same eligible market independently for each program overstates participation.

Cohort impacts and reporting

For savings stream ff and active cohort ii: Qm,i,f,y=nm,i,s Sm,i,f,y,i≤y<i+Lm.Q_{m,i,f,y}=n_{m,i,s}\,S_{m,i,f,y},\qquad i\leq y<i+L_m. The Potential object retains per-unit streams and scaled streams. Despite the name, energy_savings_per_sales contains the product of per-unit savings and sales. Lifetime cost-effectiveness totals are also scaled by transacted sales. First-year reporting selects new cohort impacts. Lifetime reporting sums the cohort’s lifetime stream. Cumulative reporting aggregates applicable cohorts; persistence drop-off uses attribute.persistence, defaulting to EUL, and rejects a present invalid or non-positive value. Net/gross and customer/generator reporting transformations must be kept distinct from these cohort aggregations. Program reporting aggregates measure benefits and costs before calculating ratios and adds the applicable administrative costs. Maintain the requested fuel and power/energy units when comparing program results.

Implementation map

Financial calculations

DERP builds per-unit financial streams for each installation year and scenario before scaling them by potential. The configuration controls which streams enter each test and whether benefits, equipment costs and program costs use net or gross accounting.

Time and valuation

Let ii be installation year, LL useful life, ℓ=0,…,L−1\ell=0,\ldots,L-1 the lifetime index and hh an hour. The installation year’s hourly savings profile is repeated over the measure lifetime; the valuation changes with calendar year i+ℓi+\ell: Bi,ℓ,f=∑hSi,h,fRi+ℓ,h,f.B_{i,\ell,f}=\sum_h S_{i,h,f}R_{i+\ell,h,f}. The hourly valuation functions use 8,760-hour years. Align savings and valuation units before multiplication. Energy savings and demand savings are separate inputs. An annual energy quantity distributed over hours is not a coincident demand reduction. For distributed generation, the applicable electricity bill benefit combines self-consumed production at the customer rate and exported production at the compensation rate. With self-consumption fraction cc: Belec=∑hSh[cRh+(1−c)Ch].B_{elec}=\sum_h S_h\left[cR_h+(1-c)C_h\right]. Customer energy, demand and water bill savings; participant fixed benefits; incremental equipment and O&M costs; incentives; avoided costs; and societal impacts form separate streams. Cost forecast readers and lifetime expansion determine timing; do not substitute a generic recurring O&M schedule for the characterized input convention.

Incentives

Installation outside the program start/end interval receives no incentive from that program. Program-administrator and non-administrator incentives are tracked separately, with participation and other incentive subsets. Scenario selection and program mappings determine which incentives apply. The annual-per-kW branch uses annual series; it does not simply freeze the first-year product for every future year.

Avoided costs and societal streams

Electricity avoided energy costs combine savings with the selected avoided-cost categories and applicability percentages. Generator-level electricity effects incorporate the configured line-loss convention. Other fuels use their own energy/demand valuations. GHG avoided costs multiply hourly savings by the corresponding emissions factor and carbon valuation before annual aggregation: Bi,ℓGHG=∑hSi,hEFi+ℓ,hACi+ℓ,hGHG.B^{GHG}_{i,\ell}=\sum_h S_{i,h}EF_{i+\ell,h}AC^{GHG}_{i+\ell,h}. Water and non-energy impacts enter their configured streams. Avoided costs are selected using each measure’s valuation names and the relevant region, sector, segment and scenario selectors. A missing or mismatched series cannot be replaced by a valuation from another region merely because the fuel matches.

Configurable cost-effectiveness tests

DERP implements PCT, JST, PACT, TRC and SCT. TBE_ce_inclusion controls inclusion of participant, energy-system, society, program-administrator and other streams. TBE_net_or_gross controls the accounting basis separately for benefits, equipment and program costs. Use the configured matrix when reproducing a study rather than assuming a universal test definition. For test tt with discount rate rtr_t and assembled streams Bt,ℓ,Ct,ℓB_{t,\ell},C_{t,\ell}: PV(Bt)=∑ℓ=0L−1Bt,ℓ(1+rt)ℓ,PV(Ct)=∑ℓ=0L−1Ct,ℓ(1+rt)ℓ.PV(B_t)=\sum_{\ell=0}^{L-1}\frac{B_{t,\ell}}{(1+r_t)^\ell},\qquad PV(C_t)=\sum_{\ell=0}^{L-1}\frac{C_{t,\ell}}{(1+r_t)^\ell}. Before discounting, the cost array is floored elementwise at zero after subtracting the incentive credits enabled by the inclusion settings. For PCT, fixed participant benefits are added after the selected net/gross multiplication of the other benefit streams. These ordering rules matter when reproducing negative-cost or net-accounting cases. Installation-year cash flows have exponent zero. Net benefits are PV(Bt)−PV(Ct)PV(B_t)-PV(C_t). The test ratio is PV(Bt)/PV(Ct)PV(B_t)/PV(C_t) when costs are nonzero; it is positive infinity for positive benefits and zero costs, otherwise zero when costs are zero. JST drives DERP economic screening. PACT drives the DR dispatch screen and can be used for DR prioritization. These tests have different purposes and can produce different pass/fail results.

Participant benefit-cost ratio for adoption

The adoption BCR is a derived metric, distinct from the reported PCT ratio. Let II be discounted incentives, KK discounted raw equipment costs and cfc_f the incentive impact correction factor. The implementation uses: Define ρ=I/K\rho=I/K when K>0K>0, otherwise zero, and z=PCT(I+0.01)/(Kcf)z=PCT(I+0.01)/(Kc_f) when Kcf>0Kc_f>0, otherwise zero. Then: badj={PCT,ρ≥cf,z,ρ<cf.b_{adj}=\begin{cases}PCT,&\rho\geq c_f,\\z,&\rho<c_f.\end{cases} Residential measures additionally multiply the adjusted BCR by the ratio of discounted benefits over the first eul_adjustment_factor years to discounted lifetime benefits, when lifetime benefits are nonzero. The unadjusted metric remains available to curves configured to bypass adjustment.

Payback for adoption

Residential payback uses characterized first-year customer costs net of incentives and first-year energy, demand and water savings, including applicable sales tax. The implementation handles non-positive costs/savings explicitly, including infinity for non-paying measures, an inverse-payback branch when both are negative, and a minimum result of one year. For non-residential measures, the model builds lifetime customer cash flow and solves for IRR. A valid positive IRR gives the time to double capital: P=ln⁡2ln⁡(1+IRR).P=\frac{\ln2}{\ln(1+IRR)}. All-nonnegative cash flow gives one; all-nonpositive gives infinity. Non-positive IRR gives infinity. The negative-cost/negative-savings case checks cumulative cash flow and can use inverse cash-flow IRR with L−PinverseL-P_{inverse}. These are model adoption conventions, not interchangeable financial definitions of simple payback. WTP adoption caps the payback argument at 30 before applying its exponential curve.

Scaling and program results

Per-unit discounted benefits, costs and incentives are scaled by cohort sales. Program ratios are recomputed from aggregated benefits and costs after applicable fixed and variable administration costs. Variable costs use the configured target fuel and savings basis; electricity energy and demand require different conversion factors. For connected DR, writeback updates specific demand, participant-count, PACT and incentive results. It is not a second full recomputation of every DERP test from the dispatched load curve.

Implementation

Optional DR integration

DERP and DR can each run independently. Use their connected workflow when a DERP study should supply evolving resource markets to DR and receive dispatch-derived demand impacts in its final reports.

Execution boundary

The scenario pipeline starts a DERP calculation child, optionally a DR child when DR inputs are supplied, then a reporting child. In ordinary scenario execution, DERP-to-DR-to-report sequencing occurs within each scenario; separate scenario pipelines can run concurrently. Grid-level batch studies use the all-scenario route and reject restriction to a single scenario. The DERP child calculates potential and produces its report parts, retains DR measures for subsequent reporting, and prepares the DR handoff. The DR child imports its required study inputs and processes the handoff records. The reporting child applies writeback before joining DR and non-DR reports. Without the DR stage, DERP reports its characterized demand impacts. Standalone DR instead loads its own study inputs and writes its own results without a prior DERP potential run.

Match measures

The forward extraction matches a DERP measure to a DR characterization using normalized values of key, name, baseline, upgrade, unit, region, sector and segment. Unmatched records are skipped with a warning. Equal display names alone do not establish a match. The handoff carries measure identity, dispatch target, module type, geography, baseline/end use, program variants and year/scenario impacts. It also carries market applicability, propensity, opt-out, screen overrides, incentives, enrollment and applicable program mappings where available.

Use the correct unit denominator

The extraction aggregates the relevant market across baselines and resolves grid targets and program variants. Missing non-DR electricity savings skip that layering record; a DR resource can legitimately have no precomputed demand savings because dispatch supplies them. Multiplying a DR market by DERP annual sales would use the wrong denominator.

Handoff and result contracts

DERPToDRHandoff currently declares schema version 5, shared input paths and the directory containing serialized measure-savings records. Serialized year/scenario impacts hold units and scalar, array or absent per-unit hourly savings. The handoff is an internal execution contract, not a separately versioned public API. The DR writeback payload includes nested scenario/year/period placement records, measure/year/scenario cost-effectiveness results, emissions data and output power unit. Subprocess manifests communicate success/failure, error details, captured output and report-part paths. Do not treat a child failure manifest as a valid zero-impact study.

Select an impact for writeback

For each normalized measure/year/scenario key, writeback prefers the designated standalone peak period with peak day type. It uses independent per-unit and total peak impacts from that period. If that designation is unavailable, it falls back to effective stacked impacts from placed records and emits a warning. When several candidate records remain, the current selection ranks peak-period status first and per-unit impact second. It selects a record; it does not sum all periods, call-number results or program variants. Internal selection uses MW and removes the placement line-loss factor before converting to customer-level kW, with a missing or non-positive factor falling back to one: dunitcustomer=max⁡(0,1000dunitMWFloss),Dcustomer=max⁡(0,1000DMWFloss).d^{customer}_{unit}=\max\left(0,\frac{1000d^{MW}_{unit}}{F_{loss}}\right),\qquad D^{customer}=\max\left(0,\frac{1000D^{MW}}{F_{loss}}\right). This prevents DERP’s later generator reporting transformation from applying losses twice. Called units and propensity accompany the chosen impact.

Financial writeback

Cost-effectiveness keys can use measure_key::program. Writeback selects the matching placed program, a plain measure key, or a sole unambiguous variant. Ambiguous unmatched program variants are skipped with a warning. If a matching PACT result is unavailable, existing DERP PACT information is retained. The administrator incentive reconciliation separates the annual incentive’s per-kW component from the enrolled-unit component. In the implementation’s selected-record accounting, with customer peak savings per unit dunitcustomerd^{customer}_{unit} in kW, applied per-kW incentive ikWi_{kW}, annual incentive per enrolled unit II, enrolled units NeN_e and called units NcN_c: IPA=max⁡(0,(I−dunitcustomerikW)Ne+(dunitcustomerikW)Nc).I_{PA}=\max\left(0,(I-d^{customer}_{unit}i_{kW})N_e+(d^{customer}_{unit}i_{kW})N_c\right). Writeback updates the corresponding demand impacts, participant counts, propensity, selected PACT benefits/costs and administrator incentive result. It does not recalculate every participant, jurisdictional, resource and societal test from scratch after dispatch.

Reconcile a connected study

Check matching identities and scenario selectors first. Then compare total market, applicability, enrolled and called units on the same grid/program/year scope. Check whether the selected writeback impact came from the independent peak period or the fallback stacked impact. Finally reconcile customer/generator and kW/MW conventions before comparing DERP reports with raw DR placements. The execution implementation is in scenario pipeline, forward handoff and writeback service.