-
Notifications
You must be signed in to change notification settings - Fork 122
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
Update transmission.jl to account for asymmetrical directional flow l… #769
Conversation
…imits This PR attempts to implement asymmetrical flow limits depending on direction on power flow on transmission lines, so that unidirectional line flows on HVDC lines can be modeled.
@@ -66,6 +91,25 @@ function load_network_data!(setup::Dict, path::AbstractString, inputs_nw::Dict) | |||
inputs_nw["pMax_Line_Reinforcement"] = map(x -> max(0, x), | |||
to_floats(:Line_Max_Reinforcement_MW)) / scale_factor # convert to GW | |||
inputs_nw["pTrans_Max_Possible"] += inputs_nw["pMax_Line_Reinforcement"] | |||
if setup["asymmetrical_trans_flow_limit"] == 1 | |||
# Read between zone network reinforcement costs per peak MW of capacity added |
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 🐶
# Read between zone network reinforcement costs per peak MW of capacity added | |
# Read between zone network reinforcement costs per peak MW of capacity added |
if setup["asymmetrical_trans_flow_limit"] == 1 | ||
# Read between zone network reinforcement costs per peak MW of capacity added | ||
inputs_nw["pC_Line_Reinforcement_Pos"] = to_floats(:Line_Reinforcement_Cost_per_MWyr_Pos) / | ||
scale_factor # convert to million $/GW/yr with objective function in millions |
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 🐶
scale_factor # convert to million $/GW/yr with objective function in millions | |
scale_factor # convert to million $/GW/yr with objective function in millions |
to_floats(:Line_Max_Reinforcement_MW_Pos)) / scale_factor # convert to GW | ||
inputs_nw["pTrans_Max_Possible_Pos"] += inputs_nw["pMax_Line_Reinforcement_Pos"] | ||
|
||
# Read between zone network reinforcement costs per peak MW of capacity added |
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 🐶
# Read between zone network reinforcement costs per peak MW of capacity added | |
# Read between zone network reinforcement costs per peak MW of capacity added |
|
||
# Read between zone network reinforcement costs per peak MW of capacity added | ||
inputs_nw["pC_Line_Reinforcement_Neg"] = to_floats(:Line_Reinforcement_Cost_per_MWyr_Neg) / | ||
scale_factor # convert to million $/GW/yr with objective function in millions |
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 🐶
scale_factor # convert to million $/GW/yr with objective function in millions | |
scale_factor # convert to million $/GW/yr with objective function in millions |
@@ -79,12 +123,23 @@ | |||
# Max Flow Possible on Each Line | |||
inputs_nw["pLine_Max_Flow_Possible_MW"] = to_floats(:Line_Max_Flow_Possible_MW) / | |||
scale_factor # Convert to GW | |||
if setup["asymmetrical_trans_flow_limit"] == 1 | |||
inputs_nw["pLine_Max_Flow_Possible_MW_Pos"] = to_floats(:Line_Max_Flow_Possible_MW_Pos) / | |||
scale_factor # Convert to GW |
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 🐶
scale_factor # Convert to GW | |
scale_factor # Convert to GW |
for l in EXPANSION_LINES)+sum(vNEW_TRANS_CAP_Pos[l] * inputs["pC_Line_Reinforcement_Pos"][l] | ||
for l in EXPANSION_LINES_ASYM)+sum(vNEW_TRANS_CAP_Neg[l] * inputs["pC_Line_Reinforcement_Neg"][l] |
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 🐶
for l in EXPANSION_LINES)+sum(vNEW_TRANS_CAP_Pos[l] * inputs["pC_Line_Reinforcement_Pos"][l] | |
for l in EXPANSION_LINES_ASYM)+sum(vNEW_TRANS_CAP_Neg[l] * inputs["pC_Line_Reinforcement_Neg"][l] | |
for l in EXPANSION_LINES) + | |
sum(vNEW_TRANS_CAP_Pos[l] * inputs["pC_Line_Reinforcement_Pos"][l] | |
for l in EXPANSION_LINES_ASYM) + | |
sum(vNEW_TRANS_CAP_Neg[l] * inputs["pC_Line_Reinforcement_Neg"][l] |
@constraint(EP, cExistingTransCapPos[l = 1:L_asym], vTRANSMAX_Pos[l]==inputs["pTrans_Max_Pos"][l]) | ||
@constraint(EP, cExistingTransCapNeg[l = 1:L_asym], vTRANSMAX_Neg[l]==inputs["pTrans_Max_Neg"][l]) |
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 🐶
@constraint(EP, cExistingTransCapPos[l = 1:L_asym], vTRANSMAX_Pos[l]==inputs["pTrans_Max_Pos"][l]) | |
@constraint(EP, cExistingTransCapNeg[l = 1:L_asym], vTRANSMAX_Neg[l]==inputs["pTrans_Max_Neg"][l]) | |
@constraint(EP, cExistingTransCapPos[l = 1:L_asym], | |
vTRANSMAX_Pos[l]==inputs["pTrans_Max_Pos"][l]) | |
@constraint(EP, cExistingTransCapNeg[l = 1:L_asym], | |
vTRANSMAX_Neg[l]==inputs["pTrans_Max_Neg"][l]) |
if setup["asymmetrical_trans_flow_limit"] == 1 | ||
@constraint(EP, | ||
cMaxFlowPossible_Pos[l in EXPANSION_LINES_ASYM], | ||
eAvail_Trans_Cap_Pos[l]<=inputs["pTrans_Max_Possible_Pos"][l]) | ||
@constraint(EP, | ||
cMaxFlowPossible_Neg[l in EXPANSION_LINES_ASYM], | ||
eAvail_Trans_Cap_Neg[l]<=inputs["pTrans_Max_Possible_Neg"][l]) | ||
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 🐶
if setup["asymmetrical_trans_flow_limit"] == 1 | |
@constraint(EP, | |
cMaxFlowPossible_Pos[l in EXPANSION_LINES_ASYM], | |
eAvail_Trans_Cap_Pos[l]<=inputs["pTrans_Max_Possible_Pos"][l]) | |
@constraint(EP, | |
cMaxFlowPossible_Neg[l in EXPANSION_LINES_ASYM], | |
eAvail_Trans_Cap_Neg[l]<=inputs["pTrans_Max_Possible_Neg"][l]) | |
end | |
if setup["asymmetrical_trans_flow_limit"] == 1 | |
@constraint(EP, | |
cMaxFlowPossible_Pos[l in EXPANSION_LINES_ASYM], | |
eAvail_Trans_Cap_Pos[l]<=inputs["pTrans_Max_Possible_Pos"][l]) | |
@constraint(EP, | |
cMaxFlowPossible_Neg[l in EXPANSION_LINES_ASYM], | |
eAvail_Trans_Cap_Neg[l]<=inputs["pTrans_Max_Possible_Neg"][l]) | |
end |
@constraints(EP, | ||
begin | ||
cMaxFlow_out[l = 1:L, t = 1:T], vFLOW[l, t] <= EP[:eAvail_Trans_Cap][l] | ||
cMaxFlow_in[l = 1:L, t = 1:T], vFLOW[l, t] >= -EP[:eAvail_Trans_Cap][l] | ||
end) | ||
|
||
if setup["asymmetrical_trans_flow_limit"] ==1 |
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 🐶
if setup["asymmetrical_trans_flow_limit"] ==1 | |
if setup["asymmetrical_trans_flow_limit"] == 1 |
cMaxFlow_out[l = 1:L_asym, t = 1:T], vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] #Change these with Auxiliary | ||
cMaxFlow_in[l = 1:L_asym, t = 1:T], vTAUX_NEG[l, t] >= -EP[:eAvail_Trans_Cap_Neg][l] #Change these with Auxiliary |
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 🐶
cMaxFlow_out[l = 1:L_asym, t = 1:T], vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] #Change these with Auxiliary | |
cMaxFlow_in[l = 1:L_asym, t = 1:T], vTAUX_NEG[l, t] >= -EP[:eAvail_Trans_Cap_Neg][l] #Change these with Auxiliary | |
cMaxFlow_out[l = 1:L_asym, t = 1:T], | |
vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] #Change these with Auxiliary | |
cMaxFlow_in[l = 1:L_asym, t = 1:T], | |
vTAUX_NEG[l, t] >= -EP[:eAvail_Trans_Cap_Neg][l] #Change these with Auxiliary |
@sambuddhac this PR also needs to address how piecewise quadratic loss segments are established. We should use the max capacity for each direction to set different segment lengths for each direction of flows. |
Thanks @JesseJenkins . I'll take care of it today. |
# Transmission loss related constraints - linear losses as a function of absolute value | ||
if TRANS_LOSS_SEGS == 1 | ||
@constraints(EP, | ||
## Do I need to model different expressions for linear losses for each direction, like the following? | ||
if setup["asymmetrical_trans_flow_limit"] ==1 |
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 🐶
if setup["asymmetrical_trans_flow_limit"] ==1 | |
if setup["asymmetrical_trans_flow_limit"] == 1 |
begin | ||
# Losses are alpha times absolute values | ||
cTLossPos[l in LOSS_LINES, t = 1:T], | ||
vTLOSSPos[l, t] == | ||
inputs["pPercent_LossPos"][l] * (vTAUX_POS[l, t]) | ||
|
||
# Power flow is sum of positive and negative components | ||
cTAuxSum[l in LOSS_LINES, t = 1:T], | ||
vTAUX_POS[l, t] == vFLOW[l, t] | ||
|
||
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | ||
cTAuxLimitPos[l in LOSS_LINES, t = 1:T], | ||
vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] | ||
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 🐶
begin | |
# Losses are alpha times absolute values | |
cTLossPos[l in LOSS_LINES, t = 1:T], | |
vTLOSSPos[l, t] == | |
inputs["pPercent_LossPos"][l] * (vTAUX_POS[l, t]) | |
# Power flow is sum of positive and negative components | |
cTAuxSum[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] == vFLOW[l, t] | |
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | |
cTAuxLimitPos[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] | |
end) | |
begin | |
# Losses are alpha times absolute values | |
cTLossPos[l in LOSS_LINES, t = 1:T], | |
vTLOSSPos[l, t] == | |
inputs["pPercent_LossPos"][l] * (vTAUX_POS[l, t]) | |
# Power flow is sum of positive and negative components | |
cTAuxSum[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] == vFLOW[l, t] | |
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | |
cTAuxLimitPos[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] <= EP[:eAvail_Trans_Cap_Pos][l] | |
end) |
begin | ||
# Losses are alpha times absolute values | ||
cTLossNeg[l in LOSS_LINES, t = 1:T], | ||
vTLOSSNeg[l, t] == | ||
inputs["pPercent_LossNeg"][l] * (vTAUX_NEG[l, t]) | ||
|
||
# Power flow is sum of positive and negative components | ||
cTAuxSum[l in LOSS_LINES, t = 1:T], | ||
vTAUX_NEG[l, t] == vFLOW[l, t] | ||
|
||
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | ||
cTAuxLimitNeg[l in LOSS_LINES, t = 1:T], | ||
vTAUX_NEG[l, t] <= EP[:eAvail_Trans_Cap_Neg][l] | ||
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 🐶
begin | |
# Losses are alpha times absolute values | |
cTLossNeg[l in LOSS_LINES, t = 1:T], | |
vTLOSSNeg[l, t] == | |
inputs["pPercent_LossNeg"][l] * (vTAUX_NEG[l, t]) | |
# Power flow is sum of positive and negative components | |
cTAuxSum[l in LOSS_LINES, t = 1:T], | |
vTAUX_NEG[l, t] == vFLOW[l, t] | |
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | |
cTAuxLimitNeg[l in LOSS_LINES, t = 1:T], | |
vTAUX_NEG[l, t] <= EP[:eAvail_Trans_Cap_Neg][l] | |
end) | |
begin | |
# Losses are alpha times absolute values | |
cTLossNeg[l in LOSS_LINES, t = 1:T], | |
vTLOSSNeg[l, t] == | |
inputs["pPercent_LossNeg"][l] * (vTAUX_NEG[l, t]) | |
# Power flow is sum of positive and negative components | |
cTAuxSum[l in LOSS_LINES, t = 1:T], | |
vTAUX_NEG[l, t] == vFLOW[l, t] | |
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | |
cTAuxLimitNeg[l in LOSS_LINES, t = 1:T], | |
vTAUX_NEG[l, t] <= EP[:eAvail_Trans_Cap_Neg][l] | |
end) |
vTAUX_NEG[l, t] <= EP[:eAvail_Trans_Cap_Neg][l] | ||
end) | ||
else ## Do I need to model different expressions for linear losses for each direction, like the following? | ||
|
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 🐶
(inputs["pTrans_Loss_Coef"][l] * | ||
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | ||
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) | ||
if setup["asymmetrical_trans_flow_limit"] ==1 |
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 🐶
if setup["asymmetrical_trans_flow_limit"] ==1 | |
if setup["asymmetrical_trans_flow_limit"] == 1 |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | ||
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + |
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 🐶
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + | |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | ||
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) |
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 🐶
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) | |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | ||
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + |
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 🐶
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + | |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_POS[l, s, t] for s in 1:TRANS_LOSS_SEGS)) + |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | ||
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) |
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 🐶
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) | |
sum((2 * s - 1) * (inputs["pTrans_Max_Possible"][l] / TRANS_LOSS_SEGS) * | |
vTAUX_NEG[l, s, t] for s in 1:TRANS_LOSS_SEGS))) |
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 🐶
GenX.jl/src/model/core/transmission/transmission.jl
Lines 226 to 239 in ebc21a1
begin | |
# Losses are alpha times absolute values | |
cTLoss[l in LOSS_LINES, t = 1:T], | |
vTLOSS[l, t] == | |
inputs["pPercent_Loss"][l] * (vTAUX_POS[l, t] + vTAUX_NEG[l, t]) | |
# Power flow is sum of positive and negative components | |
cTAuxSum[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] - vTAUX_NEG[l, t] == vFLOW[l, t] | |
# Sum of auxiliary flow variables in either direction cannot exceed maximum line flow capacity | |
cTAuxLimit[l in LOSS_LINES, t = 1:T], | |
vTAUX_POS[l, t] + vTAUX_NEG[l, t] <= EP[:eAvail_Trans_Cap][l] | |
end) |
@sambuddhac will redraft PR based on conversation about how to limit duplication of code. We will create positive and negative instances of the key input parameters (max flows, max expansion, loss coefficients), use these two versions to constrain the positive and negative flow variables within the constraints in transmission.jl and investment_transmission.jl to avoid duplicated code in if/else blocks for assymetric/symmetric lines. Then when reading and setting up inputs, these two input parameters will be equal to one another if the line is symmetric. Then the code works from there for either type of line and we dont need if/else options within the constraints/expressions. |
PR #789 is the new PR. Please note that I am in the middle of pushing a bunch of updates to that. So, please hang in there for a bit more. Will tag to review and merge once I am done. |
Description
This PR attempts to implement asymmetrical flow limits depending on direction on power flow on transmission lines, so that unidirectional line flows on HVDC lines can be modeled.
What type of PR is this? (check all applicable)
Related Tickets & Documents
Checklist
How this can be tested
Post-approval checklist for GenX core developers
After the PR is approved