-
Notifications
You must be signed in to change notification settings - Fork 123
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
Add new resource type: CCS with solvent storage #795
base: solvent-storage
Are you sure you want to change the base?
Changes from 4 commits
65e25d7
6fabc96
7147493
f1bbba4
5b0c5ff
d201184
4eb44e8
165836d
faaf58a
012a28d
cccab41
74650dd
e008d1f
c2ff871
5e3d0be
9f82165
26d82e8
e0e3dca
4daa001
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -42,6 +42,43 @@ Finally, the next constraint enforces that the initial storage level for each in | |||||||||||||||||||||||||||||||||||||||
\quad \forall n \in \mathcal{N}, o \in \mathcal{O}^{LDES} | ||||||||||||||||||||||||||||||||||||||||
\end{aligned} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
**Bound storage inventory in non-representative periods** | ||||||||||||||||||||||||||||||||||||||||
We need additional variables and constraints to ensure that the storage content is within zero and the installed energy capacity in non-representative periods. We introduce | ||||||||||||||||||||||||||||||||||||||||
the variables $\Delta Q^{max,pos}_{o,z,m}$ and $\Delta Q^{max,neg}_{o,z,m}$ that represent the maximum positive and negative storage content variations within the representative | ||||||||||||||||||||||||||||||||||||||||
period $m$, respectively, extracted as: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||||||||||||||||
& \Delta Q^{max,pos}_{o,z,m} \geq \Gamma_{o,z,(m-1)\times \tau^{period}+t } - \Gamma_{o,z,(m-1)\times \tau^{period}+1 } \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}, t \in \mathcal{T} | ||||||||||||||||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||||||||||||||||
& \Delta Q^{max,neg}_{o,z,m} \leq \Gamma_{o,z,(m-1)\times \tau^{period}+t } - \Gamma_{o,z,(m-1)\times \tau^{period}+1 } \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}, t \in \mathcal{T} | ||||||||||||||||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
For every input period $n \in \mathcal{N}$, the maximum storage is computed and constrained to be less than or equal to the installed energy capacity as: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||||||||||||||||
& Q_{o,z,n} \times \left(1-\eta_{o,z}^{loss}\right) - \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} + \Delta Q^{max,pos}_{o,z,f(n)} \leq \Delta^{total, energy}_{o,z} \\ | ||||||||||||||||||||||||||||||||||||||||
& \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, n \in \mathcal{N} | ||||||||||||||||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Similarly, the minimum storage content is imposed to be positive in every period of the time horizon: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||||||||||||||||
& Q_{o,z,n} \times \left(1-\eta_{o,z}^{loss}\right) - \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} + \Delta Q^{max,neg}_{o,z,f(n)} \geq 0 \\ | ||||||||||||||||||||||||||||||||||||||||
& \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, n \in \mathcal{N} | ||||||||||||||||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Additional details on this approach are available in [Parolin et al., 2024](https://doi.org/10.48550/arXiv.2409.19079). | ||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||
function hydro_inter_period_linkage!(EP::Model, inputs::Dict) | ||||||||||||||||||||||||||||||||||||||||
println("Long Duration Storage Module for Hydro Reservoir") | ||||||||||||||||||||||||||||||||||||||||
|
@@ -71,6 +108,12 @@ function hydro_inter_period_linkage!(EP::Model, inputs::Dict) | |||||||||||||||||||||||||||||||||||||||
# Build up inventory can be positive or negative | ||||||||||||||||||||||||||||||||||||||||
@variable(EP, vdSOC_HYDRO[y in STOR_HYDRO_LONG_DURATION, w = 1:REP_PERIOD]) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Maximum positive storage inventory change within subperiod | ||||||||||||||||||||||||||||||||||||||||
@variable(EP, vdSOC_maxPos_HYDRO[y in STOR_HYDRO_LONG_DURATION, w=1:REP_PERIOD] >= 0) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Maximum negative storage inventory change within subperiod | ||||||||||||||||||||||||||||||||||||||||
@variable(EP, vdSOC_maxNeg_HYDRO[y in STOR_HYDRO_LONG_DURATION, w=1:REP_PERIOD] <= 0) | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
### Constraints ### | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Links last time step with first time step, ensuring position in hour 1 is within eligible change from final hour position | ||||||||||||||||||||||||||||||||||||||||
|
@@ -111,4 +154,27 @@ function hydro_inter_period_linkage!(EP::Model, inputs::Dict) | |||||||||||||||||||||||||||||||||||||||
r in REP_PERIODS_INDEX], | ||||||||||||||||||||||||||||||||||||||||
vSOC_HYDROw[y,r]==EP[:vS_HYDRO][y, hours_per_subperiod * dfPeriodMap[r, :Rep_Period_Index]] - | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
vdSOC_HYDRO[y, dfPeriodMap[r, :Rep_Period_Index]]) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Extract maximum storage level variation (positive) within subperiod | ||||||||||||||||||||||||||||||||||||||||
@constraint(EP, cMaxSoCVarPos_H[y in STOR_HYDRO_LONG_DURATION, w=1:REP_PERIOD, t=2:hours_per_subperiod], | ||||||||||||||||||||||||||||||||||||||||
vdSOC_maxPos_HYDRO[y,w] >= EP[:vS_HYDRO][y,hours_per_subperiod*(w-1)+t] - EP[:vS_HYDRO][y,hours_per_subperiod*(w-1)+1]) | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Extract maximum storage level variation (negative) within subperiod | ||||||||||||||||||||||||||||||||||||||||
@constraint(EP, cMaxSoCVarNeg_H[y in STOR_HYDRO_LONG_DURATION, w=1:REP_PERIOD, t=2:hours_per_subperiod], | ||||||||||||||||||||||||||||||||||||||||
vdSOC_maxNeg_HYDRO[y,w] <= EP[:vS_HYDRO][y,hours_per_subperiod*(w-1)+t] - EP[:vS_HYDRO][y,hours_per_subperiod*(w-1)+1]) | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Max storage content within each modeled period cannot exceed installed energy capacity | ||||||||||||||||||||||||||||||||||||||||
@constraint(EP, cSoCLongDurationStorageMaxInt_H[y in STOR_HYDRO_LONG_DURATION, r in MODELED_PERIODS_INDEX], | ||||||||||||||||||||||||||||||||||||||||
vSOC_HYDROw[y,r]-(1/efficiency_down(gen[y])*EP[:vP][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||||||||||||||||
-EP[:vSPILL][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1] | ||||||||||||||||||||||||||||||||||||||||
+inputs["pP_Max"][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]*EP[:eTotalCap][y] | ||||||||||||||||||||||||||||||||||||||||
+vdSOC_maxPos_HYDRO[y,dfPeriodMap[r,:Rep_Period_Index]] <= hydro_energy_to_power_ratio(gen[y])*EP[:eTotalCap][y]) | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Min storage content within each modeled period cannot be negative | ||||||||||||||||||||||||||||||||||||||||
@constraint(EP, cSoCLongDurationStorageMinInt_H[y in STOR_HYDRO_LONG_DURATION, r in MODELED_PERIODS_INDEX], | ||||||||||||||||||||||||||||||||||||||||
vSOC_HYDROw[y,r]-(1/efficiency_down(gen[y])*EP[:vP][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||||||||||||||||
-EP[:vSPILL][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1] | ||||||||||||||||||||||||||||||||||||||||
+inputs["pP_Max"][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]*EP[:eTotalCap][y] | ||||||||||||||||||||||||||||||||||||||||
+vdSOC_maxPos_HYDRO[y,dfPeriodMap[r,:Rep_Period_Index]] >= 0) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
end |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -66,9 +66,7 @@ Allows to set the attribute `sym` of an `AbstractResource` object using dot synt | |||||||
- `value`: The value to set for the attribute. | ||||||||
|
||||||||
""" | ||||||||
Base.setproperty!(r::AbstractResource, sym::Symbol, value) = setindex!(parent(r), | ||||||||
value, | ||||||||
sym) | ||||||||
Base.setproperty!(r::AbstractResource, sym::Symbol, value) = setindex!(parent(r), value, sym) | ||||||||
|
||||||||
""" | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||
haskey(r::AbstractResource, sym::Symbol) | ||||||||
|
@@ -106,32 +104,31 @@ end | |||||||
""" | ||||||||
Base.getproperty(rs::Vector{<:AbstractResource}, sym::Symbol) | ||||||||
|
||||||||
Allows to access attributes of a vector of `AbstractResource` objects using dot syntax. If the `sym` is an element of the `resource_types` constant, it returns all resources of that type. Otherwise, it returns the value of the attribute for each resource in the vector. | ||||||||
Allows to return all resources of a given type of a vector of `AbstractResource` objects using dot syntax. | ||||||||
|
||||||||
# Arguments: | ||||||||
- `rs::Vector{<:AbstractResource}`: The vector of `AbstractResource` objects. | ||||||||
- `sym::Symbol`: The symbol representing the attribute name or a type from `resource_types`. | ||||||||
- `sym::Symbol`: The symbol representing the type from `resource_types`. | ||||||||
|
||||||||
# Returns: | ||||||||
- If `sym` is an element of the `resource_types` constant, it returns a vector containing all resources of that type. | ||||||||
- If `sym` is an attribute name, it returns a vector containing the value of the attribute for each resource. | ||||||||
|
||||||||
## Examples | ||||||||
```julia | ||||||||
julia> vre_gen = gen.Vre; # gen vector of resources | ||||||||
julia> typeof(vre_gen) | ||||||||
Vector{Vre} (alias for Array{Vre, 1}) | ||||||||
julia> vre_gen.zone | ||||||||
julia> GenX.zone_id.(vre_gen) | ||||||||
``` | ||||||||
""" | ||||||||
function Base.getproperty(rs::Vector{<:AbstractResource}, sym::Symbol) | ||||||||
# if sym is Type then return a vector resources of that type | ||||||||
# if sym is one of the resource types then return a vector resources of that type | ||||||||
if sym ∈ resource_types | ||||||||
res_type = eval(sym) | ||||||||
return Vector{res_type}(rs[isa.(rs, res_type)]) | ||||||||
else | ||||||||
return getfield(rs, sym) | ||||||||
end | ||||||||
# if sym is a field of the resource then return that field for all resources | ||||||||
return [getproperty(r, sym) for r in rs] | ||||||||
end | ||||||||
|
||||||||
""" | ||||||||
|
@@ -255,8 +252,7 @@ julia> findall(r -> max_cap_mwh(r) != 0, gen.Storage) | |||||||
50 | ||||||||
``` | ||||||||
""" | ||||||||
Base.findall(f::Function, rs::Vector{<:AbstractResource}) = resource_id.(filter(r -> f(r), | ||||||||
rs)) | ||||||||
Base.findall(f::Function, rs::Vector{<:AbstractResource}) = resource_id.(filter(r -> f(r), rs)) | ||||||||
|
||||||||
""" | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||
interface(name, default=default_zero, type=AbstractResource) | ||||||||
|
@@ -531,14 +527,14 @@ const default_zero = 0 | |||||||
|
||||||||
# INTERFACE FOR ALL RESOURCES | ||||||||
resource_name(r::AbstractResource) = r.resource | ||||||||
resource_name(rs::Vector{T}) where {T <: AbstractResource} = rs.resource | ||||||||
resource_name(rs::Vector{T}) where {T <: AbstractResource} = resource_name.(rs) | ||||||||
|
||||||||
resource_id(r::AbstractResource)::Int64 = r.id | ||||||||
resource_id(rs::Vector{T}) where {T <: AbstractResource} = resource_id.(rs) | ||||||||
resource_type_mga(r::AbstractResource) = r.resource_type | ||||||||
|
||||||||
zone_id(r::AbstractResource) = r.zone | ||||||||
zone_id(rs::Vector{T}) where {T <: AbstractResource} = rs.zone | ||||||||
zone_id(rs::Vector{T}) where {T <: AbstractResource} = zone_id.(rs) | ||||||||
|
||||||||
# getter for boolean attributes (true or false) with validation | ||||||||
function new_build(r::AbstractResource) | ||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -55,7 +55,44 @@ If the capacity reserve margin constraint is enabled, a similar set of constrain | |||||||||||||||||||||||||
& \frac{1}{\eta_{o,z}^{discharge}}\Theta^{CRM}_{o,z,(m-1)\times \tau^{period}+1} - \eta_{o,z}^{charge}\Pi^{CRM}_{o,z,(m-1)\times \tau^{period}+1} \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M} | ||||||||||||||||||||||||||
\end{aligned} | ||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||
All other constraints are identical to those used to track the actual state of charge, except with the new variables $Q^{CRM}_{o,z,n}$ and $\Delta Q^{CRM}_{o,z,n}$ used in place of $Q_{o,z,n}$ and $\Delta Q_{o,z,n}$, respectively. | ||||||||||||||||||||||||||
All other constraints are identical to those used to track the actual state of charge, except with the new variables $Q^{CRM}_{o,z,n}$ and $\Delta Q^{CRM}_{o,z,n}$ used in place of $Q_{o,z,n}$ and $\Delta Q_{o,z,n}$, respectively. \ | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
**Bound storage inventory in non-representative periods** | ||||||||||||||||||||||||||
We need additional variables and constraints to ensure that the storage content is within zero and the installed energy capacity in non-representative periods. We introduce | ||||||||||||||||||||||||||
the variables $\Delta Q^{max,pos}_{o,z,m}$ and $\Delta Q^{max,neg}_{o,z,m}$ that represent the maximum positive and negative storage content variations within the representative | ||||||||||||||||||||||||||
period $m$, respectively, extracted as: | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||
& \Delta Q^{max,pos}_{o,z,m} \geq \Gamma_{o,z,(m-1)\times \tau^{period}+t } - \Gamma_{o,z,(m-1)\times \tau^{period}+1 } \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}, t \in \mathcal{T} | ||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||
& \Delta Q^{max,neg}_{o,z,m} \leq \Gamma_{o,z,(m-1)\times \tau^{period}+t } - \Gamma_{o,z,(m-1)\times \tau^{period}+1 } \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}, t \in \mathcal{T} | ||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
For every input period $n \in \mathcal{N}$, the maximum storage is computed and constrained to be less than or equal to the installed energy capacity as: | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||
& Q_{o,z,n} \times \left(1-\eta_{o,z}^{loss}\right) - \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} + \Delta Q^{max,pos}_{o,z,f(n)} \leq \Delta^{total, energy}_{o,z} \\ | ||||||||||||||||||||||||||
& \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, n \in \mathcal{N} | ||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Similarly, the minimum storage content is imposed to be positive in every period of the time horizon: | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
```math | ||||||||||||||||||||||||||
\begin{aligned} | ||||||||||||||||||||||||||
& Q_{o,z,n} \times \left(1-\eta_{o,z}^{loss}\right) - \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} + \Delta Q^{max,neg}_{o,z,f(n)} \geq 0 \\ | ||||||||||||||||||||||||||
& \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, n \in \mathcal{N} | ||||||||||||||||||||||||||
& \end{aligned} | ||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Additional details on this approach are available in [Parolin et al., 2024](https://doi.org/10.48550/arXiv.2409.19079). | ||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||
function long_duration_storage!(EP::Model, inputs::Dict, setup::Dict) | ||||||||||||||||||||||||||
println("Long Duration Storage Module") | ||||||||||||||||||||||||||
|
@@ -96,6 +133,12 @@ function long_duration_storage!(EP::Model, inputs::Dict, setup::Dict) | |||||||||||||||||||||||||
@variable(EP, vCAPRES_dsoc[y in STOR_LONG_DURATION, w = 1:REP_PERIOD]) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Maximum positive storage inventory change within subperiod | ||||||||||||||||||||||||||
@variable(EP, vdSOC_maxPos[y in STOR_LONG_DURATION, w=1:REP_PERIOD] >= 0) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Maximum negative storage inventory change within subperiod | ||||||||||||||||||||||||||
@variable(EP, vdSOC_maxNeg[y in STOR_LONG_DURATION, w=1:REP_PERIOD] <= 0) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
### Constraints ### | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Links last time step with first time step, ensuring position in hour 1 is within eligible change from final hour position | ||||||||||||||||||||||||||
|
@@ -181,4 +224,24 @@ function long_duration_storage!(EP::Model, inputs::Dict, setup::Dict) | |||||||||||||||||||||||||
r in MODELED_PERIODS_INDEX], | ||||||||||||||||||||||||||
vSOCw[y, r]>=vCAPRES_socw[y, r]) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Extract maximum storage level variation (positive) within subperiod | ||||||||||||||||||||||||||
@constraint(EP, cMaxSoCVarPos[y in STOR_LONG_DURATION, w=1:REP_PERIOD, t=2:hours_per_subperiod], | ||||||||||||||||||||||||||
vdSOC_maxPos[y,w] >= EP[:vS][y,hours_per_subperiod*(w-1)+t] - EP[:vS][y,hours_per_subperiod*(w-1)+1]) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Extract maximum storage level variation (negative) within subperiod | ||||||||||||||||||||||||||
@constraint(EP, cMaxSoCVarNeg[y in STOR_LONG_DURATION, w=1:REP_PERIOD, t=2:hours_per_subperiod], | ||||||||||||||||||||||||||
vdSOC_maxNeg[y,w] <= EP[:vS][y,hours_per_subperiod*(w-1)+t] - EP[:vS][y,hours_per_subperiod*(w-1)+1]) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Max storage content within each modeled period cannot exceed installed energy capacity | ||||||||||||||||||||||||||
@constraint(EP, cSoCLongDurationStorageMaxInt[y in STOR_LONG_DURATION, r in MODELED_PERIODS_INDEX], | ||||||||||||||||||||||||||
(1-self_discharge(gen[y]))*vSOCw[y,r]-(1/efficiency_down(gen[y])*EP[:vP][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||
+(efficiency_up(gen[y])*EP[:vCHARGE][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||
+vdSOC_maxPos[y,dfPeriodMap[r,:Rep_Period_Index]] <= EP[:eTotalCapEnergy][y]) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Min storage content within each modeled period cannot be negative | ||||||||||||||||||||||||||
@constraint(EP, cSoCLongDurationStorageMinInt[y in STOR_LONG_DURATION, r in MODELED_PERIODS_INDEX], | ||||||||||||||||||||||||||
(1-self_discharge(gen[y]))*vSOCw[y,r]-(1/efficiency_down(gen[y])*EP[:vP][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||
+(efficiency_up(gen[y])*EP[:vCHARGE][y,hours_per_subperiod*(dfPeriodMap[r,:Rep_Period_Index]-1)+1]) | ||||||||||||||||||||||||||
+vdSOC_maxNeg[y,dfPeriodMap[r,:Rep_Period_Index]] >= 0) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [JuliaFormatter] reported by reviewdog 🐶
Suggested change
|
||||||||||||||||||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[JuliaFormatter] reported by reviewdog 🐶