diff --git a/docs/src/format.md b/docs/src/format.md index 6714862..354ff5d 100644 --- a/docs/src/format.md +++ b/docs/src/format.md @@ -12,6 +12,7 @@ An instance of the stochastic security-constrained unit commitment (SCUC) proble * [Storage units](#Storage-units) * [Price-sensitive loads](#Price-sensitive-loads) * [Transmission lines](#Transmission-lines) +* [Interfaces](#Interfaces) * [Reserves](#Reserves) * [Contingencies](#Contingencies) @@ -283,7 +284,7 @@ This section describes the characteristics of transmission system, such as its t | `Target bus` | Identifier of the bus where the transmission line reaches. | Required | No | Yes | `Susceptance (S)` | Susceptance of the transmission line (in siemens). | Required | No | Yes | `Normal flow limit (MW)` | Maximum amount of power (in MW) allowed to flow through the line when the system is in its regular, fully-operational state. | `+inf` | Yes | Yes -| `Emergency flow limit (MW)` | Maximum amount of power (in MW) allowed to flow through the line when the system is in degraded state (for example, after the failure of another transmission line). | `+inf` | Y | Yes +| `Emergency flow limit (MW)` | Maximum amount of power (in MW) allowed to flow through the line when the system is in degraded state (for example, after the failure of another transmission line). | `+inf` | Yes | Yes | `Flow limit penalty ($/MW)` | Penalty for violating the flow limits of the transmission line (in $/MW). This is charged per time step. For example, if there is a thermal violation of 1 MW for three time steps, then three times this amount will be charged. | `5000.0` | Yes | Yes #### Example @@ -303,6 +304,33 @@ This section describes the characteristics of transmission system, such as its t } ``` +### Interfaces + +This section describes the characteristics of interfaces, such as its topology and the flow limits of each interface. An interface is a set of transmission lines that, when opened, split the network into different islands. A postive direction is pre-defined by the user between every 2 interfaces. The net flow through an interface is the sum of the flows through the positive lines minus the sum of the flows through the negative lines. + +| Key | Description | Default | Time series? | Uncertain? +| :--------------------- | :----------------------------------------------- | ------- | :------------: | :---: +| `Outbound lines` | List of transmission lines flow out from a region, which is defined as the positve direction. May be omitted if no outbound lines available. | `[]` | No | Yes +| `Inbound lines` | List of transmission lines flow into a region, which is defined as the negative direction. May be omitted if no inbound lines available. | `[]` | No | Yes +| `Net flow upper limit (MW)` | Maximum net amount of power (in MW) allowed to flow through the interface. | `+inf` | Yes | Yes +| `Net flow lower limit (MW)` | Minimum net amount of power (in MW) allowed to flow through the interface. | `-inf` | Yes | Yes +| `Flow limit penalty ($/MW)` | Penalty for violating the flow limits of the interface (in $/MW). This is charged per time step. For example, if there is a thermal violation of 1 MW for three time steps, then three times this amount will be charged. | `5000.0` | Yes | Yes + +#### Example + +```json +{ + "Interfaces": { + "ifc1": { + "Outbound lines": ["l2", "l3", "l5", "l7", "l8", "l9"], + "Inbound lines": ["l6"], + "Net flow upper limit (MW)": 2000, + "Net flow lower limit (MW)": -1500, + "Flow limit penalty ($/MW)": 9999.0 + } + } +} +``` ### Reserves diff --git a/src/UnitCommitment.jl b/src/UnitCommitment.jl index d46d71e..2a85320 100644 --- a/src/UnitCommitment.jl +++ b/src/UnitCommitment.jl @@ -37,6 +37,7 @@ include("model/formulations/base/system.jl") include("model/formulations/base/unit.jl") include("model/formulations/base/punit.jl") include("model/formulations/base/storage.jl") +include("model/formulations/base/interface.jl") include("model/formulations/CarArr2006/pwlcosts.jl") include("model/formulations/DamKucRajAta2016/ramp.jl") include("model/formulations/Gar1962/pwlcosts.jl") diff --git a/src/instance/read.jl b/src/instance/read.jl index 62b0230..12c9733 100644 --- a/src/instance/read.jl +++ b/src/instance/read.jl @@ -137,6 +137,7 @@ function _from_json(json; repair = true)::UnitCommitmentScenario reserves = Reserve[] profiled_units = ProfiledUnit[] storage_units = StorageUnit[] + interfaces = Interface[] function scalar(x; default = nothing) x !== nothing || return default @@ -452,6 +453,45 @@ function _from_json(json; repair = true)::UnitCommitmentScenario end end + # Read interfaces + if "Interfaces" in keys(json) + for (int_name, dict) in json["Interfaces"] + outbound_lines = TransmissionLine[] + inbound_lines = TransmissionLine[] + if "Outbound lines" in keys(dict) + outbound_lines = [ + name_to_line[l] for + l in scalar(dict["Outbound lines"], default = []) + ] + end + if "Inbound lines" in keys(dict) + inbound_lines = [ + name_to_line[l] for + l in scalar(dict["Inbound lines"], default = []) + ] + end + interface = Interface( + int_name, + length(interfaces) + 1, + outbound_lines, + inbound_lines, + timeseries( + dict["Net flow upper limit (MW)"], + default = [1e8 for t in 1:T], + ), + timeseries( + dict["Net flow lower limit (MW)"], + default = [-1e8 for t in 1:T], + ), + timeseries( + dict["Flow limit penalty (\$/MW)"], + default = [5000.0 for t in 1:T], + ), + ) + push!(interfaces, interface) + end + end + scenario = UnitCommitmentScenario( name = scenario_name, probability = probability, @@ -474,8 +514,11 @@ function _from_json(json; repair = true)::UnitCommitmentScenario profiled_units = profiled_units, storage_units_by_name = Dict(su.name => su for su in storage_units), storage_units = storage_units, + interfaces_by_name = Dict(i.name => i for i in interfaces), + interfaces = interfaces, isf = spzeros(Float64, length(lines), length(buses) - 1), lodf = spzeros(Float64, length(lines), length(lines)), + interface_isf = spzeros(Float64, length(interfaces), length(buses) - 1), ) if repair UnitCommitment.repair!(scenario) diff --git a/src/instance/structs.jl b/src/instance/structs.jl index 4082fb0..bbb0bcd 100644 --- a/src/instance/structs.jl +++ b/src/instance/structs.jl @@ -103,6 +103,16 @@ mutable struct StorageUnit max_ending_level::Float64 end +mutable struct Interface + name::String + offset::Int + outbound_lines::Vector{TransmissionLine} + inbound_lines::Vector{TransmissionLine} + net_flow_upper_limit::Vector{Float64} + net_flow_lower_limit::Vector{Float64} + flow_limit_penalty::Vector{Float64} +end + Base.@kwdef mutable struct UnitCommitmentScenario buses_by_name::Dict{AbstractString,Bus} buses::Vector{Bus} @@ -125,6 +135,9 @@ Base.@kwdef mutable struct UnitCommitmentScenario thermal_units::Vector{ThermalUnit} storage_units_by_name::Dict{AbstractString,StorageUnit} storage_units::Vector{StorageUnit} + interfaces_by_name::Dict{AbstractString,Interface} + interfaces::Vector{Interface} + interface_isf::Array{Float64,2} time::Int time_step::Int end diff --git a/src/model/build.jl b/src/model/build.jl index 0e27d42..089db92 100644 --- a/src/model/build.jl +++ b/src/model/build.jl @@ -103,6 +103,9 @@ function build_model(; _add_storage_unit!(model, su, sc) end _add_system_wide_eqs!(model, sc) + for ifc in sc.interfaces + _add_interface!(model, ifc, formulation.transmission, sc) + end end @objective(model, Min, model[:obj]) end diff --git a/src/model/formulations/base/interface.jl b/src/model/formulations/base/interface.jl new file mode 100644 index 0000000..00c2b8e --- /dev/null +++ b/src/model/formulations/base/interface.jl @@ -0,0 +1,46 @@ +# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment +# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +function _add_interface!( + model::JuMP.Model, + ifc::Interface, + f::ShiftFactorsFormulation, + sc::UnitCommitmentScenario, +)::Nothing + overflow = _init(model, :interface_overflow) + net_injection = _init(model, :net_injection) + for t in 1:model[:instance].time + # define the net flow variable + flow = @variable(model, base_name = "interface_flow[$(ifc.name),$t]") + # define the overflow variable + overflow[sc.name, ifc.name, t] = @variable(model, lower_bound = 0) + # constraints: lb - v <= flow <= ub + v + @constraint( + model, + flow <= + ifc.net_flow_upper_limit[t] + overflow[sc.name, ifc.name, t] + ) + @constraint( + model, + -flow <= + -ifc.net_flow_lower_limit[t] + overflow[sc.name, ifc.name, t] + ) + # constraint: flow value is calculated from the interface ISF matrix + @constraint( + model, + flow == sum( + net_injection[sc.name, b.name, t] * + sc.interface_isf[ifc.offset, b.offset] for + b in sc.buses if b.offset > 0 + ) + ) + # make overflow part of the objective as a punishment term + add_to_expression!( + model[:obj], + overflow[sc.name, ifc.name, t], + ifc.flow_limit_penalty[t] * sc.probability, + ) + end + return +end diff --git a/src/model/formulations/base/line.jl b/src/model/formulations/base/line.jl index 98d5f2c..52eb199 100644 --- a/src/model/formulations/base/line.jl +++ b/src/model/formulations/base/line.jl @@ -26,9 +26,11 @@ function _setup_transmission( )::Nothing isf = formulation.precomputed_isf lodf = formulation.precomputed_lodf + interface_isf = nothing if length(sc.buses) == 1 isf = zeros(0, 0) lodf = zeros(0, 0) + interface_isf = zeros(0, 0) elseif isf === nothing @info "Computing injection shift factors..." time_isf = @elapsed begin @@ -36,6 +38,11 @@ function _setup_transmission( buses = sc.buses, lines = sc.lines, ) + interface_isf = + UnitCommitment._interface_injection_shift_factors( + interfaces = sc.interfaces, + isf = isf, + ) end @info @sprintf("Computed ISF in %.2f seconds", time_isf) @info "Computing line outage factors..." @@ -53,9 +60,13 @@ function _setup_transmission( formulation.lodf_cutoff ) isf[abs.(isf). line_flows[l.offset, :] for l in sc.lines) + end + if !isempty(sc.interfaces) + # get the matrix of interface flows (Ix(B-1))x((B-1)xT)=(IxT) + interface_flows = sc.interface_isf * bus_net_injection[2:end, :] + sol[sc.name]["Interface flow (MW)"] = OrderedDict( + ifc.name => interface_flows[ifc.offset, :] for + ifc in sc.interfaces + ) end if !isempty(sc.price_sensitive_loads) sol[sc.name]["Price-sensitive loads (MW)"] = diff --git a/src/transform/slice.jl b/src/transform/slice.jl index ef90082..e0f18d8 100644 --- a/src/transform/slice.jl +++ b/src/transform/slice.jl @@ -71,6 +71,11 @@ function slice( su.min_discharge_rate = su.min_discharge_rate[range] su.max_discharge_rate = su.max_discharge_rate[range] end + for ifc in sc.interfaces + ifc.net_flow_upper_limit = ifc.net_flow_upper_limit[range] + ifc.net_flow_lower_limit = ifc.net_flow_lower_limit[range] + ifc.flow_limit_penalty = ifc.flow_limit_penalty[range] + end end return modified end diff --git a/test/fixtures/case14-interface.json.gz b/test/fixtures/case14-interface.json.gz new file mode 100644 index 0000000..1bf4f05 Binary files /dev/null and b/test/fixtures/case14-interface.json.gz differ diff --git a/test/fixtures/case24-iberian-storage.json.gz b/test/fixtures/case24-iberian-storage.json.gz new file mode 100644 index 0000000..65a5528 Binary files /dev/null and b/test/fixtures/case24-iberian-storage.json.gz differ diff --git a/test/fixtures/case3-interface-2.json.gz b/test/fixtures/case3-interface-2.json.gz new file mode 100644 index 0000000..0bb7b65 Binary files /dev/null and b/test/fixtures/case3-interface-2.json.gz differ diff --git a/test/fixtures/case3-interface.json.gz b/test/fixtures/case3-interface.json.gz new file mode 100644 index 0000000..59d95f2 Binary files /dev/null and b/test/fixtures/case3-interface.json.gz differ diff --git a/test/src/UnitCommitmentT.jl b/test/src/UnitCommitmentT.jl index ae28329..5d92195 100644 --- a/test/src/UnitCommitmentT.jl +++ b/test/src/UnitCommitmentT.jl @@ -9,6 +9,8 @@ include("import/egret_test.jl") include("instance/read_test.jl") include("instance/migrate_test.jl") include("model/formulations_test.jl") +include("model/storage_optimization_test.jl") +include("model/interface_optimization_test.jl") include("solution/methods/XavQiuWanThi19/filter_test.jl") include("solution/methods/XavQiuWanThi19/find_test.jl") include("solution/methods/XavQiuWanThi19/sensitivity_test.jl") @@ -39,6 +41,8 @@ function runtests() instance_read_test() instance_migrate_test() model_formulations_test() + storage_optimization_test() + interface_optimization_test() solution_methods_XavQiuWanThi19_filter_test() solution_methods_XavQiuWanThi19_find_test() solution_methods_XavQiuWanThi19_sensitivity_test() diff --git a/test/src/instance/migrate_test.jl b/test/src/instance/migrate_test.jl index 8328e53..08b12e2 100644 --- a/test/src/instance/migrate_test.jl +++ b/test/src/instance/migrate_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip +using UnitCommitment, LinearAlgebra, JuMP, JSON, GZip function instance_migrate_test() @testset "read v0.2" begin diff --git a/test/src/instance/read_test.jl b/test/src/instance/read_test.jl index bcb3eb4..9ccbdc1 100644 --- a/test/src/instance/read_test.jl +++ b/test/src/instance/read_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip +using UnitCommitment, LinearAlgebra, JuMP, JSON, GZip function instance_read_test() @testset "read_benchmark" begin @@ -224,4 +224,20 @@ function instance_read_test() @test su4.simultaneous_charge_and_discharge == [false, false, true, true] end + + @testset "read_benchmark interface" begin + instance = UnitCommitment.read(fixture("case14-interface.json.gz")) + sc = instance.scenarios[1] + @test length(sc.interfaces) == 1 + @test sc.interfaces_by_name["ifc1"].name == "ifc1" + + ifc = sc.interfaces[1] + @test ifc.name == "ifc1" + @test ifc.offset == 1 + @test length(ifc.outbound_lines) == 6 + @test length(ifc.inbound_lines) == 1 + @test ifc.net_flow_upper_limit == [2000 for t in 1:4] + @test ifc.net_flow_lower_limit == [-1500 for t in 1:4] + @test ifc.flow_limit_penalty == [9999.0 for t in 1:4] + end end diff --git a/test/src/lmp/aelmp_test.jl b/test/src/lmp/aelmp_test.jl index d619207..31904bb 100644 --- a/test/src/lmp/aelmp_test.jl +++ b/test/src/lmp/aelmp_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, Cbc, HiGHS, JuMP +using UnitCommitment, HiGHS, JuMP import UnitCommitment: AELMP function lmp_aelmp_test() @@ -13,8 +13,8 @@ function lmp_aelmp_test() model = UnitCommitment.build_model( instance = instance, optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), variable_names = true, ) diff --git a/test/src/lmp/conventional_test.jl b/test/src/lmp/conventional_test.jl index bd2529e..ce893de 100644 --- a/test/src/lmp/conventional_test.jl +++ b/test/src/lmp/conventional_test.jl @@ -2,13 +2,16 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, Cbc, HiGHS, JuMP +using UnitCommitment, HiGHS, JuMP function solve_conventional_testcase(path::String) instance = UnitCommitment.read(path) model = UnitCommitment.build_model( instance = instance, - optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0), + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ), variable_names = true, ) JuMP.set_silent(model) diff --git a/test/src/market/market_test.jl b/test/src/market/market_test.jl index 40a8d56..384ade6 100644 --- a/test/src/market/market_test.jl +++ b/test/src/market/market_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, Cbc, HiGHS, JuMP +using UnitCommitment, HiGHS, JuMP import UnitCommitment: MarketSettings function simple_market_test() @@ -20,8 +20,8 @@ function simple_market_test() rt_paths, MarketSettings(), # keep everything default optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), lp_optimizer = optimizer_with_attributes( HiGHS.Optimizer, @@ -52,8 +52,8 @@ function simple_market_test() rt_paths, MarketSettings(lmp_method = nothing), # no lmp optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), ) @@ -115,8 +115,8 @@ function stochastic_market_test() rt_paths, MarketSettings(), # keep everything default optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), lp_optimizer = optimizer_with_attributes( HiGHS.Optimizer, diff --git a/test/src/model/formulations_test.jl b/test/src/model/formulations_test.jl index 2b9307d..3f7e35c 100644 --- a/test/src/model/formulations_test.jl +++ b/test/src/model/formulations_test.jl @@ -4,7 +4,7 @@ using UnitCommitment using JuMP -using Cbc +using HiGHS using JSON import UnitCommitment: ArrCon2000, @@ -28,7 +28,7 @@ function _test( model = UnitCommitment.build_model( instance = instance, formulation = formulation, - optimizer = Cbc.Optimizer, + optimizer = HiGHS.Optimizer, variable_names = true, ) set_silent(model) diff --git a/test/src/model/interface_optimization_test.jl b/test/src/model/interface_optimization_test.jl new file mode 100644 index 0000000..80ad5c8 --- /dev/null +++ b/test/src/model/interface_optimization_test.jl @@ -0,0 +1,40 @@ +# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment +# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using UnitCommitment +using JuMP +using HiGHS +using JSON + +function interface_optimization_test() + @testset "interface_optimization" begin + # case3-interface: only outbounds + instance = UnitCommitment.read(fixture("case3-interface.json.gz")) + model = UnitCommitment.build_model( + instance = instance, + optimizer = HiGHS.Optimizer, + variable_names = true, + ) + set_silent(model) + UnitCommitment.optimize!(model) + @test value(variable_by_name(model, "interface_flow[ifc1,3]")) ≈ 20.0 atol = + 0.1 + @test value(variable_by_name(model, "interface_flow[ifc1,4]")) ≈ 20.0 atol = + 0.1 + + # case3-interface-2: one outbound, one inbound + instance = UnitCommitment.read(fixture("case3-interface-2.json.gz")) + model = UnitCommitment.build_model( + instance = instance, + optimizer = HiGHS.Optimizer, + variable_names = true, + ) + set_silent(model) + UnitCommitment.optimize!(model) + @test value(variable_by_name(model, "interface_flow[ifc1,1]")) ≈ 95.0 atol = + 0.1 + @test value(variable_by_name(model, "interface_flow[ifc1,2]")) ≈ 95.0 atol = + 0.1 + end +end diff --git a/test/src/model/storage_optimization_test.jl b/test/src/model/storage_optimization_test.jl new file mode 100644 index 0000000..2950f61 --- /dev/null +++ b/test/src/model/storage_optimization_test.jl @@ -0,0 +1,32 @@ +# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment +# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using UnitCommitment +using JuMP +using HiGHS +using JSON + +function storage_optimization_test() + @testset "storage_optimization" begin + instance = + UnitCommitment.read(fixture("case24-iberian-storage.json.gz")) + model = UnitCommitment.build_model( + instance = instance, + optimizer = HiGHS.Optimizer, + variable_names = true, + ) + set_silent(model) + UnitCommitment.optimize!(model) + solution = UnitCommitment.solution(model) + # results must be valid + @test UnitCommitment.validate(instance, solution) + # storages are being used + charging_rates = solution["Storage charging rates (MW)"] + discharging_rates = solution["Storage discharging rates (MW)"] + @test sum(charging_rates["su1"]) > 0 + @test sum(charging_rates["su2"]) > 0 + @test sum(discharging_rates["su1"]) > 0 + @test sum(discharging_rates["su2"]) > 0 + end +end diff --git a/test/src/solution/methods/TimeDecomposition/optimize_test.jl b/test/src/solution/methods/TimeDecomposition/optimize_test.jl index b9076fd..3969ff9 100644 --- a/test/src/solution/methods/TimeDecomposition/optimize_test.jl +++ b/test/src/solution/methods/TimeDecomposition/optimize_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, DataStructures, Cbc, HiGHS +using UnitCommitment, DataStructures, HiGHS import UnitCommitment: TimeDecomposition, ConventionalLMP function solution_methods_TimeDecomposition_optimize_test() @@ -13,8 +13,8 @@ function solution_methods_TimeDecomposition_optimize_test() instance, TimeDecomposition(time_window = 3, time_increment = 2), optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), ) @test length(solution["Thermal production (MW)"]["g1"]) == 4 @@ -47,8 +47,8 @@ function solution_methods_TimeDecomposition_optimize_test() instance, TimeDecomposition(time_window = 3, time_increment = 2), optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), after_build = after_build, after_optimize = after_optimize, @@ -68,8 +68,8 @@ function solution_methods_TimeDecomposition_optimize_test() instance, TimeDecomposition(time_window = 3, time_increment = 2), optimizer = optimizer_with_attributes( - Cbc.Optimizer, - "logLevel" => 0, + HiGHS.Optimizer, + "log_to_console" => false, ), ) @test length(solution["case14"]["Thermal production (MW)"]["g3"]) == 4 diff --git a/test/src/solution/methods/XavQiuWanThi19/sensitivity_test.jl b/test/src/solution/methods/XavQiuWanThi19/sensitivity_test.jl index 0eef038..318b69d 100644 --- a/test/src/solution/methods/XavQiuWanThi19/sensitivity_test.jl +++ b/test/src/solution/methods/XavQiuWanThi19/sensitivity_test.jl @@ -146,4 +146,19 @@ function solution_methods_XavQiuWanThi19_sensitivity_test() end end end + + @testset "_interface_injection_shift_factors" begin + instance = UnitCommitment.read(fixture("/case14-interface.json.gz")) + sc = instance.scenarios[1] + actual = UnitCommitment._interface_injection_shift_factors( + interfaces = sc.interfaces, + isf = UnitCommitment._injection_shift_factors( + lines = sc.lines, + buses = sc.buses, + ), + ) + @test size(actual) == (1, 13) + @test round.(collect(actual), digits = 2) == + [0.0 -1.0 0.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0] + end end diff --git a/test/src/transform/randomize/XavQiuAhm2021_test.jl b/test/src/transform/randomize/XavQiuAhm2021_test.jl index dfe397f..19796dd 100644 --- a/test/src/transform/randomize/XavQiuAhm2021_test.jl +++ b/test/src/transform/randomize/XavQiuAhm2021_test.jl @@ -7,7 +7,7 @@ import UnitCommitment: XavQiuAhm2021 using Distributions using Random -using UnitCommitment, Cbc, JuMP +using UnitCommitment, JuMP function get_scenario() return UnitCommitment.read_benchmark( diff --git a/test/src/transform/slice_test.jl b/test/src/transform/slice_test.jl index fdd86b4..f0e6a6e 100644 --- a/test/src/transform/slice_test.jl +++ b/test/src/transform/slice_test.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip +using UnitCommitment, LinearAlgebra, HiGHS, JuMP, JSON, GZip function transform_slice_test() @testset "slice" begin @@ -38,7 +38,10 @@ function transform_slice_test() end # Should be able to build model without errors - optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0) + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) model = UnitCommitment.build_model( instance = modified, optimizer = optimizer, @@ -58,7 +61,10 @@ function transform_slice_test() end # Should be able to build model without errors - optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0) + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) model = UnitCommitment.build_model( instance = modified, optimizer = optimizer, @@ -88,7 +94,34 @@ function transform_slice_test() end # Should be able to build model without errors - optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0) + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) + model = UnitCommitment.build_model( + instance = modified, + optimizer = optimizer, + variable_names = true, + ) + end + + @testset "slice interfaces" begin + instance = UnitCommitment.read(fixture("case14-interface.json.gz")) + modified = UnitCommitment.slice(instance, 1:3) + sc = modified.scenarios[1] + + # Should update all time-dependent fields + for ifc in sc.interfaces + @test length(ifc.net_flow_upper_limit) == 3 + @test length(ifc.net_flow_lower_limit) == 3 + @test length(ifc.flow_limit_penalty) == 3 + end + + # Should be able to build model without errors + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) model = UnitCommitment.build_model( instance = modified, optimizer = optimizer, diff --git a/test/src/usage.jl b/test/src/usage.jl index ea4eb20..3e5cf5f 100644 --- a/test/src/usage.jl +++ b/test/src/usage.jl @@ -2,7 +2,7 @@ # Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. -using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON +using UnitCommitment, LinearAlgebra, HiGHS, JuMP, JSON function _set_flow_limits!(instance) for sc in instance.scenarios @@ -18,8 +18,10 @@ function usage_test() @testset "deterministic" begin instance = UnitCommitment.read(fixture("case14.json.gz")) _set_flow_limits!(instance) - optimizer = - optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0) + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) model = UnitCommitment.build_model( instance = instance, optimizer = optimizer, @@ -53,8 +55,10 @@ function usage_test() ]) _set_flow_limits!(instance) @test length(instance.scenarios) == 2 - optimizer = - optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0) + optimizer = optimizer_with_attributes( + HiGHS.Optimizer, + "log_to_console" => false, + ) model = UnitCommitment.build_model( instance = instance, optimizer = optimizer,