Variable and Emission Cost Accounting
There appears to be an issue with how variable costs (and emission costs) are represented in the objective function.
Some background:
- Decision Variables in Temoa: Temoa has two main sets of decision variables: those related to capacity ("V_Capacity") and those related to dispatch ("V_FlowOut"). These variables are connected through several equations, including the Capacity_Constraint (discussed further below).
- Modeling Discrete Future Years: Temoa typically models a discrete set of future years (e.g., 2020, 2025, 2030, etc.).
- Accounting for End-of-Life Technologies: Temoa includes logic to account for situations where technologies reach their end-of-life during the middle of a model period (e.g., in 2023). In such cases, the effective capacities—and consequently, the dispatch—of these technologies are scaled down proportionally to the fraction of the model period during which they are active (e.g., for 2023 in a 2020–2025 period, the fraction would be 3/5=0.6).
Some notes on variable names
-
ModelProcessLife, orMPL, represents the number of years during the period in question over which the technology remains operational. This is the lesser of the period length and the remaining process lifetime of the technology. For example, in the case above, MPL would be min(5,3)=3. -
ProcessLifeFracis the fraction representing the ratio of the two arguments in MPL, e.g., 3/5=0.6.
Guts
The Capacity_Constraint is as follows:
capacity * value(M.CapacityToActivity[r, t]) * value(M.SegFrac[s, d]) * value(M.ProcessLifeFrac[r, p, t, v]) * M.V_Capacity[r, p, t, v] >= useful_activity
If we assume the technology only has one input commodity and one output commodity, and if we assume this technology is not governed by capacity factors, this simplifies to:
1 * value(M.CapacityToActivity[r, t]) * value(M.SegFrac[s, d]) * value(M.ProcessLifeFrac[r, p, t, v]) * M.V_Capacity[r, p, t, v] >= M.V_FlowOut[r, p, s, d, i, t, v, o]
This implies the following:
- The capacity-related decision variables, V_Capacity, are the total, nameplate capacity without any end-of-life scaling applied.
- The activity of the technology, V_FlowOut, takes into account end-of-life scaling (by the inclusion of ProcessLifeFrac).
OK. So this brings us to the objective function.
Fixed Costs Notes:
- I'm going to use code from v2 of Temoa, where the cost logic is a little more explicit/clear.
- I'm also omitting the for loops over the indexed parameters for clarity.
- And we're assuming the global discount rate is 0%.
fixed_costs = sum( M.V_Capacity[r, p, S_t, S_v] * ( value(M.CostFixed[r, p, S_t, S_v]) * ( value(MPL[r, p, S_t, S_v]) ) )
Here, we see the fixed costs are scaled by MPL, which makes sense. We take the capacity, V_Capacity, which has not yet been scaled for end-of-life effects, and scale it by MPL. Logic: you pay fixed costs only in the years in which that technology exists.
Variable Costs
variable_costs = sum( M.V_FlowOut[r, p, s, d, S_i, S_t, S_v, S_o] * ( value(M.CostVariable[r, p, S_t, S_v]) * ( value(MPL[r, p, S_t, S_v]) ) )
Here, we see the variable costs are scaled by MPL as well. And I believe this is a bug. The activity (V_FlowOut) has already taken into account the end-of-life effects by the presence of PLF in the Capacity_Constraint. Therefore, it should be multiplied here by the period length (e.g., 5 years), not the MPL (e.g., 3 years).
Example Let's imagine an NGCC plant w/ 1 GW capacity operating in a model period of length 5 years (e.g. 2020-2025) and the technology reaches its EOL 3 years into that period (2023). Then we have:
- MPL = 3
- PLF = 3/5 = 0.6
Capacity constraint:
value(M.CapacityToActivity[r, t]) * value(M.SegFrac[s, d]) * value(M.ProcessLifeFrac[r, p, t, v]) * M.V_Capacity[r, p, t, v] >= M.V_FlowOut[r, p, s, d, i, t, v, o]
simplifies to:
8760 GWh/GW * 1/8760 * 0.6 * 1 GW >= M.V_FlowOut
which is equivalent to
V_FlowOut <= 0.6 GWh
This makes sense. That plant can operate at it's namplelate capacity of 1 GW in 3 of the 5 years, resulting in an average annual activity of 0.6 GWh.
Given that, the objective function should multiply this activity by the period length (5 years = 3 GWh), and not the MPL of 3 years (1.8 GWh).
Impact Fairly minimal. This bug effectively discounts variable costs for technologies in the model period in which they reach their EOL. This discount is proportional to its MPL.
Proposed Fix
Fairly straightforward. The MPL parameter in the variable cost and emission cost logic within the objective function should be replaced by the period length, M.PeriodLength[p]