Can be reproduced using the current HIFLD grid model for the Eastern interconnect, which has all zeros for Pd values for buses within the "Colorado Eastern" zone (zone_id = 6). To reproduce, you can call REISE.run_scenario_gurobi or REISE.run_scenario. Checking the data with python we see the root of the data problem.
The output produced by the above code, which may be a screenshot, console output, etc.
Expression contains an invalid NaN constant. This could be produced by `Inf - Inf`.
Stacktrace:
[1] error(::String) at .\error.jl:33
[2] _assert_isfinite(::JuMP.GenericAffExpr{Float64,JuMP.VariableRef}) at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\aff_expr.jl:476
[3] MathOptInterface.ScalarAffineFunction(::JuMP.GenericAffExpr{Float64,JuMP.VariableRef}) at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\aff_expr.jl:507
[4] moi_function at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\aff_expr.jl:550 [inlined]
[5] moi_function at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\constraints.jl:396 [inlined]
[6] add_constraint(::JuMP.Model, ::JuMP.ScalarConstraint{JuMP.GenericAffExpr{Float64,JuMP.VariableRef},MathOptInterface.EqualTo{Float64}}, ::String) at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\constraints.jl:547
[7] add_constraint at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\constraints.jl:546 [inlined]
[8] _broadcast_getindex_evalf at .\broadcast.jl:648 [inlined]
[9] _broadcast_getindex at .\broadcast.jl:621 [inlined]
[10] getindex at .\broadcast.jl:575 [inlined]
[11] copyto_nonleaf!(::Array{JuMP.ConstraintRef{JuMP.Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.EqualTo{Float64}},JuMP.ScalarShape},2}, ::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2},Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},typeof(JuMP.add_constraint),Tuple{Base.RefValue{JuMP.Model},Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2},Nothing,typeof(JuMP.build_constraint),Tuple{Base.RefValue{JuMP.var"#_error#92"{Tuple{Symbol,Symbol,Expr},Symbol,LineNumberNode}},Base.Broadcast.Extruded{Array{JuMP.GenericAffExpr{Float64,JuMP.VariableRef},2},Tuple{Bool,Bool},Tuple{Int64,Int64}},Base.RefValue{MathOptInterface.EqualTo{Float64}}}}}}, ::CartesianIndices{2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}, ::CartesianIndex{2}, ::Int64) at .\broadcast.jl:1026
[12] copy at .\broadcast.jl:880 [inlined]
[13] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2},Nothing,typeof(JuMP.add_constraint),Tuple{Base.RefValue{JuMP.Model},Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2},Nothing,typeof(JuMP.build_constraint),Tuple{Base.RefValue{JuMP.var"#_error#92"{Tuple{Symbol,Symbol,Expr},Symbol,LineNumberNode}},Array{JuMP.GenericAffExpr{Float64,JuMP.VariableRef},2},Base.RefValue{MathOptInterface.EqualTo{Float64}}}}}}) at .\broadcast.jl:837
[14] macro expansion at C:\Users\DanielOlsen\.julia\packages\JuMP\Xrr7O\src\macros.jl:677 [inlined]
[15] _add_constraint_power_balance!(::JuMP.Model, ::REISE.Case, ::REISE.Sets, ::REISE.Storage, ::REISE.DemandFlexibility, ::Array{Float64,2}, ::Bool) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\model.jl:278
[16] _build_model(::JuMP.Model; case::REISE.Case, storage::REISE.Storage, demand_flexibility::REISE.DemandFlexibility, start_index::Int64, interval_length::Int64, demand_scaling::Float64, load_shed_enabled::Bool, load_shed_penalty::Int64, trans_viol_enabled::Bool, trans_viol_penalty::Int64, initial_ramp_enabled::Bool, initial_ramp_g0::Array{Float64,1}, storage_e0::Array{Float64,1}, init_shifted_demand::Array{Float64,1}) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\model.jl:728
[17] interval_loop(::Gurobi.Env, ::Dict{String,Any}, ::Dict{String,Int64}, ::Int64, ::Int64, ::Int64, ::String, ::String) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\loop.jl:73
[18] (::REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env})() at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\REISE.jl:91
[19] #100 at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\save.jl:120 [inlined]
[20] redirect_stderr(::REISE.var"#100#104"{REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env}}, ::IOStream) at .\stream.jl:1150
[21] #99 at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\save.jl:119 [inlined]
[22] redirect_stdout(::REISE.var"#99#103"{IOStream,REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env}}, ::IOStream) at .\stream.jl:1150
[23] #98 at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\save.jl:118 [inlined]
[24] open(::REISE.var"#98#102"{IOStream,REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env}}, ::String, ::Vararg{String,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at .\io.jl:325
[25] open at .\io.jl:323 [inlined]
[26] #97 at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\save.jl:117 [inlined]
[27] open(::REISE.var"#97#101"{REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env},String}, ::String, ::Vararg{String,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at .\io.jl:325
[28] open at .\io.jl:323 [inlined]
[29] redirect_stdout_stderr(::REISE.var"#112#113"{Int64,Int64,Int64,String,Gurobi.Env}, ::String, ::String) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\save.jl:116
[30] run_scenario(; num_segments::Int64, interval::Int64, n_interval::Int64, start_index::Int64, inputfolder::String, outputfolder::String, threads::Nothing, optimizer_factory::Gurobi.Env, solver_kwargs::Dict{String,Int64}, model_kwargs::Dict{String,Integer}) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\REISE.jl:89
[31] run_scenario_gurobi(; solver_kwargs::Nothing, kwargs::Base.Iterators.Pairs{Symbol,Any,NTuple{6,Symbol},NamedTuple{(:interval, :n_interval, :start_index, :inputfolder, :outputfolder, :model_kwargs),Tuple{Int64,Int64,Int64,String,String,Dict{String,Integer}}}}) at C:\Users\DanielOlsen\repos\bes\REISE.jl\src\solver_specific\gurobi.jl:13
In the case I was running into, I had set the demand to zero for that zone anyway, so I would have hoped that bus_demand would be all zeros for that zone. In this situation, I think we can safely replace any NaN values with zeros, and potentially warn the user/log of what's going on. In a situation for which there is non-zero demand for a zone with all-zero Pd values, I think we should detect this when loading the input files and halt before trying to build the model.
This bug should be environment agnostic.
Please specify your platform and versions of the relevant libraries you are using:
🪲
Bug summary
If all buses within a zone have a
Pdof zero, model building will crash within the_add_constraint_power_balance!function, due to aNaNvalue withinbus_demand. The origin of this isNaNvalue is the following line:bus_share = bus_df[:, :load] ./ bus_df_with_zone_load[:, :load_sum]which divides by zero for at least one zone since the sum of all Pd values for the zone is zero.REISE.jl/src/model.jl
Line 55 in 420dc05
Code for reproduction
Can be reproduced using the current HIFLD grid model for the Eastern interconnect, which has all zeros for
Pdvalues for buses within the"Colorado Eastern"zone (zone_id = 6). To reproduce, you can callREISE.run_scenario_gurobiorREISE.run_scenario. Checking the data with python we see the root of the data problem.Actual outcome
The output produced by the above code, which may be a screenshot, console output, etc.
Expected outcome
In the case I was running into, I had set the demand to zero for that zone anyway, so I would have hoped that
bus_demandwould be all zeros for that zone. In this situation, I think we can safely replace any NaN values with zeros, and potentially warn the user/log of what's going on. In a situation for which there is non-zero demand for a zone with all-zero Pd values, I think we should detect this when loading the input files and halt before trying to build the model.Environment
This bug should be environment agnostic.
Please specify your platform and versions of the relevant libraries you are using:
git rev-parse origin/HEAD):e8639dd8a2fe42299e58e0c7ed49bc84527f5d07