Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jd/psy4v2 #39

Merged
merged 22 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "StorageSystemsSimulations"
uuid = "e2f1a126-19d0-4674-9252-42b2384f8e3c"
authors = ["Jose Daniel Lara, Rodrigo Henriquez-Auba, Sourabh Dalvi"]
version = "0.9.0"
version = "0.10.0"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand All @@ -18,10 +18,10 @@ PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd"
Dates = "1"
DataStructures = "~0.18"
DocStringExtensions = "~0.8, ~0.9"
InfrastructureSystems = "1"
InfrastructureSystems = "2"
JuMP = "1"
LinearAlgebra = "1"
MathOptInterface = "1"
PowerSimulations = "^0.27"
PowerSystems = "3"
PowerSimulations = "^0.28"
PowerSystems = "4"
julia = "^1.6"
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ StorageSystemsSimulations = "e2f1a126-19d0-4674-9252-42b2384f8e3c"

[compat]
Documenter = "1"
InfrastructureSystems = "1"
InfrastructureSystems = "2"
12 changes: 6 additions & 6 deletions docs/src/formulation_library/StorageDispatchWithReserves.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ StorageDispatchWithReserves

## Attributes

- `"reservation"`: Forces the battery to operate exclusively on charge or discharge mode through the entire operation interval. We recommend setting this to false for models with relatively large resolutions (e.g., 1-Hr) since the storage can take simultaneous charge or discharge positions on average over the period.
- `"cycling_limits"`: This limits the battery's energy cycling. The calculation uses the total energy charge/discharge and the number of cycles. Currently, the formulation only supports a fixed value per operation period. Additional variables for [`StorageChargeCyclingSlackVariable`](@ref) and [`StorageDischargeCyclingSlackVariable`](@ref) are included in the model if `use_slacks` is set to `true`.
- `"energy_target"`: Set a target at the end of the model horizon for the state of charge. Currently, the formulation only supports a fixed value per operation period. Additional variables for [`StorageEnergyShortageVariable`](@ref) and [`StorageEnergySurplusVariable`](@ref) are included in the model if `use_slacks` is set to `true`.
- `"reservation"`: Forces the storage to operate exclusively on charge or discharge mode through the entire operation interval. We recommend setting this to false for models with relatively longer time resolutions (e.g., 1-Hr) since the storage can take simultaneous charge or discharge positions on average over the period.
- `"cycling_limits"`: This limits the storage's energy cycling. A single charging (discharging) cycle is fully charging (discharging) the storage once. The calculation uses the total energy charge/discharge and the number of cycles. Currently, the formulation only supports a fixed value per operation period. Additional variables for [`StorageChargeCyclingSlackVariable`](@ref) and [`StorageDischargeCyclingSlackVariable`](@ref) are included in the model if `use_slacks` is set to `true`.
- `"energy_target"`: Set a target at the end of the model horizon for the storage's state of charge. Currently, the formulation only supports a fixed value per operation period. Additional variables for [`StorageEnergyShortageVariable`](@ref) and [`StorageEnergySurplusVariable`](@ref) are included in the model if `use_slacks` is set to `true`.

!!! warning

Combining the cycle limits and energy target attributes is not recommended. Both
attributes impose constraints on the energy; there is no guarantee that the constraints can be satisfied simultaneously.
Combining cycle limits and energy target attributes is not recommended. Both
attributes impose constraints on energy. There is no guarantee that the constraints can be satisfied simultaneously.

- `"complete_coverage"`: This attribute implements constraints that require the battery to cover the sum of all the ancillary services it participates in simultaneously. It is equivalent to holding energy in case all the services get deployed simultaneously. This constraint is added to the constraints that cover each service independently and corresponds to a more conservative operation regime.
- `"regularization"`: This attribute smooths the charge/discharge profiles to avoid bang-bang solutions via a penalty on the absolute value of the intra-temporal variations of the charge and discharge power. The model can stall in models with large amounts of curtailment or long periods with negative or zero prices due to numerical degeneracy. The regularization term is scaled by the power limits to normalize the term and avoid additional penalties to larger storage units.
- `"regularization"`: This attribute smooths the charge/discharge profiles to avoid bang-bang solutions via a penalty on the absolute value of the intra-temporal variations of the charge and discharge power. Solving for optimal storage dispatch can stall in models with large amounts of curtailment or long periods with negative or zero prices due to numerical degeneracy. The regularization term is scaled by the storage device's power limits to normalize the term and avoid additional penalties to larger storage units.

!!! danger

Expand Down
6 changes: 3 additions & 3 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ CurrentModule = StorageSystemsSimulations
## Overview

`StorageSimulations.jl` is a `PowerSimulations.jl` extension to support formulations and models
related to energ storage.
related to energy storage.

Operational Storage Model can have multiple combinations of different restrictions. For instance,
An Operational Storage Model can have multiple combinations of different restrictions. For instance,
it might be relevant to a study to consider cycling limits or employ energy targets coming from a planning model. To manage all these variations `StorageSimulations.jl` heavily uses the `DeviceModel` attributes feature.

For example, the formulation `StorageDispatchWithReserves` can be parametrized as follows:

```julia
DeviceModel(
StorageType, # E.g. BatteryEMS or GenericStorage
StorageType, # E.g. EnergyReservoirStorage
StorageDispatchWithReserves;
attributes=Dict(
"reservation" => true,
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/single_stage_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ set_available!(orcd, false)
```

```@example op_problem
batt = get_component(BatteryEMS, c_sys5_bat, "Bat2")
batt = get_component(EnergyReservoirStorage, c_sys5_bat, "Bat2")

operation_cost = get_operation_cost(batt)
```
Expand All @@ -48,7 +48,7 @@ set_device_model!(template_uc, Line, StaticBranch)

```@example op_problem
storage_model = DeviceModel(
BatteryEMS,
EnergyReservoirStorage,
StorageDispatchWithReserves;
attributes=Dict(
"reservation" => true,
Expand Down
1 change: 1 addition & 0 deletions src/StorageSystemsSimulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const PSI = PowerSimulations
const PSY = PowerSystems
const PM = PSI.PM
const IS = InfrastructureSystems
const ISOPT = InfrastructureSystems.Optimization

using DocStringExtensions
@template (FUNCTIONS, METHODS) = """
Expand Down
4 changes: 2 additions & 2 deletions src/core/feedforward.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct EnergyTargetFeedforward <: PSI.AbstractAffectFeedforward
affected_values::Vector{DataType},
target_period::Int,
penalty_cost::Float64,
meta=PSI.CONTAINER_KEY_EMPTY_META,
meta=ISOPT.CONTAINER_KEY_EMPTY_META,
) where {T}
values_vector = Vector{PSI.VariableKey}(undef, length(affected_values))
for (ix, v) in enumerate(affected_values)
Expand Down Expand Up @@ -135,7 +135,7 @@ struct EnergyLimitFeedforward <: PSI.AbstractAffectFeedforward
source::Type{T},
affected_values::Vector{DataType},
number_of_periods::Int,
meta=PSI.CONTAINER_KEY_EMPTY_META,
meta=ISOPT.CONTAINER_KEY_EMPTY_META,
) where {T}
values_vector = Vector{PSI.VariableKey}(undef, length(affected_values))
for (ix, v) in enumerate(affected_values)
Expand Down
2 changes: 1 addition & 1 deletion src/core/formulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The formulation supports the following attributes. See Documentation for more de

```julia
DeviceModel(
StorageType, # E.g. BatteryEMS or GenericStorage
StorageType, # E.g. EnergyReservoirStorage or GenericStorage
StorageDispatchWithReserves;
attributes=Dict(
"reservation" => true,
Expand Down
8 changes: 4 additions & 4 deletions src/storage_constructor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function PSI.construct_device!(
model::PSI.DeviceModel{St, D},
network_model::PSI.NetworkModel{S},
) where {St <: PSY.Storage, D <: StorageDispatchWithReserves, S <: PM.AbstractPowerModel}
devices = PSI.get_available_components(St, sys)
devices = PSI.get_available_components(model, sys)
_active_power_variables_and_expressions(container, devices, model, network_model)
PSI.add_variables!(container, PSI.ReactivePowerVariable, devices, D())

Expand Down Expand Up @@ -252,7 +252,7 @@ function PSI.construct_device!(
model::PSI.DeviceModel{St, D},
network_model::PSI.NetworkModel{S},
) where {St <: PSY.Storage, D <: StorageDispatchWithReserves, S <: PM.AbstractPowerModel}
devices = PSI.get_available_components(St, sys)
devices = PSI.get_available_components(model, sys)
_active_power_and_energy_bounds(container, devices, model, network_model)

PSI.add_constraints!(
Expand Down Expand Up @@ -318,7 +318,7 @@ function PSI.construct_device!(
D <: StorageDispatchWithReserves,
S <: PM.AbstractActivePowerModel,
}
devices = PSI.get_available_components(St, sys)
devices = PSI.get_available_components(model, sys)
_active_power_variables_and_expressions(container, devices, model, network_model)

if PSI.get_attribute(model, "regularization")
Expand All @@ -345,7 +345,7 @@ function PSI.construct_device!(
D <: StorageDispatchWithReserves,
S <: PM.AbstractActivePowerModel,
}
devices = PSI.get_available_components(St, sys)
devices = PSI.get_available_components(model, sys)
_active_power_and_energy_bounds(container, devices, model, network_model)

# Energy Balanace limits
Expand Down
Loading
Loading