Skip to content

Commit a732f55

Browse files
authored
Fix errors in the calculation of costs (#563)
* Fix calculation of material costs * Fix calculation of variable costs * Revert change to output * Fix error in variable cost calculation * Fix consumption function to allow non-1 outputs * Revert "Fix consumption function to allow non-1 outputs" This reverts commit c9d4c3e. * One more material costs error * Better name for tech_activity * Fix error in fixed and variable costs * Select products only when calculating variable costs
1 parent 9096109 commit a732f55

2 files changed

Lines changed: 61 additions & 32 deletions

File tree

src/muse/costs.py

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ def net_present_value(
9191
products = is_enduse(technologies.comm_usage)
9292
fuels = is_fuel(technologies.comm_usage)
9393

94+
# Calculate consumption
95+
cons = consumption(technologies=techs, production=production, prices=prices)
96+
9497
# Revenue
9598
prices_non_env = filter_input(prices, commodity=products, year=years.values)
9699
raw_revenues = (production * prices_non_env * rates).sum(("commodity", "year"))
@@ -112,34 +115,41 @@ def net_present_value(
112115

113116
# Fuel/energy costs
114117
prices_fuel = filter_input(prices, commodity=fuels, year=years.values)
115-
fuel = consumption(technologies=techs, production=production, prices=prices)
116-
fuel_costs = (fuel * prices_fuel * rates).sum(("commodity", "year"))
118+
fuel_costs = (cons * prices_fuel * rates).sum(("commodity", "year"))
117119

118120
# Cost related to material other than fuel/energy and environmentals
119121
prices_material = filter_input(prices, commodity=material, year=years.values)
120-
material_costs = (production * prices_material * rates).sum(("commodity", "year"))
122+
material_costs = (cons * prices_material * rates).sum(("commodity", "year"))
121123

122-
# Fixed and Variable costs
123-
fixed_costs = convert_timeslice(
124-
techs.fix_par * (capacity**techs.fix_exp),
125-
prices.timeslice,
126-
QuantityType.EXTENSIVE,
124+
# Fixed costs
125+
fixed_costs = (
126+
convert_timeslice(
127+
techs.fix_par * (capacity**techs.fix_exp),
128+
prices.timeslice,
129+
QuantityType.EXTENSIVE,
130+
)
131+
* rates
132+
).sum("year")
133+
134+
# Variable costs
135+
tech_activity = (production.sel(commodity=products) / techs.fixed_outputs).max(
136+
"commodity"
127137
)
128-
variable_costs = techs.var_par * (
129-
(production.sel(commodity=products).sum("commodity")) ** techs.var_exp
138+
variable_costs = ((techs.var_par * tech_activity**techs.var_exp) * rates).sum(
139+
"year"
130140
)
131-
assert set(fixed_costs.dims) == set(variable_costs.dims)
132-
fixed_and_variable_costs = ((fixed_costs + variable_costs) * rates).sum("year")
133141

134-
results = raw_revenues - (
142+
# Net present value
143+
result = raw_revenues - (
135144
installed_capacity_costs
136145
+ fuel_costs
137146
+ environmental_costs
138147
+ material_costs
139-
+ fixed_and_variable_costs
148+
+ fixed_costs
149+
+ variable_costs
140150
)
141151

142-
return results
152+
return result
143153

144154

145155
def net_present_cost(
@@ -259,6 +269,9 @@ def lifetime_levelized_cost_of_energy(
259269
products = is_enduse(technologies.comm_usage)
260270
fuels = is_fuel(technologies.comm_usage)
261271

272+
# Calculate consumption
273+
cons = consumption(technologies=techs, production=production, prices=prices)
274+
262275
# Cost of installed capacity
263276
installed_capacity_costs = convert_timeslice(
264277
techs.cap_par * (capacity**techs.cap_exp),
@@ -276,31 +289,47 @@ def lifetime_levelized_cost_of_energy(
276289

277290
# Fuel/energy costs
278291
prices_fuel = filter_input(prices, commodity=fuels, year=years.values)
279-
fuel = consumption(technologies=techs, production=production, prices=prices)
280-
fuel_costs = (fuel * prices_fuel * rates).sum(("commodity", "year"))
292+
fuel_costs = (cons * prices_fuel * rates).sum(("commodity", "year"))
281293

282294
# Cost related to material other than fuel/energy and environmentals
283295
prices_material = filter_input(prices, commodity=material, year=years.values)
284-
material_costs = (production * prices_material * rates).sum(("commodity", "year"))
296+
material_costs = (cons * prices_material * rates).sum(("commodity", "year"))
285297

286-
# Fixed and Variable costs
287-
fixed_costs = convert_timeslice(
288-
techs.fix_par * (capacity**techs.fix_exp),
289-
prices.timeslice,
290-
QuantityType.EXTENSIVE,
298+
# Fixed costs
299+
fixed_costs = (
300+
convert_timeslice(
301+
techs.fix_par * (capacity**techs.fix_exp),
302+
prices.timeslice,
303+
QuantityType.EXTENSIVE,
304+
)
305+
* rates
306+
).sum("year")
307+
308+
# Variable costs
309+
tech_activity = (production.sel(commodity=products) / techs.fixed_outputs).max(
310+
"commodity"
291311
)
292-
variable_costs = (
293-
techs.var_par * production.sel(commodity=products) ** techs.var_exp
294-
).sum("commodity")
295-
fixed_and_variable_costs = ((fixed_costs + variable_costs) * rates).sum("year")
296-
denominator = production.where(production > 0.0, 1e-6)
312+
variable_costs = ((techs.var_par * tech_activity**techs.var_exp) * rates).sum(
313+
"year"
314+
)
315+
316+
# Production
317+
prod = (
318+
production.where(production > 0.0, 1e-6)
319+
.sel(commodity=products)
320+
.sum("commodity")
321+
)
322+
total_prod = (prod * rates).sum("year")
323+
324+
# LCOE
297325
result = (
298326
installed_capacity_costs
299327
+ fuel_costs
300328
+ environmental_costs
301329
+ material_costs
302-
+ fixed_and_variable_costs
303-
) / (denominator.sel(commodity=products).sum("commodity") * rates).sum("year")
330+
+ fixed_costs
331+
+ variable_costs
332+
) / total_prod
304333

305334
return result
306335

src/muse/outputs/mca.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ def sectory_consumption(
694694
def metric_fuel_costs(
695695
market: xr.Dataset, sectors: list[AbstractSector], **kwargs
696696
) -> pd.DataFrame:
697-
"""Current lifetime levelised cost across all sectors."""
697+
"""Current fuel costs across all sectors."""
698698
return _aggregate_sectors(sectors, market, op=sector_fuel_costs)
699699

700700

@@ -878,7 +878,7 @@ def sector_emission_costs(
878878
def metric_lcoe(
879879
market: xr.Dataset, sectors: list[AbstractSector], **kwargs
880880
) -> pd.DataFrame:
881-
"""Current emission costs across all sectors."""
881+
"""Current lifetime levelised cost across all sectors."""
882882
return _aggregate_sectors(sectors, market, op=sector_lcoe)
883883

884884

0 commit comments

Comments
 (0)