Renewable generation constraint

Hello all,

I have posted an earlier question on coding renewable generation constraints with availability factors. I am still stuck with the problem. I have reverted back to bare basics, but i still receive keyErrors. A sample of the dispatch code is below and data is available on the link.

using JuMP, Clp
using DataFrames, CSV
#Load data
generators = DataFrame(CSV.File(joinpath(inputs_path, "plants_aggregation.csv")))
generators = select(generators, :R_ID, :plant_type, :node, :node_id, :g_max, :cost, :Conventional,:ROR, :WIND, :SOLAR)
demand_inputs = DataFrame(CSV.File(joinpath(inputs_path, "demand_2018.csv")))
demand = select(demand_inputs, :Load_z1, :Load_z2, :Load_z3, :Load_z4, :Load_z5, :Load_z6, :Load_z7, :Load_z8, :Load_z9, :Load_z10, :Load_z11)

variability = DataFrame(CSV.File(joinpath(inputs_path, "Generators_variability.csv")))
variability = variability[:,2:ncol(variability)]

network = DataFrame(CSV.File(joinpath(inputs_path, "Network.csv")))
zones = collect(skipmissing(network.Network_zones))

lines = select(network[1:9,:], 
    :Network_lines, :z1, :z2, :z3, :z4, :z5, :z6, :z7, :z8, :z9, :z10, :z11, 
    :f_max, :Line_Min_Flow_MW)
# Sets
G = generators.R_ID #all generators
T = convert(Array{Int64}, demand_inputs.time_index) #time
Z = convert(Array{Int64}, 1:11) #zones
L = convert(Array{Int64}, lines.Network_lines) #lines

C = generators.R_ID[generators.Conventional.==1] #conventional generators

WND = intersect(generators.R_ID[generators.WIND.==1], G) #wind resources

SOL = intersect(generators.R_ID[generators.SOLAR.==1], G) #solar resources

ROR = intersect(generators.R_ID[generators.ROR.==1], G) #Run-Of-River

#Define model
Dispatch_Model =  Model(Clp.Optimizer)

#Decission variables

@variable(Dispatch_Model, vGEN[c in C, T] >=0) #Conventional plant generation
@variable(Dispatch_Model, vFLOW[T, L] ) #Line power flow
@variable(Dispatch_Model, vRUNOFRIVER[r in ROR, T] >=0) #run-of-river
@variable(Dispatch_Model, vSOLAR[s in SOL, T] >=0) #solar
@variable(Dispatch_Model, vWIND[w in WND, T] >=0) #wind

@constraint(Dispatch_Model, cMaxPower[c in C, t in T], 
        vGEN[c,t] <= generators[generators.R_ID .== c,:g_max][1])

#Renewable injection constraints

@constraint(Dispatch_Model, cSolarInjection[t in T, s in  SOL], vSOLAR[t,s] <= generators[s,:g_max] * variability[t,s])

#Same constraints for wind and ROR

My main problem still lies with coding renewable generation constraints (solar, wind, and ROR). For now in the variability csv files, each renewable resource has a time series of capacity factors instead of the zonal capacity factor (my previous attempt).What I am still trying to obtain is output for my renewables (solar, wind etc,), over time and across the zones.


Data file: Sample_Data - Google Drive

So some general tips when trying to debug this (and post questions):

  • Simply the example to the minimum. The smaller the example, the easier it is for someone to provide advice. Moreover, the act of simplifying can often help you figure out the problem!
    • Comment out all variables and constraints that don’t directly lead to the error
    • Simplify the data. Remove all constants that don’t directly lead to the error
    • Remove all packages that don’t directly lead to the error (e.g., you probably don’t need Clp to reproduce this)
  • Provide the full text of the error message
    • Usually someone can figure out the problem by looking at the error without having to run the code
  • Make it so that someone can copy-paste the example and reproduce the error
    • It’s great that you provided the data, but it’s still an extra step for someone to take before they can help. Which parts are necessary, and which parts can be omitted/

Thanks for the helpful tips @odow. Below is hopefully a much more simplified version of the problem;

#using DataFrames

generators = DataFrame(index = ["conventional_gas", "conventional_nuc", "West_A_Wind", "Central_C_Wind", "North_D_Wind", 
                                "West_A_ROR", "Central_C_ROR", "North_D_ROR"], R_ID = 1:8, node_id = [1,2,1,2,3,1,2,3],
                                g_max = [100,250,40,60,80,30,100,60], cost = [20,8,0,0,0,0,0,0], 
                               conventional = [1,1,0,0,0,0,0,0], WIND = [0,0,1,1,1,0,0,0],
                                ROR = [0,0,0,0,0,1,1,1])

demand = DataFrame(load_z1 = [100,80,60], load_z2 = [300,250,330], load_z3 = [50,40,80])

variability = DataFrame(conventional_gas = [1,1,1], conventional_nuc = [1,1,1], West_A_Wind = [0.13,0.16,0.18], 
                        Central_C_Wind = [0.12,0.11,0.14], North_D_Wind = [0.22,0.19,0.43],
                        West_A_ROR = [0.57, 0.57, 0.57], Central_C_ROR = [0.60,0.60,0.60], North_D_ROR = [0.40,0.40,0.40])

# Sets
G = generators.R_ID #all generators
T = convert(Array{Int64}, 1:3)
Z = convert(Array{Int64}, 1:3) #zones

C = generators.R_ID[generators.conventional.==1] #conventional generators
WND = intersect(generators.R_ID[generators.WIND.==1], G) #wind resources
ROR = intersect(generators.R_ID[generators.ROR.==1], G) #Run-Of-River
#Define model
#Dispatch_Model =  Model(Clp.Optimizer)

#Decission variables

#@variable(Dispatch_Model, vGEN[c in C, T] >=0) #Conventional plant generation
#@variable(Dispatch_Model, vWIND[w in WND, T] >=0) #wind
#@variable(Dispatch_Model, vROR[r in ROR, T] >=0)

#@constraint(Dispatch_Model, cMaxPower[c in C, t in T], 
#        vGEN[c,t] <= generators[generators.R_ID .== c,:g_max][1])

@constraint(Dispatch_Model, cWindInjection[t in T, w in  WND], vWIND[t,w] <= generators[w,:g_max] * variability[t,w])
#Error message after running the WindInjection constraint

ERROR: KeyError: key 1 not found
  [1] getindex
    @ .\dict.jl:482 [inlined]
  [2] getindex
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\DenseAxisArray.jl:43 [inlined]
  [3] _getindex_recurse
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\DenseAxisArray.jl:250 [inlined]
  [4] to_index
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\DenseAxisArray.jl:259 [inlined]
  [5] getindex(::JuMP.Containers.DenseAxisArray{VariableRef, 2, Tuple{Vector{Int64}, Vector{Int64}}, Tuple{JuMP.Containers._AxisLookup{Dict{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{Int64, Int64}}}}, ::Int64, ::Int64)
    @ JuMP.Containers C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\DenseAxisArray.jl:266
  [6] macro expansion
    @ C:\Users\mbahe\.julia\packages\MutableArithmetics\0Y9ZS\src\rewrite.jl:279 [inlined]
  [7] macro expansion
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\macros.jl:676 [inlined]
  [8] (::var"#17#18")(t::Int64, w::Int64)
    @ Main C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\macro.jl:194
  [9] #38
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\container.jl:105 [inlined]
 [10] iterate
    @ .\generator.jl:47 [inlined]
 [11] collect(itr::Base.Generator{JuMP.Containers.VectorizedProductIterator{Tuple{Vector{Int64}, Vector{Int64}}}, JuMP.Containers.var"#38#39"{var"#17#18"}})
    @ Base .\array.jl:678
 [12] map(f::Function, A::JuMP.Containers.VectorizedProductIterator{Tuple{Vector{Int64}, Vector{Int64}}})
    @ Base .\abstractarray.jl:2323
 [13] container(f::Function, indices::JuMP.Containers.VectorizedProductIterator{Tuple{Vector{Int64}, Vector{Int64}}}, #unused#::Type{JuMP.Containers.DenseAxisArray})
    @ JuMP.Containers C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\container.jl:105
 [14] container(f::Function, indices::JuMP.Containers.VectorizedProductIterator{Tuple{Vector{Int64}, Vector{Int64}}})
    @ JuMP.Containers C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\Containers\container.jl:66
 [15] macro expansion
    @ C:\Users\mbahe\.julia\packages\JuMP\klrjG\src\macros.jl:142 [inlined]
 [16] top-level scope
    @ c:\Users\mbahe\Desktop\JuliaDiscourse\renewable_generation_constraint_question.jl:48

With the constraint, I am trying to limit renewable injection output by the availability factor over time and for each resource (in a particular zone)

1 Like

vWIND is defined as @variable(Dispatch_Model, vWIND[w in WND, T] >=0) but you indexed it as vWIND[t,w].

It should probably be vWIND[w, t]

1 Like

Thanks a lot Odow for your prompt response. Really appreciate it. It worked!

1 Like