Skip to content

Commit

Permalink
Make test_cost_functions pass
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielKS committed Mar 31, 2024
1 parent 31b848a commit f0fdd47
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 118 deletions.
6 changes: 6 additions & 0 deletions src/PowerSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ export get_data
export iterate_components
export get_time_series_multiple
export get_variable_cost
export get_no_load_cost
export get_start_up
export get_shut_down
export get_incremental_offer_curves
export get_decremental_offer_curves
export get_ancillary_services
export get_services_bid
export set_variable_cost!
export set_service_bid!
Expand Down
17 changes: 12 additions & 5 deletions src/models/cost_function_timeseries.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# MarketBidCost has two variable costs, here we mean the incremental one
get_generation_variable_cost(cost::MarketBidCost) = get_incremental_offer_curves(cost)
set_generation_variable_cost!(cost::MarketBidCost, val) =
set_incremental_offer_curves!(cost, val)
get_generation_variable_cost(cost::OperationalCost) = get_variable_cost(cost)
set_generation_variable_cost!(cost::OperationalCost, val) = set_variable_cost(cost, val)

"""
Returns variable cost bids time-series data.
Expand Down Expand Up @@ -28,7 +35,7 @@ function get_variable_cost(
end

"""
Returns variable cost bids time-series data for MarketBidCost.
Returns variable cost bids time-series data for MarketBidCost.
# Arguments
- `device::StaticInjection`: Static injection device
Expand All @@ -42,10 +49,10 @@ function get_variable_cost(
start_time::Union{Nothing, Dates.DateTime} = nothing,
len::Union{Nothing, Int} = nothing,
)
time_series_key = get_variable(cost)
time_series_key = get_generation_variable_cost(cost)
if isnothing(time_series_key)
error(
"Cost component has a `nothing` stored in field `variable`, Please use `set_variable_cost!` to add variable cost forecast.",
"Cost component is empty, please use `set_variable_cost!` to add variable cost forecast.",
)
end
raw_data = IS.get_time_series_by_key(
Expand Down Expand Up @@ -106,7 +113,7 @@ function get_services_bid(
start_time::Union{Nothing, Dates.DateTime} = nothing,
len::Union{Nothing, Int} = nothing,
)
variable_ts_key = get_variable(cost)
variable_ts_key = get_generation_variable_cost(cost)
service_ts_key = IS.TimeSeriesKey(variable_ts_key.time_series_type, get_name(service))
raw_data = IS.get_time_series_by_key(
service_ts_key,
Expand Down Expand Up @@ -135,7 +142,7 @@ function set_variable_cost!(
add_time_series!(sys, component, time_series_data)
key = IS.TimeSeriesKey(time_series_data)
market_bid_cost = get_operation_cost(component)
set_variable!(market_bid_cost, key)
set_generation_variable_cost!(market_bid_cost, key)
return
end

Expand Down
2 changes: 1 addition & 1 deletion src/models/cost_functions/HydroGenerationCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ end
# Constructor for demo purposes; non-functional.
function HydroGenerationCost(::Nothing)
HydroGenerationCost(;
variable = InputOutputFuelCurve(LinearFunctionData(0.0), 0.0, nothing),
variable = zero(FuelCurve),
fixed = 0.0,
)
end
Expand Down
2 changes: 1 addition & 1 deletion src/models/cost_functions/LoadCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ end
# Constructor for demo purposes; non-functional.
function LoadCost(::Nothing)
LoadCost(;
variable = InputOutputCostCurve(LinearFunctionData(0.0)),
variable = zero(CostCurve),
fixed = 0.0,
)
end
Expand Down
37 changes: 35 additions & 2 deletions src/models/cost_functions/MarketBidCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,17 @@ mutable struct MarketBidCost <: OperationalCost
"shut-down cost"
shut_down::Float64
"Variable Cost TimeSeriesKey"
incremental_offer_curves::Union{Nothing, IS.TimeSeriesKey, PiecewiseLinearData}
incremental_offer_curves::Union{
Nothing,
IS.TimeSeriesKey,
CostCurve{InputOutputCurve{PiecewiseLinearData}},
}
"Variable Cost TimeSeriesKey"
decremental_offer_curves::Union{Nothing, IS.TimeSeriesKey, PiecewiseLinearData}
decremental_offer_curves::Union{
Nothing,
IS.TimeSeriesKey,
CostCurve{InputOutputCurve{PiecewiseLinearData}},
}
"Bids for the ancillary services"
ancillary_services::Vector{Service}
end
Expand Down Expand Up @@ -63,6 +71,31 @@ function MarketBidCost(::Nothing)
)
end

"""
Accepts a single `start_up` value to use as the `hot` value, with `warm` and `cold` set to
`0.0`.
"""
function MarketBidCost(
no_load_cost,
start_up::Real,
shut_down,
incremental_offer_curves = nothing,
decremental_offer_curves = nothing,
ancillary_services = Vector{Service}(),
)
# Intended for use with generators that are not multi-start (e.g. ThermalStandard).
# Operators use `hot` when they don’t have multiple stages.
start_up_multi = (hot = Float64(start_up), warm = 0.0, cold = 0.0)
return MarketBidCost(
no_load_cost,
start_up_multi,
shut_down,
incremental_offer_curves,
decremental_offer_curves,
ancillary_services,
)
end

"""Get [`MarketBidCost`](@ref) `no_load_cost`."""
get_no_load_cost(value::MarketBidCost) = value.no_load_cost
"""Get [`MarketBidCost`](@ref) `start_up`."""
Expand Down
8 changes: 4 additions & 4 deletions src/models/cost_functions/RenewableGenerationCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ mutable struct RenewableGenerationCost <: OperationalCost
curtailment_cost::CostCurve
end

function RenewableGenerationCost(;
variable,
curtailment_cost = InputOutputCostCurve(LinearFunctionData(0.0)),
function RenewableGenerationCost(
variable;
curtailment_cost = zero(CostCurve),
)
RenewableGenerationCost(variable, curtailment_cost)
end

# Constructor for demo purposes; non-functional.
function RenewableGenerationCost(::Nothing)
RenewableGenerationCost(;
variable = InputOutputCostCurve(LinearFunctionData(0.0)),
variable = zero(CostCurve),
)
end

Expand Down
23 changes: 21 additions & 2 deletions src/models/cost_functions/StorageCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,28 @@ mutable struct StorageCost <: OperationalCost
energy_surplus_cost::Float64
end

StorageCost(
charge_variable_cost::CostCurve,
discharge_variable_cost::CostCurve,
fixed::Float64,
start_up::Real,
shut_down::Float64,
energy_shortage_cost::Float64,
energy_surplus_cost::Float64,
) =
StorageCost(
charge_variable_cost,
discharge_variable_cost,
fixed,
Float64(start_up),
shut_down,
energy_shortage_cost,
energy_surplus_cost,
)

function StorageCost(;
charge_variable_cost = InputOutputCostCurve(LinearFunctionData(0.0)),
discharge_variable_cost = InputOutputCostCurve(LinearFunctionData(0.0)),
charge_variable_cost = zero(CostCurve),
discharge_variable_cost = zero(CostCurve),
fixed = 0.0,
start_up = 0.0,
shut_down = 0.0,
Expand Down
2 changes: 1 addition & 1 deletion src/models/cost_functions/ThermalGenerationCost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ end
# Constructor for demo purposes; non-functional.
function ThermalGenerationCost(::Nothing)
ThermalGenerationCost(;
variable = InputOutputCostCurve(LinearFunctionData(0.0)),
variable = zero(CostCurve),
fixed = 0.0,
start_up = 0.0,
shut_down = 0.0,
Expand Down
11 changes: 7 additions & 4 deletions src/models/cost_functions/variable_cost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ Direct representation of the variable operation cost of a power plant in currenc
of a [`ValueCurve`][@ref] that may represent input-output, incremental, or average rate
data.
"""
@kwdef struct CostCurve <: ProductionVariableCost
@kwdef struct CostCurve{T} <: ProductionVariableCost where {T <: ValueCurve}
"The underlying `ValueCurve` representation of this `ProductionVariableCost`"
value_curve::ValueCurve
value_curve::T
end

Base.:(==)(a::CostCurve, b::CostCurve) =
Expand All @@ -31,13 +31,16 @@ Representation of the variable operation cost of a power plant in terms of fuel
liters, m^3, etc.), coupled with a conversion factor between fuel and currency. Composed of
a [`ValueCurve`][@ref] that may represent input-output, incremental, or average rate data.
"""
@kwdef struct FuelCurve <: ProductionVariableCost
@kwdef struct FuelCurve{T} <: ProductionVariableCost where {T <: ValueCurve}
"The underlying `ValueCurve` representation of this `ProductionVariableCost`"
value_curve::ValueCurve
value_curve::T
"Either a fixed value for fuel cost or the name of a fuel cost time series name"
fuel_cost::Union{Float64, String}
end

FuelCurve(value_curve::ValueCurve, fuel_cost::Int) =
FuelCurve(value_curve, Float64(fuel_cost))

Base.:(==)(a::FuelCurve, b::FuelCurve) =
(get_value_curve(a) == get_value_curve(b)) &&
(get_fuel_cost(a) == get_fuel_cost(b))
Expand Down
17 changes: 0 additions & 17 deletions src/models/supplemental_constructors.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
"""
Accepts a single `start_up` value to use as the `hot` value, with `warm` and `cold` set to
`0.0`.
"""
function MarketBidCost(
no_load,
start_up::Number,
shut_down,
variable = nothing,
ancillary_services = Vector{Service}(),
)
# Intended for use with generators that are not multi-start (e.g. ThermalStandard).
# Operators use `hot` when they don’t have multiple stages.
start_up_multi = (hot = start_up, warm = 0.0, cold = 0.0)
return MarketBidCost(no_load, start_up_multi, shut_down, variable, ancillary_services)
end

"""Accepts angle_limits as a Float64."""
function Line(
name,
Expand Down
6 changes: 4 additions & 2 deletions src/parsers/power_models_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ function make_hydro_gen(gen_name, d, bus, sys_mbase)
end

function make_renewable_dispatch(gen_name, d, bus, sys_mbase)
cost = RenewableGenerationCost(; variable = InputOutputCostCurve(LinearFunctionData(0.0)))
cost = RenewableGenerationCost(;
variable = CostCurve(InputOutputCurve(LinearFunctionData(0.0))),
)
base_conversion = sys_mbase / d["mbase"]

rating = calculate_rating(d["pmax"], d["qmax"])
Expand Down Expand Up @@ -456,7 +458,7 @@ function make_thermal_gen(gen_name::AbstractString, d::Dict, bus::ACBus, sys_mba
cost = QuadraticFunctionData(get.(Ref(coeffs), quadratic_degrees, 0)...)
fixed = (d["ncost"] >= 1) ? last(d["cost"]) : 0.0
end
cost = InputOutputCostCurve(cost)
cost = CostCurve(InputOutputCurve((cost)))
startup = d["startup"]
shutdn = d["shutdown"]
else
Expand Down
Loading

0 comments on commit f0fdd47

Please sign in to comment.