heat_rate¶
Piecewise-linear heat rates (convex, no UC required).
Standard CEM/PCM addition for thermal generators: their fuel-burn- per-MWh isn't constant across the operating range. Above the design point, marginal heat rate increases (each additional MWh costs more fuel than the previous one). LP-friendly approximation: split the operating range into K segments with monotone-non-decreasing multipliers, force the dispatch to use the cheapest segment first.
The convexity matters: with non-decreasing multipliers across ascending output ranges, the LP optimum naturally fills segments in order (cheapest first) without any binary ordering constraints. Real heat-rate curves below the design point (where part-load losses dominate) are concave -- those can only be modelled with no- load + startup costs in the UC overlay (v1.15+).
Inputs¶
tech_heat_rate.csv (table format) -- one row per (tech,
segment), with columns:
tech-- technology namesegment-- integer index (1, 2, 3, ...)frac_max-- cumulative cap fraction at the upper edge of this segment (e.g., 0.5 for segment 1 means "0-50 % of cap"). Segments must form a partition:frac_maxstrictly increasing, last value = 1.0.multiplier-- relative heat rate within this segment, 1.0 == baseline (whatevertech_fuel_pricealready implies). The multiplier sequence MUST be non-decreasing for LP convexity.
Techs not listed in the CSV keep the v1.18 single-rate fuel cost
(fuel_price * gen). Mixing piecewise and flat-rate techs is
fine.
Constraints¶
Per (h, m, y, z, te) in the heat-rate set:
sum-to-gen:
sum_s gen_segment[h, m, y, z, te, s] == gen[h, m, y, z, te]per-segment width:
gen_segment[..., s] <= width[s] * cap_existing[y, z, te] * dt
where width[s] = frac_max[s] - frac_max[s-1].
Fuel cost replaces the flat fuel_price * gen with:
fuel_price[te, y] * sum_s multiplier[s] * gen_segment[..., s]
NPV-discounted via var_factor[y, z] and divided by weight,
identical to the rest of cost_var.
Config¶
cost_parameters.is_piecewise_heat_rate(bool, default False). When False, the module is a no-op and PREP-SHOT keeps the v1.18 flat-rate behaviour byte-for-byte.
- class prepshot._model.heat_rate.AddHeatRateConstraints(model)[源代码]¶
基类:
objectPiecewise-linear heat rate, opt-in.
- 参数
model (object) --
- prepshot._model.heat_rate.add_heat_rate_fuel_cost(model)[源代码]¶
Per-segment fuel cost contribution, NPV-discounted.
For each tech with a heat-rate curve, the fuel cost becomes:
fuel_price[te, y] * sum_s multiplier[s] * gen_segment[..., s]
summed over (h, m, y, z), discounted by
var_factor[y, z], and divided byweight. Returned as an ExprBuilder. Returns a zero ExprBuilder when the module is disabled or no heat-rate curves are loaded.The CALLER (
cost.var_cost_rule) must remove the corresponding techs' contribution from the existing flat-ratefuel_cost_breakdownto avoid double-counting -- handled by skipping those techs in the originalfuel_cost_breakdownloop whenhasattr(model, 'gen_segment')and the tech is insegments_by_tech.- 返回类型
ExprBuilder