Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Manifest.toml
*.DS_Store
*.pras
!PRASFiles.jl/test/versioned_toy/*
PRASFiles.jl/test/PRAS_Results_Export/

docs/build/
Expand Down
7 changes: 4 additions & 3 deletions PRASCore.jl/src/Simulations/Simulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ function initialize!(
rng, state.lines_available, state.lines_nexttransition,
system.lines, N)

fill!(state.stors_energy, 0)
fill!(state.genstors_energy, 0)
fill!(state.drs_energy, 0)
initialize_energy!(system.storages.initial_soc, state.stors_energy, system.storages.energy_capacity)
initialize_energy!(system.generatorstorages.initial_soc, state.genstors_energy, system.generatorstorages.energy_capacity)
initialize_energy!(system.demandresponses.initial_borrowed_load, state.drs_energy, system.demandresponses.energy_capacity)

fill!(state.drs_unservedenergy, 0)
fill!(state.drs_paybackcounter, -1)
return
Expand Down
16 changes: 16 additions & 0 deletions PRASCore.jl/src/Simulations/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ function available_capacity(

end

function initialize_energy!(
initial_values::Vector{Float64},
energy_state::Vector{Int64},
energy_capacity::Matrix{Int64}
)

if size(energy_capacity, 1) > 0
# Set initial state of charge based on initial fraction and initial capacity
energy_state .= round.(Int, initial_values .* energy_capacity[:,1])
else
fill!(energy_state, 0.0)
end

end


function update_energy!(
stors_energy::Vector{Int},
stors::AbstractAssets,
Expand Down
130 changes: 83 additions & 47 deletions PRASCore.jl/src/Systems/assets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ A struct representing storage devices in the system.
- `μ` (repair probability): Probability the unit transitions from forced outage to
operational during a given simulation timestep, for each storage unit in each
timeperiod. Unitless.
- `initial_soc`: Optional keyword for initial state of charge as a fraction [0,1.0] of `energy_capacity` at first timestep for
each storage unit at the beginning of the simulation. Default is zero.
"""
struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P}

Expand All @@ -195,12 +197,15 @@ struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,
λ::Matrix{Float64}
μ::Matrix{Float64}

initial_soc::Vector{Float64} # energy

function Storages{N,L,T,P,E}(
names::Vector{<:AbstractString}, categories::Vector{<:AbstractString},
chargecapacity::Matrix{Int}, dischargecapacity::Matrix{Int},
energycapacity::Matrix{Int}, chargeefficiency::Matrix{Float64},
dischargeefficiency::Matrix{Float64}, carryoverefficiency::Matrix{Float64},
λ::Matrix{Float64}, μ::Matrix{Float64}
λ::Matrix{Float64}, μ::Matrix{Float64};
initial_soc::Vector{Float64} = zeros(Float64, length(names))
) where {N,L,T,P,E}

n_stors = length(names)
Expand All @@ -226,10 +231,14 @@ struct Storages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,
@assert all(isfractional, λ)
@assert all(isfractional, μ)

@assert length(initial_soc) == n_stors
@assert all(isfractional, initial_soc)

#order of this is tied to how struct order is defined
new{N,L,T,P,E}(string.(names), string.(categories),
chargecapacity, dischargecapacity, energycapacity,
chargeefficiency, dischargeefficiency, carryoverefficiency,
λ, μ)
λ, μ, initial_soc)

end

Expand All @@ -242,7 +251,8 @@ function Storages{N,L,T,P,E}() where {N,L,T,P,E}
String[], String[],
zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N),
zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N),
zeros(Float64, 0, N), zeros(Float64, 0, N))
zeros(Float64, 0, N), zeros(Float64, 0, N);
initial_soc = zeros(Float64, 0))
end

Base.:(==)(x::T, y::T) where {T <: Storages} =
Expand All @@ -255,13 +265,15 @@ Base.:(==)(x::T, y::T) where {T <: Storages} =
x.discharge_efficiency == y.discharge_efficiency &&
x.carryover_efficiency == y.carryover_efficiency &&
x.λ == y.λ &&
x.μ == y.μ
x.μ == y.μ &&
x.initial_soc == y.initial_soc

Base.getindex(s::S, idxs::AbstractVector{Int}) where {S <: Storages} =
S(s.names[idxs], s.categories[idxs],s.charge_capacity[idxs,:],
s.discharge_capacity[idxs, :],s.energy_capacity[idxs, :],
s.charge_efficiency[idxs, :], s.discharge_efficiency[idxs, :],
s.carryover_efficiency[idxs, :],s.λ[idxs, :], s.μ[idxs, :])
s.carryover_efficiency[idxs, :],s.λ[idxs, :], s.μ[idxs, :];
initial_soc = s.initial_soc[idxs])

function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E}

Expand All @@ -281,6 +293,8 @@ function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E}
λ = Matrix{Float64}(undef, n_stors, N)
μ = Matrix{Float64}(undef, n_stors, N)

initial_soc = Vector{Float64}(undef, n_stors)

last_idx = 0

for s in stors
Expand All @@ -302,12 +316,15 @@ function Base.vcat(stors::Storages{N,L,T,P,E}...) where {N, L, T, P, E}
λ[rows, :] = s.λ
μ[rows, :] = s.μ

initial_soc[rows] = s.initial_soc

last_idx += n

end

return Storages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency,
carryover_efficiency, λ, μ)
carryover_efficiency, λ, μ;
initial_soc = initial_soc)

end

Expand Down Expand Up @@ -351,6 +368,8 @@ A struct representing generator-storage hybrid devices within a power system.
- `μ` (repair probability): Probability the unit transitions from forced outage to
operational during a given simulation timestep, for each generator-storage unit in each
timeperiod. Unitless.
- `initial_soc`: Optional keyword for initial state of charge as a fraction [0.0, 1.0] of
`energy_capacity` at the first timestep for each generator-storage unit. Default is zero.
"""
struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P}

Expand All @@ -372,6 +391,8 @@ struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAs
λ::Matrix{Float64}
μ::Matrix{Float64}

initial_soc::Vector{Float64} # energy

function GeneratorStorages{N,L,T,P,E}(
names::Vector{<:AbstractString}, categories::Vector{<:AbstractString},
charge_capacity::Matrix{Int}, discharge_capacity::Matrix{Int},
Expand All @@ -380,7 +401,8 @@ struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAs
carryover_efficiency::Matrix{Float64},
inflow::Matrix{Int},
gridwithdrawal_capacity::Matrix{Int}, gridinjection_capacity::Matrix{Int},
λ::Matrix{Float64}, μ::Matrix{Float64}
λ::Matrix{Float64}, μ::Matrix{Float64};
initial_soc::Vector{Float64} = zeros(Float64, length(names)),
) where {N,L,T,P,E}

n_stors = length(names)
Expand Down Expand Up @@ -416,12 +438,15 @@ struct GeneratorStorages{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAs
@assert all(isfractional, λ)
@assert all(isfractional, μ)

@assert length(initial_soc) == n_stors
@assert all(isfractional, initial_soc)

new{N,L,T,P,E}(
string.(names), string.(categories),
charge_capacity, discharge_capacity, energy_capacity,
charge_efficiency, discharge_efficiency, carryover_efficiency,
inflow, gridwithdrawal_capacity, gridinjection_capacity,
λ, μ)
λ, μ,initial_soc)

end

Expand All @@ -435,7 +460,7 @@ function GeneratorStorages{N,L,T,P,E}() where {N,L,T,P,E}
zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N),
zeros(Float64, 0, N), zeros(Float64, 0, N), zeros(Float64, 0, N),
zeros(Int, 0, N), zeros(Int, 0, N), zeros(Int, 0, N),
zeros(Float64, 0, N), zeros(Float64, 0, N))
zeros(Float64, 0, N), zeros(Float64, 0, N); initial_soc = zeros(Float64, 0))

end

Expand All @@ -452,15 +477,16 @@ Base.:(==)(x::T, y::T) where {T <: GeneratorStorages} =
x.gridwithdrawal_capacity == y.gridwithdrawal_capacity &&
x.gridinjection_capacity == y.gridinjection_capacity &&
x.λ == y.λ &&
x.μ == y.μ
x.μ == y.μ &&
x.initial_soc == y.initial_soc

Base.getindex(g_s::G, idxs::AbstractVector{Int}) where {G <: GeneratorStorages} =
G(g_s.names[idxs], g_s.categories[idxs], g_s.charge_capacity[idxs,:],
g_s.discharge_capacity[idxs, :], g_s.energy_capacity[idxs, :],
g_s.charge_efficiency[idxs, :], g_s.discharge_efficiency[idxs, :],
g_s.carryover_efficiency[idxs, :],g_s.inflow[idxs, :],
g_s.gridwithdrawal_capacity[idxs, :],g_s.gridinjection_capacity[idxs, :],
g_s.λ[idxs, :], g_s.μ[idxs, :])
g_s.λ[idxs, :], g_s.μ[idxs, :]; initial_soc = g_s.initial_soc[idxs])

function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P, E}

Expand All @@ -484,6 +510,8 @@ function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P
λ = Matrix{Float64}(undef, n_gen_stors, N)
μ = Matrix{Float64}(undef, n_gen_stors, N)

initial_soc = Vector{Float64}(undef, n_gen_stors)

last_idx = 0

for g_s in gen_stors
Expand All @@ -509,12 +537,14 @@ function Base.vcat(gen_stors::GeneratorStorages{N,L,T,P,E}...) where {N, L, T, P
λ[rows, :] = g_s.λ
μ[rows, :] = g_s.μ

initial_soc[rows] = g_s.initial_soc

last_idx += n

end

return GeneratorStorages{N,L,T,P,E}(names, categories, charge_capacity, discharge_capacity, energy_capacity, charge_efficiency, discharge_efficiency,
carryover_efficiency,inflow, gridwithdrawal_capacity, gridinjection_capacity, λ, μ)
carryover_efficiency,inflow, gridwithdrawal_capacity, gridinjection_capacity, λ, μ; initial_soc = initial_soc)

end

Expand Down Expand Up @@ -551,6 +581,8 @@ A struct representing demand response devices in the system.
- `μ` (repair probability): Probability the unit transitions from forced outage to
operational during a given simulation timestep, for each storage unit in each
timeperiod. Unitless.
- `initial_borrowed_load`: Optional initial state of borrowed load as a fraction [0,1.0] of `energy_capacity` at first timestep for
each demand response unit at the beginning of the simulation. Default is zero.
"""
struct DemandResponses{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAssets{N,L,T,P}

Expand All @@ -571,13 +603,17 @@ struct DemandResponses{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAsse
borrow_efficiency::Matrix{Float64}
payback_efficiency::Matrix{Float64}

initial_borrowed_load::Vector{Float64} # energy

function DemandResponses{N,L,T,P,E}(
names::Vector{<:AbstractString}, categories::Vector{<:AbstractString},
borrowcapacity::Matrix{Int}, paybackcapacity::Matrix{Int},
energycapacity::Matrix{Int}, borrowedenergyinterest::Matrix{Float64},
allowablepaybackperiod::Matrix{Int},
λ::Matrix{Float64}, μ::Matrix{Float64},
borrowefficiency::Matrix{Float64},paybackefficiency::Matrix{Float64}
λ::Matrix{Float64}, μ::Matrix{Float64};
borrow_efficiency::Matrix{Float64} = ones(Float64, size(borrowcapacity)),
payback_efficiency::Matrix{Float64} = ones(Float64, size(paybackcapacity)),
initial_borrowed_load::Vector{Float64} = zeros(Float64, length(names))
) where {N,L,T,P,E}

n_drs = length(names)
Expand All @@ -592,11 +628,11 @@ struct DemandResponses{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAsse
@assert all(isnonnegative, paybackcapacity)
@assert all(isnonnegative, energycapacity)

@assert size(borrowefficiency) == (n_drs, N)
@assert size(paybackefficiency) == (n_drs, N)
@assert size(borrow_efficiency) == (n_drs, N)
@assert size(payback_efficiency) == (n_drs, N)
@assert size(borrowedenergyinterest) == (n_drs, N)
@assert all(isfractional, borrowefficiency)
@assert all(isfractional, paybackefficiency)
@assert all(isfractional, borrow_efficiency)
@assert all(isfractional, payback_efficiency)
@assert all(borrowedenergyinterest .<= 1.0)
@assert all(borrowedenergyinterest .>= -1.0)

Expand All @@ -609,41 +645,31 @@ struct DemandResponses{N,L,T<:Period,P<:PowerUnit,E<:EnergyUnit} <: AbstractAsse
@assert all(isfractional, λ)
@assert all(isfractional, μ)

@assert length(initial_borrowed_load) == n_drs
@assert all(isfractional, initial_borrowed_load)

new{N,L,T,P,E}(string.(names), string.(categories),
borrowcapacity, paybackcapacity, energycapacity,
borrowedenergyinterest,
allowablepaybackperiod,
λ, μ,borrowefficiency, paybackefficiency,)
λ, μ,
borrow_efficiency,
payback_efficiency,
initial_borrowed_load)
end
end

# second constructor if borrow and payback efficiencies are not provided
function DemandResponses{N,L,T,P,E}(
names::Vector{<:AbstractString}, categories::Vector{<:AbstractString},
borrowcapacity::Matrix{Int}, paybackcapacity::Matrix{Int},
energycapacity::Matrix{Int}, borrowedenergyinterest::Matrix{Float64},
allowablepaybackperiod::Matrix{Int},
λ::Matrix{Float64}, μ::Matrix{Float64}
) where {N,L,T,P,E}
return DemandResponses{N,L,T,P,E}(
names, categories,
borrowcapacity, paybackcapacity, energycapacity,
borrowedenergyinterest, allowablepaybackperiod,
λ, μ,
ones(Float64, size(borrowcapacity)), ones(Float64, size(paybackcapacity))
)
end


# Empty DemandResponses constructor
function DemandResponses{N,L,T,P,E}() where {N,L,T,P,E}

return DemandResponses{N,L,T,P,E}(
String[], String[],
Matrix{Int}(undef, 0, N),Matrix{Int}(undef, 0, N),Matrix{Int}(undef, 0, N),
Matrix{Float64}(undef, 0, N),
Matrix{Int}(undef, 0, N),Matrix{Float64}(undef, 0, N),Matrix{Float64}(undef, 0, N),
Matrix{Float64}(undef, 0, N),Matrix{Float64}(undef, 0, N))
return DemandResponses{N,L,T,P,E}(
String[], String[],
Matrix{Int}(undef, 0, N),Matrix{Int}(undef, 0, N),Matrix{Int}(undef, 0, N),
Matrix{Float64}(undef, 0, N),
Matrix{Int}(undef, 0, N),Matrix{Float64}(undef, 0, N),Matrix{Float64}(undef, 0, N);
borrow_efficiency = Matrix{Float64}(undef, 0, N),
payback_efficiency = Matrix{Float64}(undef, 0, N),
initial_borrowed_load = zeros(Float64, 0))
end

Base.:(==)(x::T, y::T) where {T <: DemandResponses} =
Expand All @@ -657,13 +683,16 @@ Base.:(==)(x::T, y::T) where {T <: DemandResponses} =
x.borrowed_energy_interest == y.borrowed_energy_interest &&
x.allowable_payback_period == y.allowable_payback_period &&
x.λ == y.λ &&
x.μ == y.μ
x.μ == y.μ &&
x.initial_borrowed_load == y.initial_borrowed_load

Base.getindex(dr::DR, idxs::AbstractVector{Int}) where {DR <: DemandResponses} =
DR(dr.names[idxs], dr.categories[idxs],dr.borrow_capacity[idxs,:],
dr.payback_capacity[idxs, :],dr.energy_capacity[idxs, :],
dr.borrowed_energy_interest[idxs, :],dr.allowable_payback_period[idxs, :],dr.λ[idxs, :], dr.μ[idxs, :],
dr.borrow_efficiency[idxs, :], dr.payback_efficiency[idxs, :])
dr.borrowed_energy_interest[idxs, :],dr.allowable_payback_period[idxs, :],dr.λ[idxs, :], dr.μ[idxs, :];
borrow_efficiency = dr.borrow_efficiency[idxs, :],
payback_efficiency = dr.payback_efficiency[idxs, :],
initial_borrowed_load = dr.initial_borrowed_load[idxs])

function Base.vcat(drs::DemandResponses{N,L,T,P,E}...) where {N, L, T, P, E}

Expand All @@ -686,6 +715,8 @@ function Base.vcat(drs::DemandResponses{N,L,T,P,E}...) where {N, L, T, P, E}
λ = Matrix{Float64}(undef, n_drs, N)
μ = Matrix{Float64}(undef, n_drs, N)

initial_borrowed_load = Vector{Float64}(undef, n_drs)

last_idx = 0

for dr in drs
Expand All @@ -709,12 +740,17 @@ function Base.vcat(drs::DemandResponses{N,L,T,P,E}...) where {N, L, T, P, E}
λ[rows, :] = dr.λ
μ[rows, :] = dr.μ

initial_borrowed_load[rows] = dr.initial_borrowed_load

last_idx += n

end

return DemandResponses{N,L,T,P,E}(names, categories, borrow_capacity, payback_capacity, energy_capacity,
borrowed_energy_interest,allowable_payback_period, λ, μ, borrow_efficiency, payback_efficiency)
borrowed_energy_interest,allowable_payback_period, λ, μ;
borrow_efficiency = borrow_efficiency,
payback_efficiency = payback_efficiency,
initial_borrowed_load = initial_borrowed_load)

end

Expand Down
Loading
Loading