CO2 Emissions And Carbon Tax
This example adds a CO2 carrier, a CO2 node, a linked CO2 emission flow, and a carbon tax. The emission factor is 0.4 tCO2/MWh.
julia> begin
using Nosy
using HiGHS
import JuMP: set_silent
s = Sim(Model(HiGHS.Optimizer); mesh=TimeMesh())
set_silent(model(s))
elec_carrier = EnergyCarrier("power", s)
co2_carrier = CO2Carrier("co2", s)
hours = 1:8760
day_angle = 2pi .* ((hours .- 1) .% 24) ./ 24
season_angle = 2pi .* (hours .- 1) ./ 8760
load_profile = 3000 .+ 1500 .* sin.(day_angle .- pi / 2) .+
120 .* sin.(season_angle .- pi / 2)
snapshot = Snapshot(s)
grid = Node("grid", elec_carrier, rule=:curtailed)
co2_node = Node("co2", co2_carrier, rule=:curtailed)
consumption = Component("consumption", Demand(elec_carrier, load_profile))
connect!(snapshot, consumption, grid)
gasplant = Component(
"gasplant",
DispatchableSource(elec_carrier),
[
LinkedJointFlow("co2", co2_carrier, :output, "output", x -> 0.4 .* x[1]),
VariableCapacity("output", energy),
FixedCost(:capex, "output", energy, 60_000.0),
VariableCost(:fuel, "output", energy, 50.0),
VariableCost(:co2tax, "co2", co2, 100.0),
],
)
connect!(snapshot, gasplant, grid, "output")
connect!(snapshot, gasplant, co2_node, "co2")
optimize!(snapshot, cost(snapshot))
result = extract(snapshot)
end;
Expected results:
julia> costs(result)
3×5 DataFrame
Row │ component capex co2tax fuel total
│ String Float64 Float64 Float64 Float64
─────┼───────────────────────────────────────────────────
1 │ consumption 0.0 0.0 0.0 0.0
2 │ gasplant 2.772e8 1.0512e9 1.314e9 2.6424e9
3 │ all 2.772e8 1.0512e9 1.314e9 2.6424e9
julia> balance(result, "gasplant", :output, co2; collapse=true, aggregate=true)
1.0512000000000114e7
julia> balance(result, "gasplant", :output, mass; collapse=true, aggregate=true)
1.0512000000000114e7The CO2 flow is a normal port from the point of view of costs and balances. For CO2Carrier, co2 and mass return the same physical quantity.