mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-06 07:48:50 -06:00
Add emission limits and penalties
This commit is contained in:
@@ -128,6 +128,19 @@ function parse(json)::Instance
|
||||
plants_by_name[name] = plant
|
||||
end
|
||||
|
||||
# Read emissions
|
||||
emissions = Emissions[]
|
||||
emissions_by_name = OrderedDict{String,Emissions}()
|
||||
if haskey(json, "emissions")
|
||||
for (name, edict) in json["emissions"]
|
||||
limit = timeseries(edict["limit (tonne)"], null_val = Inf)
|
||||
penalty = timeseries(edict["penalty (\$/tonne)"])
|
||||
emission = Emissions(; name, limit, penalty)
|
||||
push!(emissions, emission)
|
||||
emissions_by_name[name] = emission
|
||||
end
|
||||
end
|
||||
|
||||
return Instance(;
|
||||
time_horizon,
|
||||
building_period,
|
||||
@@ -138,5 +151,7 @@ function parse(json)::Instance
|
||||
centers_by_name,
|
||||
plants,
|
||||
plants_by_name,
|
||||
emissions,
|
||||
emissions_by_name,
|
||||
)
|
||||
end
|
||||
|
||||
@@ -54,6 +54,12 @@ Base.@kwdef struct Plant
|
||||
initial_capacity::Float64
|
||||
end
|
||||
|
||||
Base.@kwdef struct Emissions
|
||||
name::String
|
||||
limit::Vector{Float64}
|
||||
penalty::Vector{Float64}
|
||||
end
|
||||
|
||||
Base.@kwdef struct Instance
|
||||
building_period::Vector{Int}
|
||||
centers_by_name::OrderedDict{String,Center}
|
||||
@@ -64,4 +70,6 @@ Base.@kwdef struct Instance
|
||||
time_horizon::Int
|
||||
plants::Vector{Plant}
|
||||
plants_by_name::OrderedDict{String,Plant}
|
||||
emissions_by_name::OrderedDict{String,Emissions}
|
||||
emissions::Vector{Emissions}
|
||||
end
|
||||
|
||||
@@ -119,15 +119,15 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
||||
end
|
||||
|
||||
# Transportation emissions by greenhouse gas
|
||||
z_tr_em = _init(model, :z_tr_em)
|
||||
z_em_tr = _init(model, :z_em_tr)
|
||||
for (p1, p2, m) in E, t in T, g in keys(m.tr_emissions)
|
||||
z_tr_em[g, p1.name, p2.name, m.name, t] = @variable(model, lower_bound = 0)
|
||||
z_em_tr[g, p1.name, p2.name, m.name, t] = @variable(model, lower_bound = 0)
|
||||
end
|
||||
|
||||
# Plant emissions by greenhouse gas
|
||||
z_plant_em = _init(model, :z_plant_em)
|
||||
z_em_plant = _init(model, :z_em_plant)
|
||||
for p in plants, t in T, g in keys(p.emissions)
|
||||
z_plant_em[g, p.name, t] = @variable(model, lower_bound = 0)
|
||||
z_em_plant[g, p.name, t] = @variable(model, lower_bound = 0)
|
||||
end
|
||||
|
||||
|
||||
@@ -192,6 +192,30 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
||||
)
|
||||
end
|
||||
|
||||
# Emissions penalty cost
|
||||
for emission in instance.emissions, t in T
|
||||
# Plant emissions penalty
|
||||
for p in plants
|
||||
if emission.name in keys(p.emissions)
|
||||
add_to_expression!(
|
||||
obj,
|
||||
emission.penalty[t],
|
||||
z_em_plant[emission.name, p.name, t],
|
||||
)
|
||||
end
|
||||
end
|
||||
# Transportation emissions penalty
|
||||
for (p1, p2, m) in E
|
||||
if emission.name in keys(m.tr_emissions)
|
||||
add_to_expression!(
|
||||
obj,
|
||||
emission.penalty[t],
|
||||
z_em_tr[emission.name, p1.name, p2.name, m.name, t],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@objective(model, Min, obj)
|
||||
|
||||
# Constraints
|
||||
@@ -323,25 +347,41 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
||||
end
|
||||
|
||||
# Transportation emissions
|
||||
eq_tr_em = _init(model, :eq_tr_em)
|
||||
eq_emission_tr = _init(model, :eq_emission_tr)
|
||||
for (p1, p2, m) in E, t in T, g in keys(m.tr_emissions)
|
||||
eq_tr_em[g, p1.name, p2.name, m.name, t] = @constraint(
|
||||
eq_emission_tr[g, p1.name, p2.name, m.name, t] = @constraint(
|
||||
model,
|
||||
z_tr_em[g, p1.name, p2.name, m.name, t] ==
|
||||
z_em_tr[g, p1.name, p2.name, m.name, t] ==
|
||||
distances[p1, p2, m] * m.tr_emissions[g][t] * y[p1.name, p2.name, m.name, t]
|
||||
)
|
||||
end
|
||||
|
||||
# Plant emissions
|
||||
eq_plant_em = _init(model, :eq_plant_em)
|
||||
eq_emission_plant = _init(model, :eq_emission_plant)
|
||||
for p in plants, t in T, g in keys(p.emissions)
|
||||
eq_plant_em[g, p.name, t] = @constraint(
|
||||
eq_emission_plant[g, p.name, t] = @constraint(
|
||||
model,
|
||||
z_plant_em[g, p.name, t] ==
|
||||
z_em_plant[g, p.name, t] ==
|
||||
p.emissions[g][t] * sum(y[src.name, p.name, m.name, t] for (src, m) in E_in[p])
|
||||
)
|
||||
end
|
||||
|
||||
# Global emissions limit
|
||||
eq_emission_limit = _init(model, :eq_emission_limit)
|
||||
for emission in instance.emissions, t in T
|
||||
isfinite(emission.limit[t]) || continue
|
||||
eq_emission_limit[emission.name, t] = @constraint(
|
||||
model,
|
||||
sum(
|
||||
z_em_plant[emission.name, p.name, t] for
|
||||
p in plants if emission.name in keys(p.emissions)
|
||||
) + sum(
|
||||
z_em_tr[emission.name, p1.name, p2.name, m.name, t] for
|
||||
(p1, p2, m) in E if emission.name in keys(m.tr_emissions)
|
||||
) <= emission.limit[t]
|
||||
)
|
||||
end
|
||||
|
||||
if variable_names
|
||||
_set_names!(model)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user