From cc627b1e74a8060e0be3921d83a3af207e8724b2 Mon Sep 17 00:00:00 2001 From: pghosh Date: Sun, 8 Dec 2024 00:38:33 -0800 Subject: [PATCH 01/14] added _add_vom_cost_to_objective! to market_bid.jl --- .../common/objective_function/market_bid.jl | 36 +++++- test/run_market_bid_cost.jl | 107 ++++++++++++++++++ 2 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 test/run_market_bid_cost.jl diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index 635f59e07..af64a8ba1 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -476,9 +476,9 @@ function _add_variable_cost_to_objective!( initial_time = get_initial_time(container) incremental_cost_curves = PSY.get_incremental_offer_curves(cost_function) decremental_cost_curves = PSY.get_decremental_offer_curves(cost_function) - if isnothing(decremental_cost_curves) - error("Component $(component_name) is not allowed to participate as a demand.") - end + # if isnothing(decremental_cost_curves) + # error("Component $(component_name) is not allowed to participate as a demand.") + # end #= variable_cost_forecast = PSY.get_variable_cost( component, @@ -583,3 +583,33 @@ function _add_service_bid_cost!( end function _add_service_bid_cost!(::OptimizationContainer, ::PSY.Component, ::PSY.Service) end + +function _add_vom_cost_to_objective!( + container::OptimizationContainer, + ::T, + component::PSY.Component, + op_cost::PSY.MarketBidCost, + ::U, +) where {T <: VariableType, U <: AbstractDeviceFormulation} + incremental_cost_curves = PSY.get_incremental_offer_curves(op_cost) + decremental_cost_curves = PSY.get_decremental_offer_curves(op_cost) + power_units = PSY.get_power_units(incremental_cost_curves) + vom_cost = PSY.get_vom_cost(incremental_cost_curves) + multiplier = 1.0 # VOM Cost is always positive + cost_term = PSY.get_proportional_term(vom_cost) + iszero(cost_term) && return + base_power = get_base_power(container) + device_base_power = PSY.get_base_power(component) + cost_term_normalized = get_proportional_cost_per_system_unit( + cost_term, + power_units, + base_power, + device_base_power, + ) + for t in get_time_steps(container) + exp = + _add_proportional_term!(container, T(), d, cost_term_normalized * multiplier, t) + add_to_expression!(container, ProductionCostExpression, exp, d, t) + end + return +end diff --git a/test/run_market_bid_cost.jl b/test/run_market_bid_cost.jl new file mode 100644 index 000000000..e166781d6 --- /dev/null +++ b/test/run_market_bid_cost.jl @@ -0,0 +1,107 @@ +using Pkg +Pkg.activate("test") +Pkg.instantiate() + +using Revise +using PowerSystems +using PowerSystemCaseBuilder +using PowerSimulations +using StorageSystemsSimulations +using HydroPowerSimulations +using Xpress +using Logging +# using PlotlyJS +using Dates +using JuMP +using InfrastructureSystems +using DataStructures +using TimeSeries +const PSY = PowerSystems +const PSI = PowerSimulations +const PSB = PowerSystemCaseBuilder +const PM = PSI.PowerModels + +################################## +### Load Test Function Helpers ### +################################## + +include("test_utils/solver_definitions.jl") +include("test_utils/operations_problem_templates.jl") + +sys = PSB.build_system(PSITestSystems, "c_sys5_re") + +show_components(sys, ThermalStandard, [:active_power]) +show_components(sys, RenewableDispatch, [:active_power]) + +th_solitude = get_component(ThermalStandard, sys, "Solitude") +th_brighton = get_component(ThermalStandard, sys, "Brighton") +re_A = get_component(RenewableDispatch, sys, "WindBusA") +get_bus(th_solitude) + +#### Add MarketBidCost + +proposed_offer_curve = make_market_bid_curve( + [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], + [25.0, 25.5, 26.0, 27.0, 28.0, 30.0], + 10.0 +) + +set_operation_cost!( + th_solitude, + MarketBidCost(; + no_load_cost=0.0, + start_up = (hot=3.0, warm=0.0, cold=0.0), + shut_down = 1.5, + incremental_offer_curves = proposed_offer_curve + ) +) + +#### PowerSimulations Stuff ### + +template = ProblemTemplate( + NetworkModel( + CopperPlatePowerModel; + duals = [CopperPlateBalanceConstraint], + ), +) +set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) +#set_device_model!(template, ThermalStandard, ThermalDispatchNoMin) +set_device_model!(template, PowerLoad, StaticPowerLoad) +set_device_model!(template, RenewableDispatch, RenewableFullDispatch) + +model = DecisionModel( + template, + sys; + name = "UC", + optimizer = optimizer_with_attributes(Xpress.Optimizer, "MIPRELSTOP" => 1e-3), + system_to_file = false, + store_variable_names = true, + calculate_conflict = true, + optimizer_solve_log_print = true, +) + +build!(model; output_dir = mktempdir(; cleanup = true)) + +vars = model.internal.container.variables +cons = model.internal.container.constraints + +power_balance = + cons[PowerSimulations.ConstraintKey{CopperPlateBalanceConstraint, System}("")] +lb_thermal = cons[PowerSimulations.ConstraintKey{ + ActivePowerVariableLimitsConstraint, + ThermalStandard, +}( + "lb", +)] + +solve!(model) + +res = OptimizationProblemResults(model) + +p_th = read_variable(res, "ActivePowerVariable__ThermalStandard") + +param_re = read_parameter(res, "ActivePowerTimeSeriesParameter__RenewableDispatch") +p_re = read_variable(res, "ActivePowerVariable__RenewableDispatch") + +# $/(per-unit MW) = $/(100 MW) = 0.01 $/MW +price = read_dual(res, "CopperPlateBalanceConstraint__System") \ No newline at end of file From a241db03052157ff619c5fb38df9af15c7161783 Mon Sep 17 00:00:00 2001 From: pghosh Date: Mon, 9 Dec 2024 11:21:19 -0800 Subject: [PATCH 02/14] fixed test --- .../common/objective_function/market_bid.jl | 335 ++++++------ ..._device_thermal_generation_constructors.jl | 481 +++++++----------- 2 files changed, 341 insertions(+), 475 deletions(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index af64a8ba1..c64472ad4 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -3,24 +3,19 @@ ################################################## # For Market Bid -function _add_pwl_variables!( - container::OptimizationContainer, - ::Type{T}, - component_name::String, - time_period::Int, - cost_data::PSY.PiecewiseStepData, -) where {T <: PSY.Component} +function _add_pwl_variables!(container::OptimizationContainer, + ::Type{T}, + component_name::String, + time_period::Int, + cost_data::PSY.PiecewiseStepData) where {T<:PSY.Component} var_container = lazy_container_addition!(container, PieceWiseLinearBlockOffer(), T) # length(PiecewiseStepData) gets number of segments, here we want number of points break_points = PSY.get_x_coords(cost_data) pwlvars = Array{JuMP.VariableRef}(undef, length(break_points)) for i in 1:(length(break_points) - 1) - pwlvars[i] = - var_container[(component_name, i, time_period)] = JuMP.@variable( - get_jump_model(container), - base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", - lower_bound = 0.0, - ) + pwlvars[i] = var_container[(component_name, i, time_period)] = JuMP.@variable(get_jump_model(container), + base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", + lower_bound = 0.0,) end return pwlvars end @@ -37,29 +32,24 @@ Implement the constraints for PWL Block Offer variables. That is: \\sum_{k\\in\\mathcal{K}} \\delta_{k,t} <= P_{k+1,t}^{max} - P_{k,t}^{max} ``` """ -function _add_pwl_constraint!( - container::OptimizationContainer, - component::T, - ::U, - break_points::Vector{Float64}, - period::Int, -) where {T <: PSY.Component, U <: VariableType} +function _add_pwl_constraint!(container::OptimizationContainer, + component::T, + ::U, + break_points::Vector{Float64}, + period::Int) where {T<:PSY.Component,U<:VariableType} variables = get_variable(container, U(), T) - const_container = lazy_container_addition!( - container, - PieceWiseLinearBlockOfferConstraint(), - T, - axes(variables)..., - ) + const_container = lazy_container_addition!(container, + PieceWiseLinearBlockOfferConstraint(), + T, + axes(variables)...) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) name = PSY.get_name(component) - const_container[name, period] = JuMP.@constraint( - jump_model, - variables[name, period] == - sum(pwl_vars[name, ix, period] for ix in 1:len_cost_data) - ) + const_container[name, period] = JuMP.@constraint(jump_model, + variables[name, period] == + sum(pwl_vars[name, ix, period] + for ix in 1:len_cost_data)) #= const_upperbound_container = lazy_container_addition!( @@ -72,10 +62,9 @@ function _add_pwl_constraint!( # TODO: Parameter for this for ix in 1:len_cost_data - JuMP.@constraint( - jump_model, - pwl_vars[name, ix, period] <= break_points[ix + 1] - break_points[ix] - ) + JuMP.@constraint(jump_model, + pwl_vars[name, ix, period] <= + break_points[ix + 1] - break_points[ix]) end return end @@ -88,37 +77,32 @@ Implement the constraints for PWL Block Offer variables for ORDC. That is: \\sum_{k\\in\\mathcal{K}} \\delta_{k,t} <= P_{k+1,t}^{max} - P_{k,t}^{max} ``` """ -function _add_pwl_constraint!( - container::OptimizationContainer, - component::T, - ::U, - break_points::Vector{Float64}, - sos_status::SOSStatusVariable, - period::Int, -) where {T <: PSY.ReserveDemandCurve, U <: ServiceRequirementVariable} +function _add_pwl_constraint!(container::OptimizationContainer, + component::T, + ::U, + break_points::Vector{Float64}, + sos_status::SOSStatusVariable, + period::Int) where {T<:PSY.ReserveDemandCurve, + U<:ServiceRequirementVariable} name = PSY.get_name(component) variables = get_variable(container, U(), T, name) - const_container = lazy_container_addition!( - container, - PieceWiseLinearBlockOfferConstraint(), - T, - axes(variables)...; - meta = name, - ) + const_container = lazy_container_addition!(container, + PieceWiseLinearBlockOfferConstraint(), + T, + axes(variables)...; + meta=name,) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) - const_container[name, period] = JuMP.@constraint( - jump_model, - variables[name, period] == - sum(pwl_vars[name, ix, period] for ix in 1:len_cost_data) - ) + const_container[name, period] = JuMP.@constraint(jump_model, + variables[name, period] == + sum(pwl_vars[name, ix, period] + for ix in 1:len_cost_data)) for ix in 1:len_cost_data - JuMP.@constraint( - jump_model, - pwl_vars[name, ix, period] <= break_points[ix + 1] - break_points[ix] - ) + JuMP.@constraint(jump_model, + pwl_vars[name, ix, period] <= + break_points[ix + 1] - break_points[ix]) end return end @@ -127,77 +111,66 @@ end ################ PWL Expressions ################# ################################################## -function _get_pwl_cost_expression( - container::OptimizationContainer, - component::T, - time_period::Int, - cost_data::PSY.PiecewiseStepData, - multiplier::Float64, -) where {T <: PSY.Component} +function _get_pwl_cost_expression(container::OptimizationContainer, + component::T, + time_period::Int, + cost_data::PSY.PiecewiseStepData, + multiplier::Float64) where {T<:PSY.Component} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) gen_cost = JuMP.AffExpr(0.0) cost_data = PSY.get_y_coords(cost_data) for (i, cost) in enumerate(cost_data) - JuMP.add_to_expression!( - gen_cost, - cost * multiplier * pwl_var_container[(name, i, time_period)], - ) + JuMP.add_to_expression!(gen_cost, + cost * multiplier * + pwl_var_container[(name, i, time_period)]) end return gen_cost end -function _get_pwl_cost_expression( - container::OptimizationContainer, - component::T, - time_period::Int, - cost_function::PSY.MarketBidCost, - ::PSY.PiecewiseStepData, - ::U, - ::V, -) where {T <: PSY.Component, U <: VariableType, V <: AbstractDeviceFormulation} +function _get_pwl_cost_expression(container::OptimizationContainer, + component::T, + time_period::Int, + cost_function::PSY.MarketBidCost, + ::PSY.PiecewiseStepData, + ::U, + ::V) where {T<:PSY.Component,U<:VariableType, + V<:AbstractDeviceFormulation} incremental_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_curve) power_units = PSY.get_power_units(incremental_curve) cost_component = PSY.get_function_data(value_curve) base_power = get_base_power(container) device_base_power = PSY.get_base_power(component) - cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit( - cost_component, - power_units, - base_power, - device_base_power, - ) + cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit(cost_component, + power_units, + base_power, + device_base_power) resolution = get_resolution(container) dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR - return _get_pwl_cost_expression( - container, - component, - time_period, - cost_data_normalized, - dt, - ) + return _get_pwl_cost_expression(container, + component, + time_period, + cost_data_normalized, + dt) end """ Get cost expression for StepwiseCostReserve """ -function _get_pwl_cost_expression( - container::OptimizationContainer, - component::T, - time_period::Int, - cost_data::PSY.PiecewiseStepData, - multiplier::Float64, -) where {T <: PSY.ReserveDemandCurve} +function _get_pwl_cost_expression(container::OptimizationContainer, + component::T, + time_period::Int, + cost_data::PSY.PiecewiseStepData, + multiplier::Float64) where {T<:PSY.ReserveDemandCurve} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) slopes = PSY.get_y_coords(cost_data) ordc_cost = JuMP.AffExpr(0.0) for i in 1:length(slopes) - JuMP.add_to_expression!( - ordc_cost, - slopes[i] * multiplier * pwl_var_container[(name, i, time_period)], - ) + JuMP.add_to_expression!(ordc_cost, + slopes[i] * multiplier * + pwl_var_container[(name, i, time_period)]) end return ordc_cost end @@ -279,14 +252,13 @@ end Add PWL cost terms for data coming from the MarketBidCost with a fixed incremental offer curve """ -function _add_pwl_term!( - container::OptimizationContainer, - component::T, - cost_function::PSY.MarketBidCost, - ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, - ::U, - ::V, -) where {T <: PSY.Component, U <: VariableType, V <: AbstractDeviceFormulation} +function _add_pwl_term!(container::OptimizationContainer, + component::T, + cost_function::PSY.MarketBidCost, + ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, + ::U, + ::V) where {T<:PSY.Component,U<:VariableType, + V<:AbstractDeviceFormulation} name = PSY.get_name(component) incremental_offer_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_offer_curve) @@ -295,12 +267,10 @@ function _add_pwl_term!( device_base_power = PSY.get_base_power(component) power_units = PSY.get_power_units(incremental_offer_curve) - data = get_piecewise_incrementalcurve_per_system_unit( - cost_component, - power_units, - base_power, - device_base_power, - ) + data = get_piecewise_incrementalcurve_per_system_unit(cost_component, + power_units, + base_power, + device_base_power) cost_is_convex = PSY.is_convex(data) if !cost_is_convex @@ -313,8 +283,8 @@ function _add_pwl_term!( for t in time_steps _add_pwl_variables!(container, T, name, t, data) _add_pwl_constraint!(container, component, U(), break_points, t) - pwl_cost = - _get_pwl_cost_expression(container, component, t, cost_function, data, U(), V()) + pwl_cost = _get_pwl_cost_expression(container, component, t, cost_function, data, + U(), V()) pwl_cost_expressions[t] = pwl_cost end return pwl_cost_expressions @@ -324,13 +294,12 @@ end ########## PWL for StepwiseCostReserve ########## ################################################## -function _add_pwl_term!( - container::OptimizationContainer, - component::T, - cost_data::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, - ::U, - ::V, -) where {T <: PSY.Component, U <: VariableType, V <: AbstractServiceFormulation} +function _add_pwl_term!(container::OptimizationContainer, + component::T, + cost_data::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, + ::U, + ::V) where {T<:PSY.Component,U<:VariableType, + V<:AbstractServiceFormulation} multiplier = objective_function_multiplier(U(), V()) resolution = get_resolution(container) dt = Dates.value(Dates.Second(resolution)) / SECONDS_IN_HOUR @@ -339,12 +308,10 @@ function _add_pwl_term!( power_units = PSY.get_power_units(cost_data) cost_component = PSY.get_function_data(value_curve) device_base_power = PSY.get_base_power(component) - data = get_piecewise_incrementalcurve_per_system_unit( - cost_component, - power_units, - base_power, - device_base_power, - ) + data = get_piecewise_incrementalcurve_per_system_unit(cost_component, + power_units, + base_power, + device_base_power) name = PSY.get_name(component) time_steps = get_time_steps(container) pwl_cost_expressions = Vector{JuMP.AffExpr}(undef, time_steps[end]) @@ -463,22 +430,21 @@ Decremental offers are not accepted for most components, except Storage systems - component_name::String: The component_name of the variable container - cost_function::MarketBidCost : container for market bid cost """ -function _add_variable_cost_to_objective!( - container::OptimizationContainer, - ::T, - component::PSY.Component, - cost_function::PSY.MarketBidCost, - ::U, -) where {T <: VariableType, U <: AbstractDeviceFormulation} +function _add_variable_cost_to_objective!(container::OptimizationContainer, + ::T, + component::PSY.Component, + cost_function::PSY.MarketBidCost, + ::U) where {T<:VariableType, + U<:AbstractDeviceFormulation} component_name = PSY.get_name(component) @debug "Market Bid" _group = LOG_GROUP_COST_FUNCTIONS component_name time_steps = get_time_steps(container) initial_time = get_initial_time(container) incremental_cost_curves = PSY.get_incremental_offer_curves(cost_function) decremental_cost_curves = PSY.get_decremental_offer_curves(cost_function) - # if isnothing(decremental_cost_curves) - # error("Component $(component_name) is not allowed to participate as a demand.") - # end + if !(isnothing(decremental_cost_curves)) + error("Component $(component_name) is not allowed to participate as a demand.") + end #= variable_cost_forecast = PSY.get_variable_cost( component, @@ -496,15 +462,12 @@ function _add_variable_cost_to_objective!( eltype(variable_cost_forecast_values), ) =# - pwl_cost_expressions = - _add_pwl_term!( - container, - component, - cost_function, - incremental_cost_curves, - T(), - U(), - ) + pwl_cost_expressions = _add_pwl_term!(container, + component, + cost_function, + incremental_cost_curves, + T(), + U()) jump_model = get_jump_model(container) for t in time_steps #= @@ -524,13 +487,11 @@ function _add_variable_cost_to_objective!( t, ) =# - add_to_expression!( - container, - ProductionCostExpression, - pwl_cost_expressions[t], - component, - t, - ) + add_to_expression!(container, + ProductionCostExpression, + pwl_cost_expressions[t], + component, + t) add_to_objective_variant_expression!(container, pwl_cost_expressions[t]) end @@ -544,21 +505,17 @@ function _add_variable_cost_to_objective!( return end -function _add_service_bid_cost!( - container::OptimizationContainer, - component::PSY.Component, - service::T, -) where {T <: PSY.Reserve{<:PSY.ReserveDirection}} +function _add_service_bid_cost!(container::OptimizationContainer, + component::PSY.Component, + service::T) where {T<:PSY.Reserve{<:PSY.ReserveDirection}} time_steps = get_time_steps(container) initial_time = get_initial_time(container) base_power = get_base_power(container) - forecast_data = PSY.get_services_bid( - component, - PSY.get_operation_cost(component), - service; - start_time = initial_time, - len = length(time_steps), - ) + forecast_data = PSY.get_services_bid(component, + PSY.get_operation_cost(component), + service; + start_time=initial_time, + len=length(time_steps),) forecast_data_values = PSY.get_cost.(TimeSeries.values(forecast_data)) # Single Price Bid if eltype(forecast_data_values) == Float64 @@ -570,27 +527,25 @@ function _add_service_bid_cost!( error("$(eltype(forecast_data_values)) not supported for MarketBidCost") end - reserve_variable = - get_variable(container, ActivePowerReserveVariable(), T, PSY.get_name(service)) + reserve_variable = get_variable(container, ActivePowerReserveVariable(), T, + PSY.get_name(service)) component_name = PSY.get_name(component) for t in time_steps - add_to_objective_invariant_expression!( - container, - data_values[t] * base_power * reserve_variable[component_name, t], - ) + add_to_objective_invariant_expression!(container, + data_values[t] * base_power * + reserve_variable[component_name, t]) end return end function _add_service_bid_cost!(::OptimizationContainer, ::PSY.Component, ::PSY.Service) end -function _add_vom_cost_to_objective!( - container::OptimizationContainer, - ::T, - component::PSY.Component, - op_cost::PSY.MarketBidCost, - ::U, -) where {T <: VariableType, U <: AbstractDeviceFormulation} +function _add_vom_cost_to_objective!(container::OptimizationContainer, + ::T, + component::PSY.Component, + op_cost::PSY.MarketBidCost, + ::U) where {T<:VariableType, + U<:AbstractDeviceFormulation} incremental_cost_curves = PSY.get_incremental_offer_curves(op_cost) decremental_cost_curves = PSY.get_decremental_offer_curves(op_cost) power_units = PSY.get_power_units(incremental_cost_curves) @@ -600,15 +555,13 @@ function _add_vom_cost_to_objective!( iszero(cost_term) && return base_power = get_base_power(container) device_base_power = PSY.get_base_power(component) - cost_term_normalized = get_proportional_cost_per_system_unit( - cost_term, - power_units, - base_power, - device_base_power, - ) + cost_term_normalized = get_proportional_cost_per_system_unit(cost_term, + power_units, + base_power, + device_base_power) for t in get_time_steps(container) - exp = - _add_proportional_term!(container, T(), d, cost_term_normalized * multiplier, t) + exp = _add_proportional_term!(container, T(), d, cost_term_normalized * multiplier, + t) add_to_expression!(container, ProductionCostExpression, exp, d, t) end return diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index cdb3a3881..785e75d93 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -1,37 +1,33 @@ test_path = mktempdir() @testset "Test Thermal Generation Cost Functions " begin - test_cases = [ - ("linear_cost_test", 4664.88, ThermalBasicUnitCommitment), - ("linear_fuel_test", 4664.88, ThermalBasicUnitCommitment), - ("quadratic_cost_test", 3301.81, ThermalDispatchNoMin), - ("quadratic_fuel_test", 3331.12, ThermalDispatchNoMin), - ("pwl_io_cost_test", 3421.64, ThermalBasicUnitCommitment), - ("pwl_io_fuel_test", 3421.64, ThermalBasicUnitCommitment), - ("pwl_incremental_cost_test", 3424.43, ThermalBasicUnitCommitment), - ("pwl_incremental_fuel_test", 3424.43, ThermalBasicUnitCommitment), - ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment), - ] + test_cases = [("linear_cost_test", 4664.88, ThermalBasicUnitCommitment), + ("linear_fuel_test", 4664.88, ThermalBasicUnitCommitment), + ("quadratic_cost_test", 3301.81, ThermalDispatchNoMin), + ("quadratic_fuel_test", 3331.12, ThermalDispatchNoMin), + ("pwl_io_cost_test", 3421.64, ThermalBasicUnitCommitment), + ("pwl_io_fuel_test", 3421.64, ThermalBasicUnitCommitment), + ("pwl_incremental_cost_test", 3424.43, ThermalBasicUnitCommitment), + ("pwl_incremental_fuel_test", 3424.43, ThermalBasicUnitCommitment), + ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment)] for (i, cost_reference, thermal_formulation) in test_cases @testset "$i" begin sys = build_system(PSITestSystems, "c_$(i)") template = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template, ThermalStandard, thermal_formulation) set_device_model!(template, PowerLoad, StaticPowerLoad) - model = DecisionModel( - template, - sys; - name = "UC_$(i)", - optimizer = HiGHS_optimizer, - system_to_file = false, - optimizer_solve_log_print = true, - ) - @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT + model = DecisionModel(template, + sys; + name="UC_$(i)", + optimizer=HiGHS_optimizer, + system_to_file=false, + optimizer_solve_log_print=true,) + @test build!(model; output_dir=test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) expr = read_expression(results, "ProductionCostExpression__ThermalStandard") var_unit_cost = sum(expr[!, "Test Unit"]) - @test isapprox(var_unit_cost, cost_reference; atol = 1) + @test isapprox(var_unit_cost, cost_reference; atol=1) @test expr[!, "Test Unit"][end] == 0.0 end end @@ -68,58 +64,47 @@ end end =# -#= -#TODO: This test +#TODO: timeseries market_bid_cost @testset "Test Thermal Generation MarketBidCost models" begin - test_cases = [ - ("fixed_market_bid_cost", 20532.76), - #"market_bid_cost", - ] + test_cases = [("fixed_market_bid_cost", 20772.76) + #"market_bid_cost", + ] for (i, cost_reference) in test_cases @testset "$i" begin sys = build_system(PSITestSystems, "c_$(i)") template = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) set_device_model!(template, PowerLoad, StaticPowerLoad) - model = DecisionModel( - template, - sys; - name = "UC_$(i)", - optimizer = HiGHS_optimizer, - system_to_file = false, - optimizer_solve_log_print = true, - ) - @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT + model = DecisionModel(template, + sys; + name="UC_$(i)", + optimizer=HiGHS_optimizer, + system_to_file=false, + optimizer_solve_log_print=true,) + @test build!(model; output_dir=test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) expr = read_expression(results, "ProductionCostExpression__ThermalStandard") var_unit_cost = sum(expr[!, "Test Unit1"]) - @test isapprox(var_unit_cost, cost_reference; atol = 1) - @test expr[!, "Test Unit1"][end] == 0.0 + @test isapprox(var_unit_cost, cost_reference; atol=1) + @test expr[!, "Test Unit2"][end] == 50.0 end end end -=# ################################### Unit Commitment tests ################################## @testset "Thermal UC With DC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] - uc_constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn"), - ] + uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] - aux_variables_keys = [ - PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard), - ] + aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -140,22 +125,16 @@ end end @testset "Thermal UC With AC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard), - ] - uc_constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn"), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] - aux_variables_keys = [ - PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard), - ] + aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) @@ -177,17 +156,15 @@ end end @testset "Thermal MultiStart UC With DC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), - ] - uc_constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "dn"), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -200,17 +177,15 @@ end end @testset "Thermal MultiStart UC With AC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), - ] - uc_constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "dn"), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -224,11 +199,9 @@ end ################################### Basic Unit Commitment tests ############################ @testset "Thermal Basic UC With DC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -247,11 +220,9 @@ end end @testset "Thermal Basic UC With AC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -270,11 +241,9 @@ end end @testset "Thermal MultiStart Basic UC With DC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -286,11 +255,9 @@ end end @testset "Thermal MultiStart Basic UC With AC - PF" begin - bin_variable_keys = [ - PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), - ] + bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -411,25 +378,20 @@ end c_sys5_pwl_ed_nonconvex = PSB.build_system(PSITestSystems, "c_sys5_pwl_ed_nonconvex") template = get_thermal_dispatch_template_network() set_device_model!(template, DeviceModel(ThermalStandard, ThermalDispatchNoMin)) - model = DecisionModel( - MockOperationProblem, - CopperPlatePowerModel, - c_sys5_pwl_ed_nonconvex; - export_pwl_vars = true, - initialize_model = false, - ) - @test_throws IS.InvalidValue mock_construct_device!( - model, - DeviceModel(ThermalStandard, ThermalDispatchNoMin), - ) + model = DecisionModel(MockOperationProblem, + CopperPlatePowerModel, + c_sys5_pwl_ed_nonconvex; + export_pwl_vars=true, + initialize_model=false,) + @test_throws IS.InvalidValue mock_construct_device!(model, + DeviceModel(ThermalStandard, + ThermalDispatchNoMin)) end ################################## Ramp Limited Testing ################################## @testset "ThermalStandard with ThermalStandardDispatch With DC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - ] + constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -446,10 +408,8 @@ end end @testset "ThermalStandard with ThermalStandardDispatch With AC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - ] + constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -466,10 +426,8 @@ end end @testset "ThermalMultiStart with ThermalStandardDispatch With DC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - ] + constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -480,10 +438,8 @@ end end @testset "ThermalMultiStart with ThermalStandardDispatch With AC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - ] + constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -496,30 +452,20 @@ end ################################### ThermalMultiStart Testing ############################## @testset "Thermal MultiStart with MultiStart UC and DC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey( - StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "warm", - ), - PSI.ConstraintKey( - StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "hot", - ), - PSI.ConstraintKey( - StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "lb", - ), - PSI.ConstraintKey( - StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "ub", - ), - ] + constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "warm"), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "hot"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "lb"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "ub")] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 334, false => 282) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -531,30 +477,20 @@ end end @testset "Thermal MultiStart with MultiStart UC and AC - PF" begin - constraint_keys = [ - PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey( - StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "warm", - ), - PSI.ConstraintKey( - StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "hot", - ), - PSI.ConstraintKey( - StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "lb", - ), - PSI.ConstraintKey( - StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "ub", - ), - ] + constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "warm"), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "hot"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "lb"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "ub")] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 382, false => 330) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -644,7 +580,7 @@ end device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 245, 0, 144, 144, 0, false) psi_checkobjfun_test(model, GAEVF) end @@ -653,7 +589,7 @@ end device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_pglib) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 290, 0, 96, 96, 96, false) psi_checkobjfun_test(model, GAEVF) end @@ -662,7 +598,7 @@ end device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 365, 0, 264, 264, 0, false) psi_checkobjfun_test(model, GAEVF) end @@ -671,7 +607,7 @@ end device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_pglib) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 338, 0, 144, 144, 96, false) psi_checkobjfun_test(model, GAEVF) end @@ -682,14 +618,12 @@ end template = ProblemTemplate(CopperPlatePowerModel) set_device_model!(template, ThermalStandard, ThermalStandardDispatch) set_device_model!(template, PowerLoad, StaticPowerLoad) - ED = DecisionModel( - EconomicDispatchProblem, - template, - ramp_test_sys; - optimizer = HiGHS_optimizer, - initialize_model = false, - ) - @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT + ED = DecisionModel(EconomicDispatchProblem, + template, + ramp_test_sys; + optimizer=HiGHS_optimizer, + initialize_model=false,) + @test build!(ED; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT moi_tests(ED, 10, 0, 15, 15, 5, false) psi_checksolve_test(ED, [MOI.OPTIMAL], 11191.00) end @@ -697,16 +631,14 @@ end # Testing Duration Constraints @testset "Solving UC with CopperPlate for testing Duration Constraints" begin template = get_thermal_standard_uc_template() - UC = DecisionModel( - UnitCommitmentProblem, - template, - PSB.build_system(PSITestSystems, "c_duration_test"); - optimizer = HiGHS_optimizer, - initialize_model = false, - store_variable_names = true, - ) - build!(UC; output_dir = mktempdir(; cleanup = true)) - @test build!(UC; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT + UC = DecisionModel(UnitCommitmentProblem, + template, + PSB.build_system(PSITestSystems, "c_duration_test"); + optimizer=HiGHS_optimizer, + initialize_model=false, + store_variable_names=true,) + build!(UC; output_dir=mktempdir(; cleanup=true)) + @test build!(UC; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT moi_tests(UC, 56, 0, 56, 14, 21, true) psi_checksolve_test(UC, [MOI.OPTIMAL], 8223.50) end @@ -739,12 +671,10 @@ end commitment_models = [ThermalStandardUnitCommitment, ThermalCompactUnitCommitment] for net in networks, sys in systems, model in commitment_models - template = get_thermal_dispatch_template_network( - NetworkModel(net), - ) + template = get_thermal_dispatch_template_network(NetworkModel(net)) set_device_model!(template, ThermalStandard, model) - UC = DecisionModel(template, sys; optimizer = HiGHS_optimizer) - @test build!(UC; output_dir = mktempdir(; cleanup = true)) == + UC = DecisionModel(template, sys; optimizer=HiGHS_optimizer) + @test build!(UC; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT psi_checksolve_test(UC, [MOI.OPTIMAL, MOI.LOCALLY_SOLVED], 340000, 100000) end @@ -753,139 +683,126 @@ end @testset "Test Feedforwards to ThermalStandard with ThermalStandardDispatch" begin device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalStandard, - source = OnVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalStandard, + source=OnVariable, + affected_values=[ActivePowerVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalStandard, - source = ActivePowerVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalStandard, + source=ActivePowerVariable, + affected_values=[ActivePowerVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 365, 0, 264, 144, 0, false) end @testset "Test Feedforwards to ThermalStandard with ThermalBasicDispatch" begin device_model = DeviceModel(ThermalStandard, ThermalBasicDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalStandard, - source = OnVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalStandard, + source=OnVariable, + affected_values=[ActivePowerVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalStandard, - source = ActivePowerVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalStandard, + source=ActivePowerVariable, + affected_values=[ActivePowerVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 360, 0, 240, 120, 0, false) end @testset "Test Feedforwards to ThermalStandard with ThermalCompactDispatch" begin device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalStandard, - source = OnVariable, - affected_values = [PowerAboveMinimumVariable], - ) + component_type=ThermalStandard, + source=OnVariable, + affected_values=[PowerAboveMinimumVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalStandard, - source = PSI.PowerAboveMinimumVariable, - affected_values = [PSI.PowerAboveMinimumVariable], - ) + component_type=ThermalStandard, + source=PSI.PowerAboveMinimumVariable, + affected_values=[PSI.PowerAboveMinimumVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 365, 0, 264, 144, 0, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalStandardDispatch" begin device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalMultiStart, - source = OnVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalMultiStart, + source=OnVariable, + affected_values=[ActivePowerVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalMultiStart, - source = ActivePowerVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalMultiStart, + source=ActivePowerVariable, + affected_values=[ActivePowerVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 338, 0, 144, 96, 96, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalBasicDispatch" begin device_model = DeviceModel(ThermalMultiStart, ThermalBasicDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalMultiStart, - source = OnVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalMultiStart, + source=OnVariable, + affected_values=[ActivePowerVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalMultiStart, - source = ActivePowerVariable, - affected_values = [ActivePowerVariable], - ) + component_type=ThermalMultiStart, + source=ActivePowerVariable, + affected_values=[ActivePowerVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 336, 0, 96, 48, 96, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalCompactDispatch" begin device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) ff_sc = SemiContinuousFeedforward(; - component_type = ThermalMultiStart, - source = OnVariable, - affected_values = [PSI.PowerAboveMinimumVariable], - ) + component_type=ThermalMultiStart, + source=OnVariable, + affected_values=[PSI.PowerAboveMinimumVariable],) ff_ub = UpperBoundFeedforward(; - component_type = ThermalMultiStart, - source = PSI.PowerAboveMinimumVariable, - affected_values = [PSI.PowerAboveMinimumVariable], - ) + component_type=ThermalMultiStart, + source=PSI.PowerAboveMinimumVariable, + affected_values=[PSI.PowerAboveMinimumVariable],) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves = true) + mock_construct_device!(model, device_model; built_for_recurrent_solves=true) moi_tests(model, 338, 0, 144, 96, 96, false) end @testset "Test Must Run ThermalGen" begin sys_5 = build_system(PSITestSystems, "c_sys5_uc") - template_uc = - ProblemTemplate(NetworkModel(CopperPlatePowerModel)) + template_uc = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template_uc, ThermalStandard, ThermalStandardUnitCommitment) #set_device_model!(template_uc, RenewableDispatch, FixedOutput) set_device_model!(template_uc, PowerLoad, StaticPowerLoad) @@ -895,22 +812,18 @@ end sundance = get_component(ThermalStandard, sys_5, "Sundance") set_must_run!(sundance, true) for rebuild in [true, false] - model = DecisionModel( - template_uc, - sys_5; - name = "UC", - optimizer = HiGHS_optimizer, - system_to_file = false, - store_variable_names = true, - rebuild_model = rebuild, - ) - - solve!(model; output_dir = mktempdir()) + model = DecisionModel(template_uc, + sys_5; + name="UC", + optimizer=HiGHS_optimizer, + system_to_file=false, + store_variable_names=true, + rebuild_model=rebuild,) + + solve!(model; output_dir=mktempdir()) ptdf_vars = get_variable_values(OptimizationProblemResults(model)) - power = - ptdf_vars[PowerSimulations.VariableKey{ActivePowerVariable, ThermalStandard}( - "", - )] + power = ptdf_vars[PowerSimulations.VariableKey{ActivePowerVariable, + ThermalStandard}("")] on = ptdf_vars[PowerSimulations.VariableKey{OnVariable, ThermalStandard}("")] start = ptdf_vars[PowerSimulations.VariableKey{StartVariable, ThermalStandard}("")] stop = ptdf_vars[PowerSimulations.VariableKey{StopVariable, ThermalStandard}("")] From 8dd0f795060b2c3ab8c381719727fbfce2b1a69b Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Mon, 9 Dec 2024 11:26:15 -0800 Subject: [PATCH 03/14] formatter --- .../common/objective_function/market_bid.jl | 222 ++++++------ test/run_market_bid_cost.jl | 20 +- ..._device_thermal_generation_constructors.jl | 328 +++++++++--------- 3 files changed, 287 insertions(+), 283 deletions(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index c64472ad4..d20d16528 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -4,18 +4,20 @@ # For Market Bid function _add_pwl_variables!(container::OptimizationContainer, - ::Type{T}, - component_name::String, - time_period::Int, - cost_data::PSY.PiecewiseStepData) where {T<:PSY.Component} + ::Type{T}, + component_name::String, + time_period::Int, + cost_data::PSY.PiecewiseStepData) where {T <: PSY.Component} var_container = lazy_container_addition!(container, PieceWiseLinearBlockOffer(), T) # length(PiecewiseStepData) gets number of segments, here we want number of points break_points = PSY.get_x_coords(cost_data) pwlvars = Array{JuMP.VariableRef}(undef, length(break_points)) for i in 1:(length(break_points) - 1) - pwlvars[i] = var_container[(component_name, i, time_period)] = JuMP.@variable(get_jump_model(container), - base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", - lower_bound = 0.0,) + pwlvars[i] = + var_container[(component_name, i, time_period)] = + JuMP.@variable(get_jump_model(container), + base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", + lower_bound = 0.0,) end return pwlvars end @@ -33,23 +35,23 @@ Implement the constraints for PWL Block Offer variables. That is: ``` """ function _add_pwl_constraint!(container::OptimizationContainer, - component::T, - ::U, - break_points::Vector{Float64}, - period::Int) where {T<:PSY.Component,U<:VariableType} + component::T, + ::U, + break_points::Vector{Float64}, + period::Int) where {T <: PSY.Component, U <: VariableType} variables = get_variable(container, U(), T) const_container = lazy_container_addition!(container, - PieceWiseLinearBlockOfferConstraint(), - T, - axes(variables)...) + PieceWiseLinearBlockOfferConstraint(), + T, + axes(variables)...) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) name = PSY.get_name(component) const_container[name, period] = JuMP.@constraint(jump_model, - variables[name, period] == - sum(pwl_vars[name, ix, period] - for ix in 1:len_cost_data)) + variables[name, period] == + sum(pwl_vars[name, ix, period] + for ix in 1:len_cost_data)) #= const_upperbound_container = lazy_container_addition!( @@ -63,8 +65,8 @@ function _add_pwl_constraint!(container::OptimizationContainer, # TODO: Parameter for this for ix in 1:len_cost_data JuMP.@constraint(jump_model, - pwl_vars[name, ix, period] <= - break_points[ix + 1] - break_points[ix]) + pwl_vars[name, ix, period] <= + break_points[ix + 1] - break_points[ix]) end return end @@ -78,31 +80,31 @@ Implement the constraints for PWL Block Offer variables for ORDC. That is: ``` """ function _add_pwl_constraint!(container::OptimizationContainer, - component::T, - ::U, - break_points::Vector{Float64}, - sos_status::SOSStatusVariable, - period::Int) where {T<:PSY.ReserveDemandCurve, - U<:ServiceRequirementVariable} + component::T, + ::U, + break_points::Vector{Float64}, + sos_status::SOSStatusVariable, + period::Int) where {T <: PSY.ReserveDemandCurve, + U <: ServiceRequirementVariable} name = PSY.get_name(component) variables = get_variable(container, U(), T, name) const_container = lazy_container_addition!(container, - PieceWiseLinearBlockOfferConstraint(), - T, - axes(variables)...; - meta=name,) + PieceWiseLinearBlockOfferConstraint(), + T, + axes(variables)...; + meta = name) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) const_container[name, period] = JuMP.@constraint(jump_model, - variables[name, period] == - sum(pwl_vars[name, ix, period] - for ix in 1:len_cost_data)) + variables[name, period] == + sum(pwl_vars[name, ix, period] + for ix in 1:len_cost_data)) for ix in 1:len_cost_data JuMP.@constraint(jump_model, - pwl_vars[name, ix, period] <= - break_points[ix + 1] - break_points[ix]) + pwl_vars[name, ix, period] <= + break_points[ix + 1] - break_points[ix]) end return end @@ -112,30 +114,30 @@ end ################################################## function _get_pwl_cost_expression(container::OptimizationContainer, - component::T, - time_period::Int, - cost_data::PSY.PiecewiseStepData, - multiplier::Float64) where {T<:PSY.Component} + component::T, + time_period::Int, + cost_data::PSY.PiecewiseStepData, + multiplier::Float64) where {T <: PSY.Component} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) gen_cost = JuMP.AffExpr(0.0) cost_data = PSY.get_y_coords(cost_data) for (i, cost) in enumerate(cost_data) JuMP.add_to_expression!(gen_cost, - cost * multiplier * - pwl_var_container[(name, i, time_period)]) + cost * multiplier * + pwl_var_container[(name, i, time_period)]) end return gen_cost end function _get_pwl_cost_expression(container::OptimizationContainer, - component::T, - time_period::Int, - cost_function::PSY.MarketBidCost, - ::PSY.PiecewiseStepData, - ::U, - ::V) where {T<:PSY.Component,U<:VariableType, - V<:AbstractDeviceFormulation} + component::T, + time_period::Int, + cost_function::PSY.MarketBidCost, + ::PSY.PiecewiseStepData, + ::U, + ::V) where {T <: PSY.Component, U <: VariableType, + V <: AbstractDeviceFormulation} incremental_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_curve) power_units = PSY.get_power_units(incremental_curve) @@ -143,34 +145,34 @@ function _get_pwl_cost_expression(container::OptimizationContainer, base_power = get_base_power(container) device_base_power = PSY.get_base_power(component) cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit(cost_component, - power_units, - base_power, - device_base_power) + power_units, + base_power, + device_base_power) resolution = get_resolution(container) dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR return _get_pwl_cost_expression(container, - component, - time_period, - cost_data_normalized, - dt) + component, + time_period, + cost_data_normalized, + dt) end """ Get cost expression for StepwiseCostReserve """ function _get_pwl_cost_expression(container::OptimizationContainer, - component::T, - time_period::Int, - cost_data::PSY.PiecewiseStepData, - multiplier::Float64) where {T<:PSY.ReserveDemandCurve} + component::T, + time_period::Int, + cost_data::PSY.PiecewiseStepData, + multiplier::Float64) where {T <: PSY.ReserveDemandCurve} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) slopes = PSY.get_y_coords(cost_data) ordc_cost = JuMP.AffExpr(0.0) for i in 1:length(slopes) JuMP.add_to_expression!(ordc_cost, - slopes[i] * multiplier * - pwl_var_container[(name, i, time_period)]) + slopes[i] * multiplier * + pwl_var_container[(name, i, time_period)]) end return ordc_cost end @@ -253,12 +255,12 @@ Add PWL cost terms for data coming from the MarketBidCost with a fixed incremental offer curve """ function _add_pwl_term!(container::OptimizationContainer, - component::T, - cost_function::PSY.MarketBidCost, - ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, - ::U, - ::V) where {T<:PSY.Component,U<:VariableType, - V<:AbstractDeviceFormulation} + component::T, + cost_function::PSY.MarketBidCost, + ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, + ::U, + ::V) where {T <: PSY.Component, U <: VariableType, + V <: AbstractDeviceFormulation} name = PSY.get_name(component) incremental_offer_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_offer_curve) @@ -268,9 +270,9 @@ function _add_pwl_term!(container::OptimizationContainer, power_units = PSY.get_power_units(incremental_offer_curve) data = get_piecewise_incrementalcurve_per_system_unit(cost_component, - power_units, - base_power, - device_base_power) + power_units, + base_power, + device_base_power) cost_is_convex = PSY.is_convex(data) if !cost_is_convex @@ -284,7 +286,7 @@ function _add_pwl_term!(container::OptimizationContainer, _add_pwl_variables!(container, T, name, t, data) _add_pwl_constraint!(container, component, U(), break_points, t) pwl_cost = _get_pwl_cost_expression(container, component, t, cost_function, data, - U(), V()) + U(), V()) pwl_cost_expressions[t] = pwl_cost end return pwl_cost_expressions @@ -295,11 +297,11 @@ end ################################################## function _add_pwl_term!(container::OptimizationContainer, - component::T, - cost_data::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, - ::U, - ::V) where {T<:PSY.Component,U<:VariableType, - V<:AbstractServiceFormulation} + component::T, + cost_data::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, + ::U, + ::V) where {T <: PSY.Component, U <: VariableType, + V <: AbstractServiceFormulation} multiplier = objective_function_multiplier(U(), V()) resolution = get_resolution(container) dt = Dates.value(Dates.Second(resolution)) / SECONDS_IN_HOUR @@ -309,9 +311,9 @@ function _add_pwl_term!(container::OptimizationContainer, cost_component = PSY.get_function_data(value_curve) device_base_power = PSY.get_base_power(component) data = get_piecewise_incrementalcurve_per_system_unit(cost_component, - power_units, - base_power, - device_base_power) + power_units, + base_power, + device_base_power) name = PSY.get_name(component) time_steps = get_time_steps(container) pwl_cost_expressions = Vector{JuMP.AffExpr}(undef, time_steps[end]) @@ -431,11 +433,11 @@ Decremental offers are not accepted for most components, except Storage systems - cost_function::MarketBidCost : container for market bid cost """ function _add_variable_cost_to_objective!(container::OptimizationContainer, - ::T, - component::PSY.Component, - cost_function::PSY.MarketBidCost, - ::U) where {T<:VariableType, - U<:AbstractDeviceFormulation} + ::T, + component::PSY.Component, + cost_function::PSY.MarketBidCost, + ::U) where {T <: VariableType, + U <: AbstractDeviceFormulation} component_name = PSY.get_name(component) @debug "Market Bid" _group = LOG_GROUP_COST_FUNCTIONS component_name time_steps = get_time_steps(container) @@ -463,11 +465,11 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, ) =# pwl_cost_expressions = _add_pwl_term!(container, - component, - cost_function, - incremental_cost_curves, - T(), - U()) + component, + cost_function, + incremental_cost_curves, + T(), + U()) jump_model = get_jump_model(container) for t in time_steps #= @@ -488,10 +490,10 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, ) =# add_to_expression!(container, - ProductionCostExpression, - pwl_cost_expressions[t], - component, - t) + ProductionCostExpression, + pwl_cost_expressions[t], + component, + t) add_to_objective_variant_expression!(container, pwl_cost_expressions[t]) end @@ -506,16 +508,16 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, end function _add_service_bid_cost!(container::OptimizationContainer, - component::PSY.Component, - service::T) where {T<:PSY.Reserve{<:PSY.ReserveDirection}} + component::PSY.Component, + service::T) where {T <: PSY.Reserve{<:PSY.ReserveDirection}} time_steps = get_time_steps(container) initial_time = get_initial_time(container) base_power = get_base_power(container) forecast_data = PSY.get_services_bid(component, - PSY.get_operation_cost(component), - service; - start_time=initial_time, - len=length(time_steps),) + PSY.get_operation_cost(component), + service; + start_time = initial_time, + len = length(time_steps)) forecast_data_values = PSY.get_cost.(TimeSeries.values(forecast_data)) # Single Price Bid if eltype(forecast_data_values) == Float64 @@ -528,12 +530,12 @@ function _add_service_bid_cost!(container::OptimizationContainer, end reserve_variable = get_variable(container, ActivePowerReserveVariable(), T, - PSY.get_name(service)) + PSY.get_name(service)) component_name = PSY.get_name(component) for t in time_steps add_to_objective_invariant_expression!(container, - data_values[t] * base_power * - reserve_variable[component_name, t]) + data_values[t] * base_power * + reserve_variable[component_name, t]) end return end @@ -541,11 +543,11 @@ end function _add_service_bid_cost!(::OptimizationContainer, ::PSY.Component, ::PSY.Service) end function _add_vom_cost_to_objective!(container::OptimizationContainer, - ::T, - component::PSY.Component, - op_cost::PSY.MarketBidCost, - ::U) where {T<:VariableType, - U<:AbstractDeviceFormulation} + ::T, + component::PSY.Component, + op_cost::PSY.MarketBidCost, + ::U) where {T <: VariableType, + U <: AbstractDeviceFormulation} incremental_cost_curves = PSY.get_incremental_offer_curves(op_cost) decremental_cost_curves = PSY.get_decremental_offer_curves(op_cost) power_units = PSY.get_power_units(incremental_cost_curves) @@ -556,12 +558,12 @@ function _add_vom_cost_to_objective!(container::OptimizationContainer, base_power = get_base_power(container) device_base_power = PSY.get_base_power(component) cost_term_normalized = get_proportional_cost_per_system_unit(cost_term, - power_units, - base_power, - device_base_power) + power_units, + base_power, + device_base_power) for t in get_time_steps(container) exp = _add_proportional_term!(container, T(), d, cost_term_normalized * multiplier, - t) + t) add_to_expression!(container, ProductionCostExpression, exp, d, t) end return diff --git a/test/run_market_bid_cost.jl b/test/run_market_bid_cost.jl index e166781d6..990d592f8 100644 --- a/test/run_market_bid_cost.jl +++ b/test/run_market_bid_cost.jl @@ -41,19 +41,19 @@ get_bus(th_solitude) #### Add MarketBidCost proposed_offer_curve = make_market_bid_curve( - [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], - [25.0, 25.5, 26.0, 27.0, 28.0, 30.0], - 10.0 + [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], + [25.0, 25.5, 26.0, 27.0, 28.0, 30.0], + 10.0, ) set_operation_cost!( - th_solitude, + th_solitude, MarketBidCost(; - no_load_cost=0.0, - start_up = (hot=3.0, warm=0.0, cold=0.0), - shut_down = 1.5, - incremental_offer_curves = proposed_offer_curve - ) + no_load_cost = 0.0, + start_up = (hot = 3.0, warm = 0.0, cold = 0.0), + shut_down = 1.5, + incremental_offer_curves = proposed_offer_curve, + ), ) #### PowerSimulations Stuff ### @@ -104,4 +104,4 @@ param_re = read_parameter(res, "ActivePowerTimeSeriesParameter__RenewableDispatc p_re = read_variable(res, "ActivePowerVariable__RenewableDispatch") # $/(per-unit MW) = $/(100 MW) = 0.01 $/MW -price = read_dual(res, "CopperPlateBalanceConstraint__System") \ No newline at end of file +price = read_dual(res, "CopperPlateBalanceConstraint__System") diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index 785e75d93..69f98e144 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -2,14 +2,14 @@ test_path = mktempdir() @testset "Test Thermal Generation Cost Functions " begin test_cases = [("linear_cost_test", 4664.88, ThermalBasicUnitCommitment), - ("linear_fuel_test", 4664.88, ThermalBasicUnitCommitment), - ("quadratic_cost_test", 3301.81, ThermalDispatchNoMin), - ("quadratic_fuel_test", 3331.12, ThermalDispatchNoMin), - ("pwl_io_cost_test", 3421.64, ThermalBasicUnitCommitment), - ("pwl_io_fuel_test", 3421.64, ThermalBasicUnitCommitment), - ("pwl_incremental_cost_test", 3424.43, ThermalBasicUnitCommitment), - ("pwl_incremental_fuel_test", 3424.43, ThermalBasicUnitCommitment), - ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment)] + ("linear_fuel_test", 4664.88, ThermalBasicUnitCommitment), + ("quadratic_cost_test", 3301.81, ThermalDispatchNoMin), + ("quadratic_fuel_test", 3331.12, ThermalDispatchNoMin), + ("pwl_io_cost_test", 3421.64, ThermalBasicUnitCommitment), + ("pwl_io_fuel_test", 3421.64, ThermalBasicUnitCommitment), + ("pwl_incremental_cost_test", 3424.43, ThermalBasicUnitCommitment), + ("pwl_incremental_fuel_test", 3424.43, ThermalBasicUnitCommitment), + ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment)] for (i, cost_reference, thermal_formulation) in test_cases @testset "$i" begin sys = build_system(PSITestSystems, "c_$(i)") @@ -17,17 +17,17 @@ test_path = mktempdir() set_device_model!(template, ThermalStandard, thermal_formulation) set_device_model!(template, PowerLoad, StaticPowerLoad) model = DecisionModel(template, - sys; - name="UC_$(i)", - optimizer=HiGHS_optimizer, - system_to_file=false, - optimizer_solve_log_print=true,) - @test build!(model; output_dir=test_path) == PSI.ModelBuildStatus.BUILT + sys; + name = "UC_$(i)", + optimizer = HiGHS_optimizer, + system_to_file = false, + optimizer_solve_log_print = true) + @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) expr = read_expression(results, "ProductionCostExpression__ThermalStandard") var_unit_cost = sum(expr[!, "Test Unit"]) - @test isapprox(var_unit_cost, cost_reference; atol=1) + @test isapprox(var_unit_cost, cost_reference; atol = 1) @test expr[!, "Test Unit"][end] == 0.0 end end @@ -67,8 +67,8 @@ end #TODO: timeseries market_bid_cost @testset "Test Thermal Generation MarketBidCost models" begin test_cases = [("fixed_market_bid_cost", 20772.76) - #"market_bid_cost", - ] + #"market_bid_cost", + ] for (i, cost_reference) in test_cases @testset "$i" begin sys = build_system(PSITestSystems, "c_$(i)") @@ -76,17 +76,17 @@ end set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) set_device_model!(template, PowerLoad, StaticPowerLoad) model = DecisionModel(template, - sys; - name="UC_$(i)", - optimizer=HiGHS_optimizer, - system_to_file=false, - optimizer_solve_log_print=true,) - @test build!(model; output_dir=test_path) == PSI.ModelBuildStatus.BUILT + sys; + name = "UC_$(i)", + optimizer = HiGHS_optimizer, + system_to_file = false, + optimizer_solve_log_print = true) + @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) expr = read_expression(results, "ProductionCostExpression__ThermalStandard") var_unit_cost = sum(expr[!, "Test Unit1"]) - @test isapprox(var_unit_cost, cost_reference; atol=1) + @test isapprox(var_unit_cost, cost_reference; atol = 1) @test expr[!, "Test Unit2"][end] == 50.0 end end @@ -95,16 +95,16 @@ end ################################### Unit Commitment tests ################################## @testset "Thermal UC With DC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -126,15 +126,15 @@ end @testset "Thermal UC With AC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) @@ -157,14 +157,14 @@ end @testset "Thermal MultiStart UC With DC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -178,14 +178,14 @@ end @testset "Thermal MultiStart UC With AC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, + "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -200,8 +200,8 @@ end ################################### Basic Unit Commitment tests ############################ @testset "Thermal Basic UC With DC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -221,8 +221,8 @@ end @testset "Thermal Basic UC With AC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), - PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StartVariable, PSY.ThermalStandard), + PSI.VariableKey(StopVariable, PSY.ThermalStandard)] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -242,8 +242,8 @@ end @testset "Thermal MultiStart Basic UC With DC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -256,8 +256,8 @@ end @testset "Thermal MultiStart Basic UC With AC - PF" begin bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -379,19 +379,19 @@ end template = get_thermal_dispatch_template_network() set_device_model!(template, DeviceModel(ThermalStandard, ThermalDispatchNoMin)) model = DecisionModel(MockOperationProblem, - CopperPlatePowerModel, - c_sys5_pwl_ed_nonconvex; - export_pwl_vars=true, - initialize_model=false,) + CopperPlatePowerModel, + c_sys5_pwl_ed_nonconvex; + export_pwl_vars = true, + initialize_model = false) @test_throws IS.InvalidValue mock_construct_device!(model, - DeviceModel(ThermalStandard, - ThermalDispatchNoMin)) + DeviceModel(ThermalStandard, + ThermalDispatchNoMin)) end ################################## Ramp Limited Testing ################################## @testset "ThermalStandard with ThermalStandardDispatch With DC - PF" begin constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -409,7 +409,7 @@ end @testset "ThermalStandard with ThermalStandardDispatch With AC - PF" begin constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -427,7 +427,7 @@ end @testset "ThermalMultiStart with ThermalStandardDispatch With DC - PF" begin constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -439,7 +439,7 @@ end @testset "ThermalMultiStart with ThermalStandardDispatch With AC - PF" begin constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -453,19 +453,19 @@ end @testset "Thermal MultiStart with MultiStart UC and DC - PF" begin constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "warm"), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "hot"), - PSI.ConstraintKey(StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "lb"), - PSI.ConstraintKey(StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "ub")] + PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "warm"), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "hot"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "lb"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "ub")] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 334, false => 282) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -478,19 +478,19 @@ end @testset "Thermal MultiStart with MultiStart UC and AC - PF" begin constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "warm"), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, - PSY.ThermalMultiStart, - "hot"), - PSI.ConstraintKey(StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "lb"), - PSI.ConstraintKey(StartupInitialConditionConstraint, - PSY.ThermalMultiStart, - "ub")] + PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "warm"), + PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSY.ThermalMultiStart, + "hot"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "lb"), + PSI.ConstraintKey(StartupInitialConditionConstraint, + PSY.ThermalMultiStart, + "ub")] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 382, false => 330) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -580,7 +580,7 @@ end device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 245, 0, 144, 144, 0, false) psi_checkobjfun_test(model, GAEVF) end @@ -589,7 +589,7 @@ end device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_pglib) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 290, 0, 96, 96, 96, false) psi_checkobjfun_test(model, GAEVF) end @@ -598,7 +598,7 @@ end device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 365, 0, 264, 264, 0, false) psi_checkobjfun_test(model, GAEVF) end @@ -607,7 +607,7 @@ end device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_pglib) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 338, 0, 144, 144, 96, false) psi_checkobjfun_test(model, GAEVF) end @@ -619,11 +619,11 @@ end set_device_model!(template, ThermalStandard, ThermalStandardDispatch) set_device_model!(template, PowerLoad, StaticPowerLoad) ED = DecisionModel(EconomicDispatchProblem, - template, - ramp_test_sys; - optimizer=HiGHS_optimizer, - initialize_model=false,) - @test build!(ED; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + template, + ramp_test_sys; + optimizer = HiGHS_optimizer, + initialize_model = false) + @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT moi_tests(ED, 10, 0, 15, 15, 5, false) psi_checksolve_test(ED, [MOI.OPTIMAL], 11191.00) end @@ -632,13 +632,13 @@ end @testset "Solving UC with CopperPlate for testing Duration Constraints" begin template = get_thermal_standard_uc_template() UC = DecisionModel(UnitCommitmentProblem, - template, - PSB.build_system(PSITestSystems, "c_duration_test"); - optimizer=HiGHS_optimizer, - initialize_model=false, - store_variable_names=true,) - build!(UC; output_dir=mktempdir(; cleanup=true)) - @test build!(UC; output_dir=mktempdir(; cleanup=true)) == PSI.ModelBuildStatus.BUILT + template, + PSB.build_system(PSITestSystems, "c_duration_test"); + optimizer = HiGHS_optimizer, + initialize_model = false, + store_variable_names = true) + build!(UC; output_dir = mktempdir(; cleanup = true)) + @test build!(UC; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT moi_tests(UC, 56, 0, 56, 14, 21, true) psi_checksolve_test(UC, [MOI.OPTIMAL], 8223.50) end @@ -673,8 +673,8 @@ end for net in networks, sys in systems, model in commitment_models template = get_thermal_dispatch_template_network(NetworkModel(net)) set_device_model!(template, ThermalStandard, model) - UC = DecisionModel(template, sys; optimizer=HiGHS_optimizer) - @test build!(UC; output_dir=mktempdir(; cleanup=true)) == + UC = DecisionModel(template, sys; optimizer = HiGHS_optimizer) + @test build!(UC; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT psi_checksolve_test(UC, [MOI.OPTIMAL, MOI.LOCALLY_SOLVED], 340000, 100000) end @@ -683,120 +683,120 @@ end @testset "Test Feedforwards to ThermalStandard with ThermalStandardDispatch" begin device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalStandard, - source=OnVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalStandard, + source = OnVariable, + affected_values = [ActivePowerVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalStandard, - source=ActivePowerVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalStandard, + source = ActivePowerVariable, + affected_values = [ActivePowerVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 365, 0, 264, 144, 0, false) end @testset "Test Feedforwards to ThermalStandard with ThermalBasicDispatch" begin device_model = DeviceModel(ThermalStandard, ThermalBasicDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalStandard, - source=OnVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalStandard, + source = OnVariable, + affected_values = [ActivePowerVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalStandard, - source=ActivePowerVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalStandard, + source = ActivePowerVariable, + affected_values = [ActivePowerVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 360, 0, 240, 120, 0, false) end @testset "Test Feedforwards to ThermalStandard with ThermalCompactDispatch" begin device_model = DeviceModel(PSY.ThermalStandard, PSI.ThermalCompactDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalStandard, - source=OnVariable, - affected_values=[PowerAboveMinimumVariable],) + component_type = ThermalStandard, + source = OnVariable, + affected_values = [PowerAboveMinimumVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalStandard, - source=PSI.PowerAboveMinimumVariable, - affected_values=[PSI.PowerAboveMinimumVariable],) + component_type = ThermalStandard, + source = PSI.PowerAboveMinimumVariable, + affected_values = [PSI.PowerAboveMinimumVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 365, 0, 264, 144, 0, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalStandardDispatch" begin device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalMultiStart, - source=OnVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalMultiStart, + source = OnVariable, + affected_values = [ActivePowerVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalMultiStart, - source=ActivePowerVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalMultiStart, + source = ActivePowerVariable, + affected_values = [ActivePowerVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 338, 0, 144, 96, 96, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalBasicDispatch" begin device_model = DeviceModel(ThermalMultiStart, ThermalBasicDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalMultiStart, - source=OnVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalMultiStart, + source = OnVariable, + affected_values = [ActivePowerVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalMultiStart, - source=ActivePowerVariable, - affected_values=[ActivePowerVariable],) + component_type = ThermalMultiStart, + source = ActivePowerVariable, + affected_values = [ActivePowerVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 336, 0, 96, 48, 96, false) end @testset "Test Feedforwards to ThermalMultiStart with ThermalCompactDispatch" begin device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalCompactDispatch) ff_sc = SemiContinuousFeedforward(; - component_type=ThermalMultiStart, - source=OnVariable, - affected_values=[PSI.PowerAboveMinimumVariable],) + component_type = ThermalMultiStart, + source = OnVariable, + affected_values = [PSI.PowerAboveMinimumVariable]) ff_ub = UpperBoundFeedforward(; - component_type=ThermalMultiStart, - source=PSI.PowerAboveMinimumVariable, - affected_values=[PSI.PowerAboveMinimumVariable],) + component_type = ThermalMultiStart, + source = PSI.PowerAboveMinimumVariable, + affected_values = [PSI.PowerAboveMinimumVariable]) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model; built_for_recurrent_solves=true) + mock_construct_device!(model, device_model; built_for_recurrent_solves = true) moi_tests(model, 338, 0, 144, 96, 96, false) end @@ -813,17 +813,19 @@ end set_must_run!(sundance, true) for rebuild in [true, false] model = DecisionModel(template_uc, - sys_5; - name="UC", - optimizer=HiGHS_optimizer, - system_to_file=false, - store_variable_names=true, - rebuild_model=rebuild,) - - solve!(model; output_dir=mktempdir()) + sys_5; + name = "UC", + optimizer = HiGHS_optimizer, + system_to_file = false, + store_variable_names = true, + rebuild_model = rebuild) + + solve!(model; output_dir = mktempdir()) ptdf_vars = get_variable_values(OptimizationProblemResults(model)) power = ptdf_vars[PowerSimulations.VariableKey{ActivePowerVariable, - ThermalStandard}("")] + ThermalStandard}( + "", + )] on = ptdf_vars[PowerSimulations.VariableKey{OnVariable, ThermalStandard}("")] start = ptdf_vars[PowerSimulations.VariableKey{StartVariable, ThermalStandard}("")] stop = ptdf_vars[PowerSimulations.VariableKey{StopVariable, ThermalStandard}("")] From a6315169e86777d5fc1c1f502664905b4700461a Mon Sep 17 00:00:00 2001 From: Purboday Ghosh <32465775+purboday@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:47:52 -0800 Subject: [PATCH 04/14] Delete test/run_market_bid_cost.jl --- test/run_market_bid_cost.jl | 107 ------------------------------------ 1 file changed, 107 deletions(-) delete mode 100644 test/run_market_bid_cost.jl diff --git a/test/run_market_bid_cost.jl b/test/run_market_bid_cost.jl deleted file mode 100644 index 990d592f8..000000000 --- a/test/run_market_bid_cost.jl +++ /dev/null @@ -1,107 +0,0 @@ -using Pkg -Pkg.activate("test") -Pkg.instantiate() - -using Revise -using PowerSystems -using PowerSystemCaseBuilder -using PowerSimulations -using StorageSystemsSimulations -using HydroPowerSimulations -using Xpress -using Logging -# using PlotlyJS -using Dates -using JuMP -using InfrastructureSystems -using DataStructures -using TimeSeries -const PSY = PowerSystems -const PSI = PowerSimulations -const PSB = PowerSystemCaseBuilder -const PM = PSI.PowerModels - -################################## -### Load Test Function Helpers ### -################################## - -include("test_utils/solver_definitions.jl") -include("test_utils/operations_problem_templates.jl") - -sys = PSB.build_system(PSITestSystems, "c_sys5_re") - -show_components(sys, ThermalStandard, [:active_power]) -show_components(sys, RenewableDispatch, [:active_power]) - -th_solitude = get_component(ThermalStandard, sys, "Solitude") -th_brighton = get_component(ThermalStandard, sys, "Brighton") -re_A = get_component(RenewableDispatch, sys, "WindBusA") -get_bus(th_solitude) - -#### Add MarketBidCost - -proposed_offer_curve = make_market_bid_curve( - [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], - [25.0, 25.5, 26.0, 27.0, 28.0, 30.0], - 10.0, -) - -set_operation_cost!( - th_solitude, - MarketBidCost(; - no_load_cost = 0.0, - start_up = (hot = 3.0, warm = 0.0, cold = 0.0), - shut_down = 1.5, - incremental_offer_curves = proposed_offer_curve, - ), -) - -#### PowerSimulations Stuff ### - -template = ProblemTemplate( - NetworkModel( - CopperPlatePowerModel; - duals = [CopperPlateBalanceConstraint], - ), -) -set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) -#set_device_model!(template, ThermalStandard, ThermalDispatchNoMin) -set_device_model!(template, PowerLoad, StaticPowerLoad) -set_device_model!(template, RenewableDispatch, RenewableFullDispatch) - -model = DecisionModel( - template, - sys; - name = "UC", - optimizer = optimizer_with_attributes(Xpress.Optimizer, "MIPRELSTOP" => 1e-3), - system_to_file = false, - store_variable_names = true, - calculate_conflict = true, - optimizer_solve_log_print = true, -) - -build!(model; output_dir = mktempdir(; cleanup = true)) - -vars = model.internal.container.variables -cons = model.internal.container.constraints - -power_balance = - cons[PowerSimulations.ConstraintKey{CopperPlateBalanceConstraint, System}("")] -lb_thermal = cons[PowerSimulations.ConstraintKey{ - ActivePowerVariableLimitsConstraint, - ThermalStandard, -}( - "lb", -)] - -solve!(model) - -res = OptimizationProblemResults(model) - -p_th = read_variable(res, "ActivePowerVariable__ThermalStandard") - -param_re = read_parameter(res, "ActivePowerTimeSeriesParameter__RenewableDispatch") -p_re = read_variable(res, "ActivePowerVariable__RenewableDispatch") - -# $/(per-unit MW) = $/(100 MW) = 0.01 $/MW -price = read_dual(res, "CopperPlateBalanceConstraint__System") From 4d40be9c0405443189e0dee6d40b6e0aaa5e5dd7 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:00:35 -0800 Subject: [PATCH 05/14] formatter --- ..._device_thermal_generation_constructors.jl | 324 +++++++++--------- 1 file changed, 166 insertions(+), 158 deletions(-) diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index 69f98e144..5e767b46b 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -1,7 +1,8 @@ test_path = mktempdir() @testset "Test Thermal Generation Cost Functions " begin - test_cases = [("linear_cost_test", 4664.88, ThermalBasicUnitCommitment), + test_cases = [ + ("linear_cost_test", 4664.88, ThermalBasicUnitCommitment), ("linear_fuel_test", 4664.88, ThermalBasicUnitCommitment), ("quadratic_cost_test", 3301.81, ThermalDispatchNoMin), ("quadratic_fuel_test", 3331.12, ThermalDispatchNoMin), @@ -9,19 +10,22 @@ test_path = mktempdir() ("pwl_io_fuel_test", 3421.64, ThermalBasicUnitCommitment), ("pwl_incremental_cost_test", 3424.43, ThermalBasicUnitCommitment), ("pwl_incremental_fuel_test", 3424.43, ThermalBasicUnitCommitment), - ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment)] + ("non_convex_io_pwl_cost_test", 3047.14, ThermalBasicUnitCommitment), + ] for (i, cost_reference, thermal_formulation) in test_cases @testset "$i" begin sys = build_system(PSITestSystems, "c_$(i)") template = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template, ThermalStandard, thermal_formulation) set_device_model!(template, PowerLoad, StaticPowerLoad) - model = DecisionModel(template, + model = DecisionModel( + template, sys; name = "UC_$(i)", optimizer = HiGHS_optimizer, system_to_file = false, - optimizer_solve_log_print = true) + optimizer_solve_log_print = true, + ) @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) @@ -94,17 +98,23 @@ end ################################### Unit Commitment tests ################################## @testset "Thermal UC With DC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalStandard), PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StopVariable, PSY.ThermalStandard), + ] - uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + uc_constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn"), + ] - aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] + aux_variables_keys = [ + PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard), + ] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -125,16 +135,22 @@ end end @testset "Thermal UC With AC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalStandard), PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] - uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.VariableKey(StopVariable, PSY.ThermalStandard), + ] + uc_constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn")] + PSI.ConstraintKey(DurationConstraint, PSY.ThermalStandard, "dn"), + ] - aux_variables_keys = [PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), - PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard)] + aux_variables_keys = [ + PSI.AuxVarKey(PSI.TimeDurationOff, ThermalStandard), + PSI.AuxVarKey(PSI.TimeDurationOn, ThermalStandard), + ] device_model = DeviceModel(ThermalStandard, ThermalStandardUnitCommitment) @@ -156,15 +172,17 @@ end end @testset "Thermal MultiStart UC With DC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] - uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), + ] + uc_constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "dn")] + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "dn"), + ] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -177,15 +195,17 @@ end end @testset "Thermal MultiStart UC With AC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] - uc_constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), + ] + uc_constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "up"), - PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, - "dn")] + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(DurationConstraint, PSY.ThermalMultiStart, "dn"), + ] device_model = DeviceModel(ThermalMultiStart, ThermalStandardUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -199,9 +219,11 @@ end ################################### Basic Unit Commitment tests ############################ @testset "Thermal Basic UC With DC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalStandard), PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StopVariable, PSY.ThermalStandard), + ] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -220,9 +242,11 @@ end end @testset "Thermal Basic UC With AC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalStandard), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalStandard), PSI.VariableKey(StartVariable, PSY.ThermalStandard), - PSI.VariableKey(StopVariable, PSY.ThermalStandard)] + PSI.VariableKey(StopVariable, PSY.ThermalStandard), + ] device_model = DeviceModel(ThermalStandard, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") @@ -241,9 +265,11 @@ end end @testset "Thermal MultiStart Basic UC With DC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), + ] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -255,9 +281,11 @@ end end @testset "Thermal MultiStart Basic UC With AC - PF" begin - bin_variable_keys = [PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), + bin_variable_keys = [ + PSI.VariableKey(OnVariable, PSY.ThermalMultiStart), PSI.VariableKey(StartVariable, PSY.ThermalMultiStart), - PSI.VariableKey(StopVariable, PSY.ThermalMultiStart)] + PSI.VariableKey(StopVariable, PSY.ThermalMultiStart), + ] device_model = DeviceModel(ThermalMultiStart, ThermalBasicUnitCommitment) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -268,7 +296,7 @@ end psi_checkobjfun_test(model, GAEVF) end -################################### Basic Dispatch tests ################################### +################################### No Minimum Dispatch tests ############################## @testset "ThermalStandard with ThermalBasicDispatch With DC - PF" begin device_model = DeviceModel(ThermalStandard, ThermalBasicDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") @@ -319,79 +347,12 @@ end psi_checkobjfun_test(model, GAEVF) end -################################### No Minimum Dispatch tests ############################## -@testset "Thermal Dispatch NoMin With DC - PF" begin - device_model = DeviceModel(ThermalStandard, ThermalDispatchNoMin) - c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") - model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - mock_construct_device!(model, device_model) - moi_tests(model, 120, 0, 120, 120, 0, false) - key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") - moi_lbvalue_test(model, key, 0.0) - psi_checkobjfun_test(model, GAEVF) - - c_sys14 = PSB.build_system(PSITestSystems, "c_sys14") - - model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys14) - mock_construct_device!(model, device_model) - moi_tests(model, 120, 0, 120, 120, 0, false) - key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") - moi_lbvalue_test(model, key, 0.0) - psi_checkobjfun_test(model, GQEVF) -end - -@testset "Thermal Dispatch NoMin With AC - PF" begin - device_model = DeviceModel(ThermalStandard, ThermalDispatchNoMin) - c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") - model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5) - mock_construct_device!(model, device_model) - moi_tests(model, 240, 0, 240, 240, 0, false) - key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") - moi_lbvalue_test(model, key, 0.0) - psi_checkobjfun_test(model, GAEVF) - - c_sys14 = PSB.build_system(PSITestSystems, "c_sys14") - - model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys14;) - mock_construct_device!(model, device_model) - moi_tests(model, 240, 0, 240, 240, 0, false) - key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") - moi_lbvalue_test(model, key, 0.0) - psi_checkobjfun_test(model, GQEVF) -end - -@testset "Thermal Dispatch NoMin With DC - PF" begin - device_model = DeviceModel(ThermalMultiStart, ThermalDispatchNoMin) - c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") - model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) - @test_throws IS.ConflictingInputsError mock_construct_device!(model, device_model) -end - -@testset "ThermalMultiStart Dispatch NoMin With AC - PF" begin - device_model = DeviceModel(ThermalMultiStart, ThermalDispatchNoMin) - c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") - model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5;) - @test_throws IS.ConflictingInputsError mock_construct_device!(model, device_model) -end - -@testset "Operation Model ThermalDispatchNoMin - and PWL Non Convex" begin - c_sys5_pwl_ed_nonconvex = PSB.build_system(PSITestSystems, "c_sys5_pwl_ed_nonconvex") - template = get_thermal_dispatch_template_network() - set_device_model!(template, DeviceModel(ThermalStandard, ThermalDispatchNoMin)) - model = DecisionModel(MockOperationProblem, - CopperPlatePowerModel, - c_sys5_pwl_ed_nonconvex; - export_pwl_vars = true, - initialize_model = false) - @test_throws IS.InvalidValue mock_construct_device!(model, - DeviceModel(ThermalStandard, - ThermalDispatchNoMin)) -end - ################################## Ramp Limited Testing ################################## @testset "ThermalStandard with ThermalStandardDispatch With DC - PF" begin - constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] + constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + ] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -408,8 +369,10 @@ end end @testset "ThermalStandard with ThermalStandardDispatch With AC - PF" begin - constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn")] + constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalStandard, "dn"), + ] device_model = DeviceModel(ThermalStandard, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_uc") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -426,8 +389,10 @@ end end @testset "ThermalMultiStart with ThermalStandardDispatch With DC - PF" begin - constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] + constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + ] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5_uc;) @@ -438,8 +403,10 @@ end end @testset "ThermalMultiStart with ThermalStandardDispatch With AC - PF" begin - constraint_keys = [PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), - PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn")] + constraint_keys = [ + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "up"), + PSI.ConstraintKey(RampConstraint, PSY.ThermalMultiStart, "dn"), + ] device_model = DeviceModel(ThermalMultiStart, ThermalStandardDispatch) c_sys5_uc = PSB.build_system(PSITestSystems, "c_sys5_pglib") model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5_uc;) @@ -452,20 +419,30 @@ end ################################### ThermalMultiStart Testing ############################## @testset "Thermal MultiStart with MultiStart UC and DC - PF" begin - constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), + constraint_keys = [ + PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSI.ConstraintKey( + StartupTimeLimitTemperatureConstraint, PSY.ThermalMultiStart, - "warm"), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + "warm", + ), + PSI.ConstraintKey( + StartupTimeLimitTemperatureConstraint, PSY.ThermalMultiStart, - "hot"), - PSI.ConstraintKey(StartupInitialConditionConstraint, + "hot", + ), + PSI.ConstraintKey( + StartupInitialConditionConstraint, PSY.ThermalMultiStart, - "lb"), - PSI.ConstraintKey(StartupInitialConditionConstraint, + "lb", + ), + PSI.ConstraintKey( + StartupInitialConditionConstraint, PSY.ThermalMultiStart, - "ub")] + "ub", + ), + ] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 334, false => 282) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -477,20 +454,30 @@ end end @testset "Thermal MultiStart with MultiStart UC and AC - PF" begin - constraint_keys = [PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), + constraint_keys = [ + PSI.ConstraintKey(ActiveRangeICConstraint, PSY.ThermalMultiStart), PSI.ConstraintKey(StartTypeConstraint, PSY.ThermalMultiStart), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + PSI.ConstraintKey( + StartupTimeLimitTemperatureConstraint, PSY.ThermalMultiStart, - "warm"), - PSI.ConstraintKey(StartupTimeLimitTemperatureConstraint, + "warm", + ), + PSI.ConstraintKey( + StartupTimeLimitTemperatureConstraint, PSY.ThermalMultiStart, - "hot"), - PSI.ConstraintKey(StartupInitialConditionConstraint, + "hot", + ), + PSI.ConstraintKey( + StartupInitialConditionConstraint, PSY.ThermalMultiStart, - "lb"), - PSI.ConstraintKey(StartupInitialConditionConstraint, + "lb", + ), + PSI.ConstraintKey( + StartupInitialConditionConstraint, PSY.ThermalMultiStart, - "ub")] + "ub", + ), + ] device_model = DeviceModel(PSY.ThermalMultiStart, PSI.ThermalMultiStartUnitCommitment) no_less_than = Dict(true => 382, false => 330) c_sys5_pglib = PSB.build_system(PSITestSystems, "c_sys5_pglib") @@ -618,11 +605,13 @@ end template = ProblemTemplate(CopperPlatePowerModel) set_device_model!(template, ThermalStandard, ThermalStandardDispatch) set_device_model!(template, PowerLoad, StaticPowerLoad) - ED = DecisionModel(EconomicDispatchProblem, + ED = DecisionModel( + EconomicDispatchProblem, template, ramp_test_sys; optimizer = HiGHS_optimizer, - initialize_model = false) + initialize_model = false, + ) @test build!(ED; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT moi_tests(ED, 10, 0, 15, 15, 5, false) psi_checksolve_test(ED, [MOI.OPTIMAL], 11191.00) @@ -631,12 +620,14 @@ end # Testing Duration Constraints @testset "Solving UC with CopperPlate for testing Duration Constraints" begin template = get_thermal_standard_uc_template() - UC = DecisionModel(UnitCommitmentProblem, + UC = DecisionModel( + UnitCommitmentProblem, template, PSB.build_system(PSITestSystems, "c_duration_test"); optimizer = HiGHS_optimizer, initialize_model = false, - store_variable_names = true) + store_variable_names = true, + ) build!(UC; output_dir = mktempdir(; cleanup = true)) @test build!(UC; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT moi_tests(UC, 56, 0, 56, 14, 21, true) @@ -671,7 +662,9 @@ end commitment_models = [ThermalStandardUnitCommitment, ThermalCompactUnitCommitment] for net in networks, sys in systems, model in commitment_models - template = get_thermal_dispatch_template_network(NetworkModel(net)) + template = get_thermal_dispatch_template_network( + NetworkModel(net), + ) set_device_model!(template, ThermalStandard, model) UC = DecisionModel(template, sys; optimizer = HiGHS_optimizer) @test build!(UC; output_dir = mktempdir(; cleanup = true)) == @@ -685,12 +678,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalStandard, source = OnVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalStandard, source = ActivePowerVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -705,12 +700,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalStandard, source = OnVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalStandard, source = ActivePowerVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -725,12 +722,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalStandard, source = OnVariable, - affected_values = [PowerAboveMinimumVariable]) + affected_values = [PowerAboveMinimumVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalStandard, source = PSI.PowerAboveMinimumVariable, - affected_values = [PSI.PowerAboveMinimumVariable]) + affected_values = [PSI.PowerAboveMinimumVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -745,12 +744,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalMultiStart, source = OnVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalMultiStart, source = ActivePowerVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -765,12 +766,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalMultiStart, source = OnVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalMultiStart, source = ActivePowerVariable, - affected_values = [ActivePowerVariable]) + affected_values = [ActivePowerVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -785,12 +788,14 @@ end ff_sc = SemiContinuousFeedforward(; component_type = ThermalMultiStart, source = OnVariable, - affected_values = [PSI.PowerAboveMinimumVariable]) + affected_values = [PSI.PowerAboveMinimumVariable], + ) ff_ub = UpperBoundFeedforward(; component_type = ThermalMultiStart, source = PSI.PowerAboveMinimumVariable, - affected_values = [PSI.PowerAboveMinimumVariable]) + affected_values = [PSI.PowerAboveMinimumVariable], + ) PSI.attach_feedforward!(device_model, ff_sc) PSI.attach_feedforward!(device_model, ff_ub) @@ -802,7 +807,8 @@ end @testset "Test Must Run ThermalGen" begin sys_5 = build_system(PSITestSystems, "c_sys5_uc") - template_uc = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) + template_uc = + ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template_uc, ThermalStandard, ThermalStandardUnitCommitment) #set_device_model!(template_uc, RenewableDispatch, FixedOutput) set_device_model!(template_uc, PowerLoad, StaticPowerLoad) @@ -812,20 +818,22 @@ end sundance = get_component(ThermalStandard, sys_5, "Sundance") set_must_run!(sundance, true) for rebuild in [true, false] - model = DecisionModel(template_uc, + model = DecisionModel( + template_uc, sys_5; name = "UC", optimizer = HiGHS_optimizer, system_to_file = false, store_variable_names = true, - rebuild_model = rebuild) + rebuild_model = rebuild, + ) solve!(model; output_dir = mktempdir()) ptdf_vars = get_variable_values(OptimizationProblemResults(model)) - power = ptdf_vars[PowerSimulations.VariableKey{ActivePowerVariable, - ThermalStandard}( - "", - )] + power = + ptdf_vars[PowerSimulations.VariableKey{ActivePowerVariable, ThermalStandard}( + "", + )] on = ptdf_vars[PowerSimulations.VariableKey{OnVariable, ThermalStandard}("")] start = ptdf_vars[PowerSimulations.VariableKey{StartVariable, ThermalStandard}("")] stop = ptdf_vars[PowerSimulations.VariableKey{StopVariable, ThermalStandard}("")] From 6836f7d00134ce8a313decaee602916dd70fe608 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:02:14 -0800 Subject: [PATCH 06/14] more formats --- ..._device_thermal_generation_constructors.jl | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index 5e767b46b..326816efe 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -296,7 +296,7 @@ end psi_checkobjfun_test(model, GAEVF) end -################################### No Minimum Dispatch tests ############################## +################################### Basic Dispatch tests ################################### @testset "ThermalStandard with ThermalBasicDispatch With DC - PF" begin device_model = DeviceModel(ThermalStandard, ThermalBasicDispatch) c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") @@ -347,6 +347,78 @@ end psi_checkobjfun_test(model, GAEVF) end +################################### No Minimum Dispatch tests ############################## +@testset "Thermal Dispatch NoMin With DC - PF" begin + device_model = DeviceModel(ThermalStandard, ThermalDispatchNoMin) + c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") + model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) + mock_construct_device!(model, device_model) + moi_tests(model, 120, 0, 120, 120, 0, false) + key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") + moi_lbvalue_test(model, key, 0.0) + psi_checkobjfun_test(model, GAEVF) + + c_sys14 = PSB.build_system(PSITestSystems, "c_sys14") + + model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys14) + mock_construct_device!(model, device_model) + moi_tests(model, 120, 0, 120, 120, 0, false) + key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") + moi_lbvalue_test(model, key, 0.0) + psi_checkobjfun_test(model, GQEVF) +end + +@testset "Thermal Dispatch NoMin With AC - PF" begin + device_model = DeviceModel(ThermalStandard, ThermalDispatchNoMin) + c_sys5 = PSB.build_system(PSITestSystems, "c_sys5") + model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5) + mock_construct_device!(model, device_model) + moi_tests(model, 240, 0, 240, 240, 0, false) + key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") + moi_lbvalue_test(model, key, 0.0) + psi_checkobjfun_test(model, GAEVF) + + c_sys14 = PSB.build_system(PSITestSystems, "c_sys14") + + model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys14;) + mock_construct_device!(model, device_model) + moi_tests(model, 240, 0, 240, 240, 0, false) + key = PSI.ConstraintKey(ActivePowerVariableLimitsConstraint, ThermalStandard, "lb") + moi_lbvalue_test(model, key, 0.0) + psi_checkobjfun_test(model, GQEVF) +end + +@testset "Thermal Dispatch NoMin With DC - PF" begin + device_model = DeviceModel(ThermalMultiStart, ThermalDispatchNoMin) + c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") + model = DecisionModel(MockOperationProblem, DCPPowerModel, c_sys5) + @test_throws IS.ConflictingInputsError mock_construct_device!(model, device_model) +end + +@testset "ThermalMultiStart Dispatch NoMin With AC - PF" begin + device_model = DeviceModel(ThermalMultiStart, ThermalDispatchNoMin) + c_sys5 = PSB.build_system(PSITestSystems, "c_sys5_pglib") + model = DecisionModel(MockOperationProblem, ACPPowerModel, c_sys5;) + @test_throws IS.ConflictingInputsError mock_construct_device!(model, device_model) +end + +@testset "Operation Model ThermalDispatchNoMin - and PWL Non Convex" begin + c_sys5_pwl_ed_nonconvex = PSB.build_system(PSITestSystems, "c_sys5_pwl_ed_nonconvex") + template = get_thermal_dispatch_template_network() + set_device_model!(template, DeviceModel(ThermalStandard, ThermalDispatchNoMin)) + model = DecisionModel( + MockOperationProblem, + CopperPlatePowerModel, + c_sys5_pwl_ed_nonconvex; + export_pwl_vars = true, + initialize_model = false, + ) + @test_throws IS.InvalidValue mock_construct_device!( + model, + DeviceModel(ThermalStandard, ThermalDispatchNoMin), + ) +end + ################################## Ramp Limited Testing ################################## @testset "ThermalStandard with ThermalStandardDispatch With DC - PF" begin constraint_keys = [ @@ -646,7 +718,7 @@ end UnitCommitmentProblem, template, sys; - optimizer = cbc_optimizer, + optimizer = HiGHS_optimizer, initialize_model = false, ) @test build!(UC; output_dir = mktempdir(; cleanup = true)) == PSI.ModelBuildStatus.BUILT From c3c27c2393d196f9afee65d0a02582c6cbf21af4 Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:06:09 -0800 Subject: [PATCH 07/14] formatter vom --- .../common/objective_function/market_bid.jl | 203 +++++++++++------- 1 file changed, 123 insertions(+), 80 deletions(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index d20d16528..04ad299ce 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -3,21 +3,24 @@ ################################################## # For Market Bid -function _add_pwl_variables!(container::OptimizationContainer, +function _add_pwl_variables!( + container::OptimizationContainer, ::Type{T}, component_name::String, time_period::Int, - cost_data::PSY.PiecewiseStepData) where {T <: PSY.Component} + cost_data::PSY.PiecewiseStepData, +) where {T <: PSY.Component} var_container = lazy_container_addition!(container, PieceWiseLinearBlockOffer(), T) # length(PiecewiseStepData) gets number of segments, here we want number of points break_points = PSY.get_x_coords(cost_data) pwlvars = Array{JuMP.VariableRef}(undef, length(break_points)) for i in 1:(length(break_points) - 1) pwlvars[i] = - var_container[(component_name, i, time_period)] = - JuMP.@variable(get_jump_model(container), - base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", - lower_bound = 0.0,) + var_container[(component_name, i, time_period)] = JuMP.@variable( + get_jump_model(container), + base_name = "PieceWiseLinearBlockOffer_$(component_name)_{pwl_$(i), $time_period}", + lower_bound = 0.0, + ) end return pwlvars end @@ -34,24 +37,29 @@ Implement the constraints for PWL Block Offer variables. That is: \\sum_{k\\in\\mathcal{K}} \\delta_{k,t} <= P_{k+1,t}^{max} - P_{k,t}^{max} ``` """ -function _add_pwl_constraint!(container::OptimizationContainer, +function _add_pwl_constraint!( + container::OptimizationContainer, component::T, ::U, break_points::Vector{Float64}, - period::Int) where {T <: PSY.Component, U <: VariableType} + period::Int, +) where {T <: PSY.Component, U <: VariableType} variables = get_variable(container, U(), T) - const_container = lazy_container_addition!(container, + const_container = lazy_container_addition!( + container, PieceWiseLinearBlockOfferConstraint(), T, - axes(variables)...) + axes(variables)..., + ) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) name = PSY.get_name(component) - const_container[name, period] = JuMP.@constraint(jump_model, + const_container[name, period] = JuMP.@constraint( + jump_model, variables[name, period] == - sum(pwl_vars[name, ix, period] - for ix in 1:len_cost_data)) + sum(pwl_vars[name, ix, period] for ix in 1:len_cost_data) + ) #= const_upperbound_container = lazy_container_addition!( @@ -64,9 +72,10 @@ function _add_pwl_constraint!(container::OptimizationContainer, # TODO: Parameter for this for ix in 1:len_cost_data - JuMP.@constraint(jump_model, - pwl_vars[name, ix, period] <= - break_points[ix + 1] - break_points[ix]) + JuMP.@constraint( + jump_model, + pwl_vars[name, ix, period] <= break_points[ix + 1] - break_points[ix] + ) end return end @@ -79,32 +88,37 @@ Implement the constraints for PWL Block Offer variables for ORDC. That is: \\sum_{k\\in\\mathcal{K}} \\delta_{k,t} <= P_{k+1,t}^{max} - P_{k,t}^{max} ``` """ -function _add_pwl_constraint!(container::OptimizationContainer, +function _add_pwl_constraint!( + container::OptimizationContainer, component::T, ::U, break_points::Vector{Float64}, sos_status::SOSStatusVariable, - period::Int) where {T <: PSY.ReserveDemandCurve, - U <: ServiceRequirementVariable} + period::Int, +) where {T <: PSY.ReserveDemandCurve, U <: ServiceRequirementVariable} name = PSY.get_name(component) variables = get_variable(container, U(), T, name) - const_container = lazy_container_addition!(container, + const_container = lazy_container_addition!( + container, PieceWiseLinearBlockOfferConstraint(), T, axes(variables)...; - meta = name) + meta = name, + ) len_cost_data = length(break_points) - 1 jump_model = get_jump_model(container) pwl_vars = get_variable(container, PieceWiseLinearBlockOffer(), T) - const_container[name, period] = JuMP.@constraint(jump_model, + const_container[name, period] = JuMP.@constraint( + jump_model, variables[name, period] == - sum(pwl_vars[name, ix, period] - for ix in 1:len_cost_data)) + sum(pwl_vars[name, ix, period] for ix in 1:len_cost_data) + ) for ix in 1:len_cost_data - JuMP.@constraint(jump_model, - pwl_vars[name, ix, period] <= - break_points[ix + 1] - break_points[ix]) + JuMP.@constraint( + jump_model, + pwl_vars[name, ix, period] <= break_points[ix + 1] - break_points[ix] + ) end return end @@ -113,66 +127,77 @@ end ################ PWL Expressions ################# ################################################## -function _get_pwl_cost_expression(container::OptimizationContainer, +function _get_pwl_cost_expression( + container::OptimizationContainer, component::T, time_period::Int, cost_data::PSY.PiecewiseStepData, - multiplier::Float64) where {T <: PSY.Component} + multiplier::Float64, +) where {T <: PSY.Component} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) gen_cost = JuMP.AffExpr(0.0) cost_data = PSY.get_y_coords(cost_data) for (i, cost) in enumerate(cost_data) - JuMP.add_to_expression!(gen_cost, - cost * multiplier * - pwl_var_container[(name, i, time_period)]) + JuMP.add_to_expression!( + gen_cost, + cost * multiplier * pwl_var_container[(name, i, time_period)], + ) end return gen_cost end -function _get_pwl_cost_expression(container::OptimizationContainer, +function _get_pwl_cost_expression( + container::OptimizationContainer, component::T, time_period::Int, cost_function::PSY.MarketBidCost, ::PSY.PiecewiseStepData, ::U, - ::V) where {T <: PSY.Component, U <: VariableType, - V <: AbstractDeviceFormulation} + ::V, +) where {T <: PSY.Component, U <: VariableType, V <: AbstractDeviceFormulation} incremental_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_curve) power_units = PSY.get_power_units(incremental_curve) cost_component = PSY.get_function_data(value_curve) base_power = get_base_power(container) device_base_power = PSY.get_base_power(component) - cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit(cost_component, + cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit( + cost_component, power_units, base_power, - device_base_power) + device_base_power, + ) resolution = get_resolution(container) dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR - return _get_pwl_cost_expression(container, + return _get_pwl_cost_expression( + container, component, time_period, cost_data_normalized, - dt) + dt, + ) end """ Get cost expression for StepwiseCostReserve """ -function _get_pwl_cost_expression(container::OptimizationContainer, +function _get_pwl_cost_expression( + container::OptimizationContainer, component::T, time_period::Int, cost_data::PSY.PiecewiseStepData, - multiplier::Float64) where {T <: PSY.ReserveDemandCurve} + multiplier::Float64, +) where {T <: PSY.ReserveDemandCurve} name = PSY.get_name(component) pwl_var_container = get_variable(container, PieceWiseLinearBlockOffer(), T) slopes = PSY.get_y_coords(cost_data) ordc_cost = JuMP.AffExpr(0.0) for i in 1:length(slopes) - JuMP.add_to_expression!(ordc_cost, - slopes[i] * multiplier * - pwl_var_container[(name, i, time_period)]) + JuMP.add_to_expression!( + ordc_cost, + slopes[i] * multiplier * pwl_var_container[(name, i, time_period)], + ) end return ordc_cost end @@ -254,13 +279,14 @@ end Add PWL cost terms for data coming from the MarketBidCost with a fixed incremental offer curve """ -function _add_pwl_term!(container::OptimizationContainer, +function _add_pwl_term!( + container::OptimizationContainer, component::T, cost_function::PSY.MarketBidCost, ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, ::U, - ::V) where {T <: PSY.Component, U <: VariableType, - V <: AbstractDeviceFormulation} + ::V, +) where {T <: PSY.Component, U <: VariableType, V <: AbstractDeviceFormulation} name = PSY.get_name(component) incremental_offer_curve = PSY.get_incremental_offer_curves(cost_function) value_curve = PSY.get_value_curve(incremental_offer_curve) @@ -269,10 +295,12 @@ function _add_pwl_term!(container::OptimizationContainer, device_base_power = PSY.get_base_power(component) power_units = PSY.get_power_units(incremental_offer_curve) - data = get_piecewise_incrementalcurve_per_system_unit(cost_component, + data = get_piecewise_incrementalcurve_per_system_unit( + cost_component, power_units, base_power, - device_base_power) + device_base_power, + ) cost_is_convex = PSY.is_convex(data) if !cost_is_convex @@ -285,8 +313,8 @@ function _add_pwl_term!(container::OptimizationContainer, for t in time_steps _add_pwl_variables!(container, T, name, t, data) _add_pwl_constraint!(container, component, U(), break_points, t) - pwl_cost = _get_pwl_cost_expression(container, component, t, cost_function, data, - U(), V()) + pwl_cost = + _get_pwl_cost_expression(container, component, t, cost_function, data, U(), V()) pwl_cost_expressions[t] = pwl_cost end return pwl_cost_expressions @@ -296,12 +324,13 @@ end ########## PWL for StepwiseCostReserve ########## ################################################## -function _add_pwl_term!(container::OptimizationContainer, +function _add_pwl_term!( + container::OptimizationContainer, component::T, cost_data::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, ::U, - ::V) where {T <: PSY.Component, U <: VariableType, - V <: AbstractServiceFormulation} + ::V, +) where {T <: PSY.Component, U <: VariableType, V <: AbstractServiceFormulation} multiplier = objective_function_multiplier(U(), V()) resolution = get_resolution(container) dt = Dates.value(Dates.Second(resolution)) / SECONDS_IN_HOUR @@ -310,10 +339,12 @@ function _add_pwl_term!(container::OptimizationContainer, power_units = PSY.get_power_units(cost_data) cost_component = PSY.get_function_data(value_curve) device_base_power = PSY.get_base_power(component) - data = get_piecewise_incrementalcurve_per_system_unit(cost_component, + data = get_piecewise_incrementalcurve_per_system_unit( + cost_component, power_units, base_power, - device_base_power) + device_base_power, + ) name = PSY.get_name(component) time_steps = get_time_steps(container) pwl_cost_expressions = Vector{JuMP.AffExpr}(undef, time_steps[end]) @@ -432,19 +463,20 @@ Decremental offers are not accepted for most components, except Storage systems - component_name::String: The component_name of the variable container - cost_function::MarketBidCost : container for market bid cost """ -function _add_variable_cost_to_objective!(container::OptimizationContainer, +function _add_variable_cost_to_objective!( + container::OptimizationContainer, ::T, component::PSY.Component, cost_function::PSY.MarketBidCost, - ::U) where {T <: VariableType, - U <: AbstractDeviceFormulation} + ::U, +) where {T <: VariableType, U <: AbstractDeviceFormulation} component_name = PSY.get_name(component) @debug "Market Bid" _group = LOG_GROUP_COST_FUNCTIONS component_name time_steps = get_time_steps(container) initial_time = get_initial_time(container) incremental_cost_curves = PSY.get_incremental_offer_curves(cost_function) decremental_cost_curves = PSY.get_decremental_offer_curves(cost_function) - if !(isnothing(decremental_cost_curves)) + if isnothing(decremental_cost_curves) error("Component $(component_name) is not allowed to participate as a demand.") end #= @@ -464,12 +496,15 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, eltype(variable_cost_forecast_values), ) =# - pwl_cost_expressions = _add_pwl_term!(container, - component, - cost_function, - incremental_cost_curves, - T(), - U()) + pwl_cost_expressions = + _add_pwl_term!( + container, + component, + cost_function, + incremental_cost_curves, + T(), + U(), + ) jump_model = get_jump_model(container) for t in time_steps #= @@ -489,11 +524,13 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, t, ) =# - add_to_expression!(container, + add_to_expression!( + container, ProductionCostExpression, pwl_cost_expressions[t], component, - t) + t, + ) add_to_objective_variant_expression!(container, pwl_cost_expressions[t]) end @@ -507,17 +544,21 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, return end -function _add_service_bid_cost!(container::OptimizationContainer, +function _add_service_bid_cost!( + container::OptimizationContainer, component::PSY.Component, - service::T) where {T <: PSY.Reserve{<:PSY.ReserveDirection}} + service::T, +) where {T <: PSY.Reserve{<:PSY.ReserveDirection}} time_steps = get_time_steps(container) initial_time = get_initial_time(container) base_power = get_base_power(container) - forecast_data = PSY.get_services_bid(component, + forecast_data = PSY.get_services_bid( + component, PSY.get_operation_cost(component), service; start_time = initial_time, - len = length(time_steps)) + len = length(time_steps), + ) forecast_data_values = PSY.get_cost.(TimeSeries.values(forecast_data)) # Single Price Bid if eltype(forecast_data_values) == Float64 @@ -529,25 +570,27 @@ function _add_service_bid_cost!(container::OptimizationContainer, error("$(eltype(forecast_data_values)) not supported for MarketBidCost") end - reserve_variable = get_variable(container, ActivePowerReserveVariable(), T, - PSY.get_name(service)) + reserve_variable = + get_variable(container, ActivePowerReserveVariable(), T, PSY.get_name(service)) component_name = PSY.get_name(component) for t in time_steps - add_to_objective_invariant_expression!(container, - data_values[t] * base_power * - reserve_variable[component_name, t]) + add_to_objective_invariant_expression!( + container, + data_values[t] * base_power * reserve_variable[component_name, t], + ) end return end function _add_service_bid_cost!(::OptimizationContainer, ::PSY.Component, ::PSY.Service) end -function _add_vom_cost_to_objective!(container::OptimizationContainer, +function _add_vom_cost_to_objective!( + container::OptimizationContainer, ::T, component::PSY.Component, op_cost::PSY.MarketBidCost, - ::U) where {T <: VariableType, - U <: AbstractDeviceFormulation} + ::U, +) where {T <: VariableType, U <: AbstractDeviceFormulation} incremental_cost_curves = PSY.get_incremental_offer_curves(op_cost) decremental_cost_curves = PSY.get_decremental_offer_curves(op_cost) power_units = PSY.get_power_units(incremental_cost_curves) From d8bdcc78e0cec8c8cd0cc2f368a6d912397f8b8c Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:20:22 -0800 Subject: [PATCH 08/14] fix typo --- .../devices/common/objective_function/market_bid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index 04ad299ce..962d0816b 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -476,7 +476,7 @@ function _add_variable_cost_to_objective!( initial_time = get_initial_time(container) incremental_cost_curves = PSY.get_incremental_offer_curves(cost_function) decremental_cost_curves = PSY.get_decremental_offer_curves(cost_function) - if isnothing(decremental_cost_curves) + if !isnothing(decremental_cost_curves) error("Component $(component_name) is not allowed to participate as a demand.") end #= From c965a3d92d0cd89d72c9c1c6dfac8bf8aa0ae87b Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:21:28 -0800 Subject: [PATCH 09/14] formatter again --- test/test_device_thermal_generation_constructors.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index 326816efe..bb1af7492 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -79,12 +79,14 @@ end template = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) set_device_model!(template, PowerLoad, StaticPowerLoad) - model = DecisionModel(template, + model = DecisionModel( + template, sys; name = "UC_$(i)", optimizer = HiGHS_optimizer, system_to_file = false, - optimizer_solve_log_print = true) + optimizer_solve_log_print = true + ) @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) From 70b0f023a7f497353a11fb81e8fe7c77c8c1dcfb Mon Sep 17 00:00:00 2001 From: rodrigomha Date: Thu, 12 Dec 2024 14:22:20 -0800 Subject: [PATCH 10/14] formatter once more time --- test/test_device_thermal_generation_constructors.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_device_thermal_generation_constructors.jl b/test/test_device_thermal_generation_constructors.jl index bb1af7492..3625211df 100644 --- a/test/test_device_thermal_generation_constructors.jl +++ b/test/test_device_thermal_generation_constructors.jl @@ -85,7 +85,7 @@ end name = "UC_$(i)", optimizer = HiGHS_optimizer, system_to_file = false, - optimizer_solve_log_print = true + optimizer_solve_log_print = true, ) @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED From c785199382910ba3577a5d73b1bf2ff999265fb9 Mon Sep 17 00:00:00 2001 From: pghosh Date: Wed, 8 Jan 2025 10:35:18 -0800 Subject: [PATCH 11/14] wip --- .../common/objective_function/market_bid.jl | 183 ++++++++++++++++++ test/test_device_load_constructors.jl | 75 +++++++ 2 files changed, 258 insertions(+) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index d20d16528..67c82d74d 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -157,6 +157,34 @@ function _get_pwl_cost_expression(container::OptimizationContainer, dt) end +function _get_pwl_cost_expression_decremental(container::OptimizationContainer, + component::T, + time_period::Int, + cost_function::PSY.MarketBidCost, + ::PSY.PiecewiseStepData, + ::U, + ::V) where {T <: PSY.Component, U <: VariableType, + V <: AbstractDeviceFormulation} + decremental_curve = PSY.get_decremental_offer_curves(cost_function) + value_curve = PSY.get_value_curve(decremental_curve) + power_units = PSY.get_power_units(decremental_curve) + cost_component = PSY.get_function_data(value_curve) + base_power = get_base_power(container) + device_base_power = PSY.get_base_power(component) + cost_data_normalized = get_piecewise_incrementalcurve_per_system_unit(cost_component, + power_units, + base_power, + device_base_power) + resolution = get_resolution(container) + dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR + multiplier = objective_function_multiplier(U(), V()) * dt + return _get_pwl_cost_expression(container, + component, + time_period, + cost_data_normalized, + multiplier) +end + """ Get cost expression for StepwiseCostReserve """ @@ -250,6 +278,20 @@ end ######## MarketBidCost: Fixed Curves ########## ############################################### +""" +Check if deceremental pwl offer curve is monotonically decreasing. +""" +function _is_convex_decremental(pwl:: PSY.PiecewiseStepData) + y_coords = PSY.get_y_coords(pwl) + for ix in 1:(length(y_coords) - 1) + if y_coords[ix] < y_coords[ix + 1] + @debug y_coords + return false + end + end + return true +end + """ Add PWL cost terms for data coming from the MarketBidCost with a fixed incremental offer curve @@ -292,6 +334,44 @@ function _add_pwl_term!(container::OptimizationContainer, return pwl_cost_expressions end +function _add_pwl_term_decremental!(container::OptimizationContainer, + component::T, + cost_function::PSY.MarketBidCost, + ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, + ::U, + ::V) where {T <: PSY.Component, U <: VariableType, + V <: AbstractDeviceFormulation} + name = PSY.get_name(component) + decremental_offer_curve = PSY.get_decremental_offer_curves(cost_function) + value_curve = PSY.get_value_curve(decremental_offer_curve) + cost_component = PSY.get_function_data(value_curve) + base_power = get_base_power(container) + device_base_power = PSY.get_base_power(component) + power_units = PSY.get_power_units(decremental_offer_curve) + + data = get_piecewise_incrementalcurve_per_system_unit(cost_component, + power_units, + base_power, + device_base_power) + + cost_is_convex = _is_convex_decremental(data) + if !cost_is_convex + error("MarketBidCost for component $(name) is non-convex") + end + + break_points = PSY.get_x_coords(data) + time_steps = get_time_steps(container) + pwl_cost_expressions = Vector{JuMP.AffExpr}(undef, time_steps[end]) + for t in time_steps + _add_pwl_variables!(container, T, name, t, data) + _add_pwl_constraint!(container, component, U(), break_points, t) + pwl_cost = _get_pwl_cost_expression_decremental(container, component, t, cost_function, data, + U(), V()) + pwl_cost_expressions[t] = pwl_cost + end + return pwl_cost_expressions +end + ################################################## ########## PWL for StepwiseCostReserve ########## ################################################## @@ -507,6 +587,81 @@ function _add_variable_cost_to_objective!(container::OptimizationContainer, return end +function _add_variable_cost_to_objective!(container::OptimizationContainer, + ::T, + component::PSY.Component, + cost_function::PSY.MarketBidCost, + ::U) where {T <: VariableType, + U <: AbstractControllablePowerLoadFormulation} + component_name = PSY.get_name(component) + @debug "Market Bid" _group = LOG_GROUP_COST_FUNCTIONS component_name + time_steps = get_time_steps(container) + initial_time = get_initial_time(container) + incremental_cost_curves = PSY.get_incremental_offer_curves(cost_function) + decremental_cost_curves = PSY.get_decremental_offer_curves(cost_function) + if !(isnothing(incremental_cost_curves)) + error("Component $(component_name) is not allowed to participate as a supply.") + end + #= + variable_cost_forecast = PSY.get_variable_cost( + component, + op_cost; + start_time = initial_time, + len = length(time_steps), + ) + variable_cost_forecast_values = TimeSeries.values(variable_cost_forecast) + parameter_container = _get_cost_function_parameter_container( + container, + CostFunctionParameter(), + component, + T(), + U(), + eltype(variable_cost_forecast_values), + ) + =# + pwl_cost_expressions = _add_pwl_term_decremental!(container, + component, + cost_function, + decremental_cost_curves, + T(), + U()) + jump_model = get_jump_model(container) + for t in time_steps + #= + set_multiplier!( + parameter_container, + # Using 1.0 here since we want to reuse the existing code that adds the mulitpler + # of base power times the time delta. + 1.0, + component_name, + t, + ) + set_parameter!( + parameter_container, + jump_model, + variable_cost_forecast_values[t], + component_name, + t, + ) + =# + add_to_expression!(container, + ProductionCostExpression, + pwl_cost_expressions[t], + component, + t) + add_to_objective_variant_expression!(container, pwl_cost_expressions[t]) + end + + # Service Cost Bid + #= + ancillary_services = PSY.get_ancillary_service_offers(op_cost) + for service in ancillary_services + _add_service_bid_cost!(container, component, service) + end + =# + return +end + function _add_service_bid_cost!(container::OptimizationContainer, component::PSY.Component, service::T) where {T <: PSY.Reserve{<:PSY.ReserveDirection}} @@ -568,3 +723,31 @@ function _add_vom_cost_to_objective!(container::OptimizationContainer, end return end + + +function _add_vom_cost_to_objective!(container::OptimizationContainer, + ::T, + component::PSY.Component, + op_cost::PSY.MarketBidCost, + ::U) where {T <: VariableType, + U <: AbstractControllablePowerLoadFormulation} + incremental_cost_curves = PSY.get_incremental_offer_curves(op_cost) + decremental_cost_curves = PSY.get_decremental_offer_curves(op_cost) + power_units = PSY.get_power_units(decremental_cost_curves) + vom_cost = PSY.get_vom_cost(decremental_cost_curves) + multiplier = 1.0 # VOM Cost is always positive + cost_term = PSY.get_proportional_term(vom_cost) + iszero(cost_term) && return + base_power = get_base_power(container) + device_base_power = PSY.get_base_power(component) + cost_term_normalized = get_proportional_cost_per_system_unit(cost_term, + power_units, + base_power, + device_base_power) + for t in get_time_steps(container) + exp = _add_proportional_term!(container, T(), d, cost_term_normalized * multiplier, + t) + add_to_expression!(container, ProductionCostExpression, exp, d, t) + end + return +end \ No newline at end of file diff --git a/test/test_device_load_constructors.jl b/test/test_device_load_constructors.jl index b36d16f86..f2f1469f6 100644 --- a/test/test_device_load_constructors.jl +++ b/test/test_device_load_constructors.jl @@ -1,3 +1,5 @@ +test_path = mktempdir() + @testset "StaticPowerLoad" begin models = [StaticPowerLoad, PowerLoadDispatch, PowerLoadInterruption] c_sys5_il = PSB.build_system(PSITestSystems, "c_sys5_il") @@ -37,6 +39,79 @@ end end end +@testset "PowerLoadDispatch AC- PF with MarketBidCost Invalid" begin + models = [PowerLoadDispatch] + c_sys5_il = PSB.build_system(PSITestSystems, "c_sys5_il") + iloadbus4 = get_component(InterruptiblePowerLoad, c_sys5_il, "IloadBus4") + set_operation_cost!( + iloadbus4, + MarketBidCost( + no_load_cost=0.0, + start_up=(hot=0.0, warm=0.0, cold=0.0), + shut_down=0.0, + incremental_offer_curves = make_market_bid_curve( + [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], + [25.0, 25.5, 26.0, 27.0, 28.0, 30.0], + 0.0 + ) + ) + ) + networks = [ACPPowerModel] + for m in models, n in networks + device_model = DeviceModel(InterruptiblePowerLoad, m) + model = DecisionModel(MockOperationProblem, n, c_sys5_il) + @test_throws ErrorException mock_construct_device!(model, device_model) + end +end + +@testset "PowerLoadDispatch AC- PF with MarketBidCost" begin + models = [PowerLoadDispatch] + c_sys5_il = PSB.build_system(PSITestSystems, "c_sys5_il") + iloadbus4 = get_component(InterruptiblePowerLoad, c_sys5_il, "IloadBus4") + set_operation_cost!( + iloadbus4, + MarketBidCost( + no_load_cost=0.0, + start_up=(hot=0.0, warm=0.0, cold=0.0), + shut_down=0.0, + decremental_offer_curves = make_market_bid_curve( + [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], + [30.0, 28.0, 27.0, 26.0, 25.5, 25.0], + 0.0 + ) + ) + ) + networks = [ACPPowerModel] + # for m in models, n in networks + # device_model = DeviceModel(InterruptiblePowerLoad, m) + # model = DecisionModel(MockOperationProblem, n, c_sys5_il) + # mock_construct_device!(model, device_model) + # moi_tests(model, 192, 0, 168, 0, 48, false) + # psi_checkobjfun_test(model, GAEVF) + # end + template = ProblemTemplate(NetworkModel(CopperPlatePowerModel; duals=[CopperPlateBalanceConstraint])) + set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) + set_device_model!(template, InterruptiblePowerLoad, PowerLoadDispatch) + model = DecisionModel(template, + c_sys5_il; + name = "UC_fixed_market_bid_cost", + optimizer = HiGHS_optimizer, + system_to_file = false, + optimizer_solve_log_print = true) + @test build!(model; output_dir = test_path) == PSI.ModelBuildStatus.BUILT + @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED + results = OptimizationProblemResults(model) + expr = read_expression(results, "ProductionCostExpression__InterruptiblePowerLoad") + println(expr) + p_th = read_variable(results, "ActivePowerVariable__ThermalStandard") + println(p_th) + price = read_dual(results, "CopperPlateBalanceConstraint__System") + println(price) + var_unit_cost = sum(expr[!, "IloadBus4"]) + @test isapprox(var_unit_cost, 50; atol = 1) + @test expr[!, "IloadBus4"][end] == 0.0 +end + @testset "PowerLoadInterruption DC- PF" begin models = [PowerLoadInterruption] c_sys5_il = PSB.build_system(PSITestSystems, "c_sys5_il") From 2f20ccdb860c9f766fb2c66e6d3b01b318eb87d5 Mon Sep 17 00:00:00 2001 From: pghosh Date: Wed, 8 Jan 2025 14:10:11 -0800 Subject: [PATCH 12/14] added get_variable and get_proportional_cost for MarketBidCost --- src/devices_models/devices/thermal_generation.jl | 4 ++++ src/utils/powersystems_utils.jl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/devices_models/devices/thermal_generation.jl b/src/devices_models/devices/thermal_generation.jl index 6c567c949..63b744ef5 100644 --- a/src/devices_models/devices/thermal_generation.jl +++ b/src/devices_models/devices/thermal_generation.jl @@ -90,6 +90,10 @@ function proportional_cost(container::OptimizationContainer, cost::PSY.ThermalGe return onvar_cost(container, cost, S, T, U, t) + PSY.get_constant_term(PSY.get_vom_cost(PSY.get_variable(cost))) + PSY.get_fixed(cost) end +function proportional_cost(container::OptimizationContainer, cost::PSY.MarketBidCost, S::OnVariable, T::PSY.ThermalGen, U::AbstractThermalFormulation, t::Int) + return proportional_cost(cost, S, T, U) +end + proportional_cost(cost::PSY.MarketBidCost, ::OnVariable, ::PSY.ThermalGen, ::AbstractThermalFormulation) = PSY.get_no_load_cost(cost) proportional_cost(::Union{PSY.MarketBidCost, PSY.ThermalGenerationCost}, ::Union{RateofChangeConstraintSlackUp, RateofChangeConstraintSlackDown}, ::PSY.ThermalGen, ::AbstractThermalFormulation) = CONSTRAINT_VIOLATION_SLACK_COST diff --git a/src/utils/powersystems_utils.jl b/src/utils/powersystems_utils.jl index 587786272..f85c7169d 100644 --- a/src/utils/powersystems_utils.jl +++ b/src/utils/powersystems_utils.jl @@ -360,3 +360,7 @@ function get_deterministic_time_series_type(sys::PSY.System) ) end end + + +"""Overload get_variable for MarketBidCost. Returns nothing""" +PSY.get_variable(value::PSY.MarketBidCost) = nothing \ No newline at end of file From 931a1ee901863ece85f2146ba0426b7121eb0940 Mon Sep 17 00:00:00 2001 From: pghosh Date: Wed, 8 Jan 2025 17:08:19 -0800 Subject: [PATCH 13/14] add unit test --- .../common/objective_function/market_bid.jl | 38 ------------------- test/test_device_load_constructors.jl | 27 ++++--------- 2 files changed, 7 insertions(+), 58 deletions(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index a83ecdf6b..299cae1de 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -401,44 +401,6 @@ function _add_pwl_term_decremental!(container::OptimizationContainer, return pwl_cost_expressions end -function _add_pwl_term_decremental!(container::OptimizationContainer, - component::T, - cost_function::PSY.MarketBidCost, - ::PSY.CostCurve{PSY.PiecewiseIncrementalCurve}, - ::U, - ::V) where {T <: PSY.Component, U <: VariableType, - V <: AbstractDeviceFormulation} - name = PSY.get_name(component) - decremental_offer_curve = PSY.get_decremental_offer_curves(cost_function) - value_curve = PSY.get_value_curve(decremental_offer_curve) - cost_component = PSY.get_function_data(value_curve) - base_power = get_base_power(container) - device_base_power = PSY.get_base_power(component) - power_units = PSY.get_power_units(decremental_offer_curve) - - data = get_piecewise_incrementalcurve_per_system_unit(cost_component, - power_units, - base_power, - device_base_power) - - cost_is_convex = _is_convex_decremental(data) - if !cost_is_convex - error("MarketBidCost for component $(name) is non-convex") - end - - break_points = PSY.get_x_coords(data) - time_steps = get_time_steps(container) - pwl_cost_expressions = Vector{JuMP.AffExpr}(undef, time_steps[end]) - for t in time_steps - _add_pwl_variables!(container, T, name, t, data) - _add_pwl_constraint!(container, component, U(), break_points, t) - pwl_cost = _get_pwl_cost_expression_decremental(container, component, t, cost_function, data, - U(), V()) - pwl_cost_expressions[t] = pwl_cost - end - return pwl_cost_expressions -end - ################################################## ########## PWL for StepwiseCostReserve ########## ################################################## diff --git a/test/test_device_load_constructors.jl b/test/test_device_load_constructors.jl index f2f1469f6..5206913da 100644 --- a/test/test_device_load_constructors.jl +++ b/test/test_device_load_constructors.jl @@ -65,7 +65,6 @@ end end @testset "PowerLoadDispatch AC- PF with MarketBidCost" begin - models = [PowerLoadDispatch] c_sys5_il = PSB.build_system(PSITestSystems, "c_sys5_il") iloadbus4 = get_component(InterruptiblePowerLoad, c_sys5_il, "IloadBus4") set_operation_cost!( @@ -75,21 +74,13 @@ end start_up=(hot=0.0, warm=0.0, cold=0.0), shut_down=0.0, decremental_offer_curves = make_market_bid_curve( - [0.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0], - [30.0, 28.0, 27.0, 26.0, 25.5, 25.0], + [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0], + [90.0, 85.0, 75.0, 70.0, 60.0, 50.0, 45.0, 40.0, 30.0, 25.0], 0.0 ) ) ) - networks = [ACPPowerModel] - # for m in models, n in networks - # device_model = DeviceModel(InterruptiblePowerLoad, m) - # model = DecisionModel(MockOperationProblem, n, c_sys5_il) - # mock_construct_device!(model, device_model) - # moi_tests(model, 192, 0, 168, 0, 48, false) - # psi_checkobjfun_test(model, GAEVF) - # end - template = ProblemTemplate(NetworkModel(CopperPlatePowerModel; duals=[CopperPlateBalanceConstraint])) + template = ProblemTemplate(NetworkModel(CopperPlatePowerModel)) set_device_model!(template, ThermalStandard, ThermalBasicUnitCommitment) set_device_model!(template, InterruptiblePowerLoad, PowerLoadDispatch) model = DecisionModel(template, @@ -102,14 +93,10 @@ end @test solve!(model) == PSI.RunStatus.SUCCESSFULLY_FINALIZED results = OptimizationProblemResults(model) expr = read_expression(results, "ProductionCostExpression__InterruptiblePowerLoad") - println(expr) - p_th = read_variable(results, "ActivePowerVariable__ThermalStandard") - println(p_th) - price = read_dual(results, "CopperPlateBalanceConstraint__System") - println(price) - var_unit_cost = sum(expr[!, "IloadBus4"]) - @test isapprox(var_unit_cost, 50; atol = 1) - @test expr[!, "IloadBus4"][end] == 0.0 + p_l = read_variable(results, "ActivePowerVariable__InterruptiblePowerLoad") + index = findfirst(row -> isapprox(100, row; atol = 1e-6), p_l.IloadBus4) + calculated_cost = expr[index, "IloadBus4"][1] + @test isapprox(-5700, calculated_cost; atol=1) end @testset "PowerLoadInterruption DC- PF" begin From e737acbe3f9a042ac9e9f609bd1cc722a7c62cb5 Mon Sep 17 00:00:00 2001 From: pghosh Date: Tue, 14 Jan 2025 12:30:34 -0800 Subject: [PATCH 14/14] made deceremental objective negative --- .../devices/common/objective_function/market_bid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices_models/devices/common/objective_function/market_bid.jl b/src/devices_models/devices/common/objective_function/market_bid.jl index 299cae1de..a81e67488 100644 --- a/src/devices_models/devices/common/objective_function/market_bid.jl +++ b/src/devices_models/devices/common/objective_function/market_bid.jl @@ -201,7 +201,7 @@ function _get_pwl_cost_expression_decremental(container::OptimizationContainer, ) resolution = get_resolution(container) dt = Dates.value(resolution) / MILLISECONDS_IN_HOUR - multiplier = objective_function_multiplier(U(), V()) * dt + multiplier = OBJECTIVE_FUNCTION_NEGATIVE * dt return _get_pwl_cost_expression(container, component, time_period,