Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
193 commits
Select commit Hold shift + click to select a range
97d1ffb
Updated array type
toddleif Apr 22, 2023
b834799
Updates for multinode functionality
toddleif Apr 25, 2023
0212e6c
Updates To Multinode Code
toddleif Aug 29, 2023
0bca9cf
Enabled electric storage to grid export
toddleif Sep 1, 2023
39e41a9
Electric Storage Updates
toddleif Sep 16, 2023
58f1509
Temporary fix to apply some battery constraints
toddleif Sep 25, 2023
d4ac66f
Updates to storage to grid
toddleif Oct 30, 2023
41274c5
Added analysis functions
toddleif May 29, 2024
a81784c
Changed the JuMP model to be a user input, and other minor edits
toddleif May 30, 2024
81a8ef7
Merge branch 'develop' into Multinode-Updates
toddleif Jun 8, 2024
6e0b574
Added a print statement
toddleif Jul 3, 2024
4fa7b37
Added ability for a node to act as a facility level utility meter. Ad…
toddleif Jul 7, 2024
4b2b32a
Added grid export from the facility meter node. Updates to plotting o…
toddleif Jul 9, 2024
cf36d82
Changed the location of the code for displaying results. Additional s…
toddleif Jul 11, 2024
ca0e5b7
Added function to check the input data, added function for computing …
toddleif Jul 13, 2024
792b5ff
Converted a variable to a string when generating a results dataframe
toddleif Jul 13, 2024
2714331
Fixed errors in the code in order to model generators as well
toddleif Jul 13, 2024
5ca4cff
Added ability to define critical loads and made improvements to the g…
toddleif Jul 14, 2024
6642f25
Fixing errors in the code for critical load fractions
toddleif Jul 18, 2024
ca6df41
Added additional line power flow data to the line power flow summary
toddleif Jul 21, 2024
ba64fad
Addition of power flow code
toddleif Aug 8, 2024
69da199
Modifications to enable the power flow code to work
toddleif Aug 9, 2024
533b99d
Update to the method for reading the lines file, and other minor upda…
toddleif Aug 15, 2024
9ae527d
Added ability to model switches, and made changes to the transformer …
toddleif Aug 16, 2024
5491718
Initial implementation of line and transformer upgrades
toddleif Aug 24, 2024
61bb9cb
Fixed errors in transformer upgrade code, added upgrades to the model…
toddleif Aug 25, 2024
5b66039
Updating the outage simulator and additional changes
toddleif Aug 25, 2024
0134314
Updates for modeling line upgrades and additional improvements
toddleif Aug 26, 2024
3f88072
Corrected a variable name
toddleif Aug 26, 2024
9904232
Corrected an error in the code for line upgrades
toddleif Aug 26, 2024
14100fe
Debugging battery code and results export code, and removing some code
toddleif Sep 14, 2024
91e6ef4
Added new method for importing microgrid inputs and improved the plot…
toddleif Sep 22, 2024
290cd02
Added new plotting capability, removed power flow post-processor, and…
toddleif Oct 16, 2024
aa47b0d
Preliminary integration with an additional power flow model
toddleif Oct 21, 2024
17f3abd
Combined the extend.jl and power_flow.jl files
toddleif Oct 22, 2024
e52207d
Incorporated linkage to a new power flow model
toddleif Oct 22, 2024
fb8358b
Debugging code for integration with new power flow model
toddleif Oct 22, 2024
ca2cbc1
Updated the power flow modeling approach
toddleif Dec 9, 2024
3ab4bf3
Improvements to the code for integration with the power flow model
toddleif Dec 9, 2024
9eeea27
Updates to outage simulator and other smaller updates
toddleif Dec 11, 2024
a4e7281
Updates to plotting code and adding the basic linear model code to a …
toddleif Dec 15, 2024
42dcdc3
Added a reference to the new basic_linear_model_microgrid file to the…
toddleif Dec 15, 2024
dcdcbf6
Adding new plotting functionality and correcting a code error
toddleif Dec 16, 2024
0208c58
Updates to plotting of the results
toddleif Dec 16, 2024
9de7379
Updates to plotting of the results
toddleif Dec 16, 2024
2430a7a
Minor code updates
toddleif Dec 29, 2024
2e68a01
Reorganization of code and minor updates
toddleif Dec 30, 2024
37b83aa
Added the ability to have generators only operate during grid outages…
toddleif Dec 31, 2024
df0e9d9
Added option to run a business as usual case. Added input for a solve…
toddleif Jan 2, 2025
c8a5416
Added additional values to the results output
toddleif Jan 2, 2025
9333d0c
Updates to the modeling of line upgrades
toddleif Jan 12, 2025
46994d7
Fixed an error in the results reporting
toddleif Jan 12, 2025
9ce4908
Corrected an error in the outage simulator plotting and added several…
toddleif Jan 15, 2025
c7f7c5e
Added code to record the run time of the outage simulation
toddleif Jan 16, 2025
0c258f4
Enabled ability to run with additional solvers
toddleif Jan 20, 2025
5fa3a8b
Changed location of two files and added a function for saving and vis…
toddleif Jan 21, 2025
4f254fb
Updates to the microgrid outage simulation
toddleif Jan 21, 2025
429783b
Commented out several plots that are unnecessary
toddleif Jan 21, 2025
246c21f
Minor updates to the code that models switches
toddleif Jan 22, 2025
c532ef8
Added the ability to model multiple outages
toddleif Jan 28, 2025
b5eb01a
Separated code into several files; commented out code for running the…
toddleif Jan 30, 2025
7c10187
Added code to allow the user to prevent generating multiple PV power …
toddleif Feb 1, 2025
288ef2a
Improved the plotting of the voltage results
toddleif Feb 3, 2025
e1f9c7a
Added code to generate a plot that shows the power flow
toddleif Feb 5, 2025
97dc678
Added a legend to the power flow plot
toddleif Feb 6, 2025
65a7355
Added improvements to the power flow plot
toddleif Feb 8, 2025
1b33128
Corrected an error in the code for the power flow plot
toddleif Feb 8, 2025
f26dad5
Applied improvements to the power flow plotting code
toddleif Feb 8, 2025
5f415fd
Updates to the results plots and removal of some code that is comment…
toddleif Feb 9, 2025
1ed55ba
Added voltage results to the results output
toddleif Feb 10, 2025
c1d849d
Reorganized the microgrid outage simulator code
toddleif Feb 11, 2025
8ef331f
Small updates to the code
toddleif Feb 12, 2025
550d136
Merge branch 'develop' into microgrid
toddleif Feb 13, 2025
ba3e6be
Updates to the code for exporting power from the electric storage to …
toddleif Feb 13, 2025
9abafd6
Updated Manifest document
toddleif Feb 13, 2025
079a0cc
Updated the manifest file
toddleif Feb 13, 2025
db21481
Update project file
toddleif Feb 13, 2025
238d89c
Reconfiguring the optimization and debugging
toddleif Feb 14, 2025
674c80f
Debugging
toddleif Feb 14, 2025
1dd5ef3
Debugging
toddleif Feb 15, 2025
51c0231
Added a test for the new code
toddleif Feb 16, 2025
9828db3
Debugging the new test for multinode powerflow
toddleif Feb 16, 2025
34247b4
Debugging
toddleif Feb 16, 2025
752a9c0
Updated multinode powerflow json file
toddleif Feb 16, 2025
9ce6cd8
Debugging test
toddleif Feb 16, 2025
3b9a98a
Debugging test for multinode powerflow
toddleif Feb 16, 2025
9e22362
Debugging
toddleif Feb 16, 2025
8b81123
Removed previous simultaneous electric storage charge and discharge code
toddleif Feb 16, 2025
0272c20
Debugging
toddleif Feb 16, 2025
ae16927
Debugging test
toddleif Feb 17, 2025
305fa69
Debugging the new test
toddleif Feb 17, 2025
d557444
Debugging test, testing again
toddleif Feb 17, 2025
fc733c1
Updates for running the multinode powerflow test
toddleif Feb 17, 2025
a262b78
Added package to the test environment
toddleif Feb 17, 2025
b1ab3d0
Debugging the multinode powerflow test
toddleif Feb 18, 2025
0a7a852
Continued debugging of the multinode powerflow test
toddleif Feb 18, 2025
0529dd5
Additional debugging of the code for the multinode powerflow test
toddleif Feb 18, 2025
3c58786
Additional multinode powerflow test debugging
toddleif Feb 18, 2025
97abb38
Renamed files
toddleif Feb 25, 2025
7d63501
Renamed variable names from microgrid to multinode
toddleif Feb 26, 2025
cb1f9a7
Debugging
toddleif Feb 26, 2025
52b9c5e
Debugging tests
toddleif Feb 26, 2025
218ec6b
Debugging tests
toddleif Feb 26, 2025
ce23335
Debugging tests
toddleif Feb 26, 2025
f2813e6
Debugging tests
toddleif Feb 26, 2025
cc96baf
Debugging tests
toddleif Feb 26, 2025
2f49d76
Debugging tests
toddleif Feb 26, 2025
6f90492
Debugging tests
toddleif Feb 27, 2025
edd08af
Debugging multinode tests
toddleif Feb 27, 2025
1a4828b
Debugging
toddleif Feb 27, 2025
974fe91
Debugging errors in the code
toddleif Feb 28, 2025
aa3633c
Updated code so line upgrades transfer to the outage simulator. Also …
toddleif Mar 1, 2025
ee5b512
Improvements to the power flow plot. And debugging.
toddleif Mar 1, 2025
2a240fe
Added model subtype
toddleif Mar 18, 2025
f966f7b
Added additional model subtype options
toddleif Mar 18, 2025
2997e3e
Corrected error in model subtypes
toddleif Mar 18, 2025
99a6c82
Updated formatting
toddleif Mar 18, 2025
7942232
Updates for the new model subtype
toddleif Mar 18, 2025
ce0c0e3
Fixed bug
toddleif Mar 18, 2025
3ef4be0
Bug fix
toddleif Mar 18, 2025
e003a29
Fixed bug in results processing for other model subtype
toddleif Mar 18, 2025
b0c7aaf
Fixing bug in results processing
toddleif Mar 18, 2025
56feffd
Bug fixing results processing
toddleif Mar 18, 2025
e853f09
Modeling dropped load in the outage simulator
toddleif Mar 21, 2025
9010422
Added three phase capability to REopt nodes for interfacing with the …
toddleif Mar 30, 2025
1a8c9e3
Added feature to allow bus voltage violations
toddleif Mar 30, 2025
ab08eab
Debugging code for multiphase analyses
toddleif Mar 31, 2025
18eda9d
Added code so only voltage results for single phase systems are shown
toddleif Mar 31, 2025
4fd336d
Debugging
toddleif Apr 3, 2025
0c045a0
Making the results variable smaller
toddleif Apr 3, 2025
1475618
Debugging
toddleif Apr 9, 2025
4aa20d5
Added additional reporting on computation times
toddleif Apr 14, 2025
e73b38b
Debugging connection between REopt nodes and power flow
toddleif Apr 14, 2025
673f1ac
Added additional data compilation of the power flows on the lines
toddleif Apr 14, 2025
161d921
Draft code for including reactive power. Deleted unnecessary code.
toddleif Apr 14, 2025
ad0d0f1
Debugging
toddleif Apr 14, 2025
aa67028
Added simplified powerflow constraints to time steps not modeled with…
toddleif May 23, 2025
d33e498
Only display plots if display_results is set to true
toddleif May 23, 2025
3eb1c03
Debugging
toddleif May 23, 2025
be81704
Removed function call for function that doesn't exist anymore
toddleif May 23, 2025
9a6d9dd
Added capability to post-process the simple powerflow model results
toddleif May 23, 2025
495e5ad
Added warning if base_voltage_kv is not defined by the user. Added so…
toddleif May 24, 2025
af47d7a
Usability improvements
toddleif May 27, 2025
a657ef8
Improvements to the simple powerflow model and other small improvements.
toddleif May 28, 2025
e94ac8c
Updates to results processing
toddleif May 30, 2025
11bcdbf
Added additional data checks before the model is run
toddleif May 30, 2025
b98c132
Updated powerflow plot to show date and time
toddleif May 30, 2025
3c1212f
Usability improvements
toddleif Jun 4, 2025
30f2a57
Usability updates
toddleif Jun 4, 2025
cb5768c
Removed plotting from code and added dictionary output with model res…
toddleif Sep 27, 2025
23b3138
Updated associated packages
toddleif Sep 29, 2025
902ff8b
Update to the associated packages
toddleif Sep 30, 2025
863afff
Allowed for small reactive power support from grid during power outag…
toddleif Oct 8, 2025
91f1435
Updates for multi-phase systems
toddleif Oct 8, 2025
7a70f33
Preliminary implementation of three phase for the simple powerflow model
toddleif Oct 9, 2025
55b08dc
Updates to multiphase modeling
toddleif Oct 10, 2025
a625369
Added input to define the maximum reactive power support
toddleif Oct 13, 2025
40f978a
Debugging
toddleif Oct 13, 2025
9c26f42
Added a label for indicating a to do task
toddleif Oct 14, 2025
cb2bd39
Made the code compatible with an additional power model formulation
toddleif Oct 14, 2025
0a644ee
Removed unnecessary code
toddleif Oct 14, 2025
7e9cfb5
Debugging and simplification of code
toddleif Oct 14, 2025
68cfe16
Debugging processing single phase results
toddleif Oct 15, 2025
7e0b697
Improving the printing of model information
toddleif Oct 15, 2025
8f7ccd8
Updates to plotting labels
toddleif Oct 15, 2025
7cbdeef
Corrected the simple powerflow model for distributing loads across mu…
toddleif Oct 16, 2025
43ca7f9
Corrected an error message
toddleif Oct 16, 2025
b8ae885
Added code to prepare the network file for multinode
toddleif Dec 13, 2025
640a34c
Updates for increased compatibility with network input files
toddleif Dec 15, 2025
02f49b8
Updates to multinode_utils
toddleif Dec 16, 2025
baf8096
Debugging and adding new features to modify the network input file
toddleif Dec 19, 2025
23e67cf
Debugging the simplified power flow model
toddleif Dec 19, 2025
e30eb12
Debugging
toddleif Dec 19, 2025
852cccb
Updating code to work with non-integer node names
toddleif Dec 21, 2025
989a5e1
Debugging
toddleif Dec 21, 2025
034ac02
Debugging
toddleif Dec 22, 2025
ef64bef
Debugging processing of results
toddleif Dec 23, 2025
eabcf56
Debugging the outage simulator code
toddleif Dec 24, 2025
cb18ee1
Miscellaneous improvements
toddleif Dec 30, 2025
5bec8a9
Update to the data checks
toddleif Dec 30, 2025
90281c1
Update multinode.jl
toddleif Dec 31, 2025
bdcadb8
Made filename lowercase
toddleif Dec 31, 2025
dc58a96
Formatting updates and added a note to the code
toddleif Mar 31, 2026
8512c42
Added the ability to run just a PowerModelsDistribution model with th…
toddleif May 16, 2026
4b9b21c
Added some code to correct issues with data inputs for the network
toddleif May 17, 2026
cbfcf3e
Deleted non-necessary line of code
toddleif May 19, 2026
875d1ae
Added checks for loops and islanded busses in the system network
toddleif May 19, 2026
1899ad6
Updates to the loop detection code
toddleif May 19, 2026
4b3a7aa
Updates to the loops and island detection functions
toddleif May 22, 2026
ccf6436
Variety of usability updates
toddleif May 27, 2026
af28159
Some debugging code and created a run_diagnostics function
toddleif Jun 2, 2026
628f4eb
updated the solar API call
toddleif Jun 4, 2026
bfb2328
updates for the nlr name
toddleif Jun 4, 2026
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
956 changes: 707 additions & 249 deletions Manifest.toml

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,35 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
JLD = "4138dd39-2aa7-5051-a626-17a0bb65d9c8"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinDistFlow = "bf674bac-ffe4-48d3-9f32-72124ffa9ede"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
TestEnv = "1e6cf692-eddd-4d53-88a5-2d735e33781b"

[compat]
ArchGDAL = "0.8, 0.9"
CoolProp = "0.1"
CSV = "0.10"
CoolProp = "0.1"
DataFrames = "1.4"
Dates = "1"
DelimitedFiles = "1"
HTTP = "0.8, 0.9, 1"
JLD = "0.13"
JSON = "0.21"
JuMP = "0.21, 0.22, 0.23, 1"
LinDistFlow = "0.1, 0.2"
LinearAlgebra = "1"
Logging = "1"
MathOptInterface = "0.9, 0.10, 1"
Requires = "1.3"
Roots = "1.3, 2"
TestEnv = "1.7, 1.8, 1.9"
Dates = "1"
DelimitedFiles = "1"
LinearAlgebra = "1"
Logging = "1"
Statistics = "1"
TestEnv = "1.7, 1.8, 1.9"
julia = "1.4, 1.5, 1.6, 1.7, 1.8"
17 changes: 11 additions & 6 deletions src/REopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export
simulate_outages,
add_variables!,
add_objective!,
LinDistFlow,
MPCScenario,
MPCInputs,
run_mpc,
Expand All @@ -30,9 +29,6 @@ export

import HTTP
import JSON
using LinDistFlow # required to export LinDistFlow
import LinDistFlow
const LDF = LinDistFlow
using JuMP
using JuMP.Containers: DenseAxisArray
using Logging
Expand All @@ -52,9 +48,14 @@ using CoolProp
using LinearAlgebra
using CSV
using DataFrames
using Plots
import Plots
using HiGHS

function __init__()
@require GhpGhx="7ce85f02-24a8-4d69-a3f0-14b5daa7d30c" println("using GhpGhx module in REopt")
@require PowerModelsDistribution="d7431456-977f-11e9-2de3-97ff7677985e" println("using the PowerModelsDistribution package") # This will load whichever feature branch you have installed in the coding environment
@require Xpress="9e70acf3-d6c9-5be6-b5bd-4e2c73e3e054" println("using the Xpress package")
end

const EXISTING_BOILER_EFFICIENCY = 0.8
Expand Down Expand Up @@ -195,11 +196,15 @@ include("results/electric_heater.jl")
include("results/ashp.jl")

include("core/reopt.jl")
include("core/reopt_multinode.jl")
include("outagesim/outage_simulator.jl")
include("outagesim/backup_reliability.jl")

include("lindistflow/extend.jl")
include("multinode/reopt_multinode.jl")
include("multinode/multinode.jl")
include("multinode/multinode_outage_simulator.jl")
include("multinode/multinode_results_processing.jl")
include("multinode/multinode_inputs.jl")
include("multinode/multinode_utils.jl")

include("mpc/results.jl")
include("mpc/model.jl")
Expand Down
45 changes: 31 additions & 14 deletions src/constraints/electric_utility_constraints.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# REopt®, Copyright (c) Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/REopt.jl/blob/master/LICENSE.
function add_export_constraints(m, p; _n="")

##Constraint (8e): Production export and curtailment no greater than production
@constraint(m, [t in p.techs.elec, ts in p.time_steps_with_grid],
p.production_factor[t,ts] * p.levelization_factor[t] * m[Symbol("dvRatedProduction"*_n)][t,ts]
>= sum(m[Symbol("dvProductionToGrid"*_n)][t, u, ts] for u in p.export_bins_by_tech[t]) +
m[Symbol("dvCurtail"*_n)][t, ts]
)
if (_n == "") || (p.s.settings.facilitymeter_node != "")
@constraint(m, [t in p.techs.elec, ts in p.time_steps_with_grid],
p.production_factor[t,ts] * p.levelization_factor[t] * m[Symbol("dvRatedProduction"*_n)][t,ts]
>= sum(m[Symbol("dvProductionToGrid"*_n)][t, u, ts] for u in p.export_bins_by_tech[t]) +
m[Symbol("dvCurtail"*_n)][t, ts]
)
else
# Don't add constraint 8e to the facility meter node
@constraint(m, [t in p.techs.elec, ts in p.time_steps_with_grid], m[Symbol("dvRatedProduction"*_n)][t,ts] == 0)
@constraint(m, [t in p.techs.elec, ts in p.time_steps_with_grid], m[Symbol("dvCurtail"*_n)][t, ts] == 0)
end

binNEM = 0
binWHL = 0
Expand All @@ -19,12 +24,16 @@ function add_export_constraints(m, p; _n="")
if !isempty(NEM_techs)
# Constraint (9c): Net metering only -- can't sell more than you purchase
# hours_per_time_step is cancelled on both sides, but used for unit consistency (convert power to energy)
@constraint(m,
p.hours_per_time_step * sum( m[Symbol("dvProductionToGrid"*_n)][t, :NEM, ts]
for t in NEM_techs, ts in p.time_steps)
<= p.hours_per_time_step * sum( m[Symbol("dvGridPurchase"*_n)][ts, tier]
for ts in p.time_steps, tier in 1:p.s.electric_tariff.n_energy_tiers)
)
if (_n == "") || (p.s.settings.facilitymeter_node != "")
@constraint(m,
p.hours_per_time_step * sum( m[Symbol("dvProductionToGrid"*_n)][t, :NEM, ts]
for t in NEM_techs, ts in p.time_steps)
<= p.hours_per_time_step * sum( m[Symbol("dvGridPurchase"*_n)][ts, tier]
for ts in p.time_steps, tier in 1:p.s.electric_tariff.n_energy_tiers)
)
else
# Don't add constraint 9c to the facility meter node
end

if p.s.electric_utility.net_metering_limit_kw == p.s.electric_utility.interconnection_limit_kw && isempty(WHL_techs)
# no need for binNEM nor binWHL
Expand Down Expand Up @@ -134,9 +143,17 @@ function add_export_constraints(m, p; _n="")

if typeof(binNEM) <: Real # no need for wholesale binary
binWHL = 1
for b in p.s.storage.types.all
println(b)
end
WHL_benefit = @expression(m, p.pwf_e * p.hours_per_time_step *
sum( sum(p.s.electric_tariff.export_rates[:WHL][ts] * m[Symbol("dvProductionToGrid"*_n)][t, :WHL, ts]
for t in p.techs_by_exportbin[:WHL]) for ts in p.time_steps)
(
sum(sum(p.s.electric_tariff.export_rates[:WHL][ts] * m[Symbol("dvStorageToGrid"*_n)][b, ts]
for b in p.s.storage.types.elec) for ts in p.time_steps) +

sum(sum(p.s.electric_tariff.export_rates[:WHL][ts] * m[Symbol("dvProductionToGrid"*_n)][t, :WHL, ts]
for t in p.techs_by_exportbin[:WHL]) for ts in p.time_steps)
)
)
else
binWHL = @variable(m, binary = true)
Expand Down
82 changes: 55 additions & 27 deletions src/constraints/generator_constraints.jl
Original file line number Diff line number Diff line change
@@ -1,60 +1,88 @@
# REopt®, Copyright (c) Alliance for Sustainable Energy, LLC. See also https://github.com/NREL/REopt.jl/blob/master/LICENSE.
function add_fuel_burn_constraints(m,p)
# *********************************************************************************
# REopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list
# of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# *********************************************************************************
function add_fuel_burn_constraints(m,p; _n="")
fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr = fuel_slope_and_intercept(
electric_efficiency_full_load=p.s.generator.electric_efficiency_full_load,
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load,
fuel_higher_heating_value_kwh_per_unit=p.s.generator.fuel_higher_heating_value_kwh_per_gal
)
@constraint(m, [t in p.techs.gen, ts in p.time_steps],
m[:dvFuelUsage][t, ts] == (fuel_slope_gal_per_kwhe * p.s.generator.fuel_higher_heating_value_kwh_per_gal *
p.production_factor[t, ts] * p.hours_per_time_step * m[:dvRatedProduction][t, ts]) +
(fuel_intercept_gal_per_hr * p.s.generator.fuel_higher_heating_value_kwh_per_gal * p.hours_per_time_step * m[:binGenIsOnInTS][t, ts])
m[Symbol("dvFuelUsage"*_n)][t, ts] == (fuel_slope_gal_per_kwhe * p.s.generator.fuel_higher_heating_value_kwh_per_gal *
p.production_factor[t, ts] * p.hours_per_time_step * m[Symbol("dvRatedProduction"*_n)][t, ts]) +
(fuel_intercept_gal_per_hr * p.s.generator.fuel_higher_heating_value_kwh_per_gal * p.hours_per_time_step * m[Symbol("binGenIsOnInTS"*_n)][t, ts])
)
@constraint(m,
sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) <=
sum(m[Symbol("dvFuelUsage"*_n)][t, ts] for t in p.techs.gen, ts in p.time_steps) <=
p.s.generator.fuel_avail_gal * p.s.generator.fuel_higher_heating_value_kwh_per_gal
)
end


function add_binGenIsOnInTS_constraints(m,p)
function add_binGenIsOnInTS_constraints(m,p; _n="")
# Generator must be on for nonnegative output
@constraint(m, [t in p.techs.gen, ts in p.time_steps],
m[:dvRatedProduction][t, ts] <= p.max_sizes[t] * m[:binGenIsOnInTS][t, ts]
m[Symbol("dvRatedProduction"*_n)][t, ts] <= p.max_sizes[t] * m[Symbol("binGenIsOnInTS"*_n)][t, ts]
)
# Note: min_turn_down_fraction is only enforced when `off_grid_flag` is true and in p.time_steps_with_grid, but not for grid outages for on-grid analyses
if p.s.settings.off_grid_flag
@constraint(m, [t in p.techs.gen, ts in p.time_steps_without_grid],
p.s.generator.min_turn_down_fraction * m[:dvSize][t] - m[:dvRatedProduction][t, ts] <=
p.max_sizes[t] * (1 - m[:binGenIsOnInTS][t, ts])
p.s.generator.min_turn_down_fraction * m[Symbol("dvSize"*_n)][t] - m[Symbol("dvRatedProduction"*_n)][t, ts] <=
p.max_sizes[t] * (1 - m[Symbol("binGenIsOnInTS"*_n)][t, ts])
)
else
@constraint(m, [t in p.techs.gen, ts in p.time_steps_with_grid],
p.s.generator.min_turn_down_fraction * m[:dvSize][t] - m[:dvRatedProduction][t, ts] <=
p.max_sizes[t] * (1 - m[:binGenIsOnInTS][t, ts])
p.s.generator.min_turn_down_fraction * m[Symbol("dvSize"*_n)][t] - m[Symbol("dvRatedProduction"*_n)][t, ts] <=
p.max_sizes[t] * (1 - m[Symbol("binGenIsOnInTS"*_n)][t, ts])
)
end
end


function add_gen_can_run_constraints(m,p)
function add_gen_can_run_constraints(m,p; _n="")
if p.s.generator.only_runs_during_grid_outage
for ts in p.time_steps_with_grid, t in p.techs.gen
fix(m[:dvRatedProduction][t, ts], 0.0, force=true)
fix(m[Symbol("dvRatedProduction"*_n)][t, ts], 0.0, force=true)
end
end

if !(p.s.generator.sells_energy_back_to_grid)
for t in p.techs.gen, u in p.export_bins_by_tech[t], ts in p.time_steps
fix(m[:dvProductionToGrid][t, u, ts], 0.0, force=true)
fix(m[Symbol("dvProductionToGrid"*_n)][t, u, ts], 0.0, force=true)
end
end
end


function add_gen_rated_prod_constraint(m, p)
function add_gen_rated_prod_constraint(m, p; _n="")
@constraint(m, [t in p.techs.gen, ts in p.time_steps],
m[:dvSize][t] >= m[:dvRatedProduction][t, ts]
m[Symbol("dvSize"*_n)][t] >= m[Symbol("dvRatedProduction"*_n)][t, ts]
)
end

Expand All @@ -64,17 +92,17 @@ end

Add Generator operational constraints and cost expressions.
"""
function add_gen_constraints(m, p)
add_fuel_burn_constraints(m,p)
add_binGenIsOnInTS_constraints(m,p)
add_gen_can_run_constraints(m,p)
add_gen_rated_prod_constraint(m,p)
function add_gen_constraints(m, p; _n="")
add_fuel_burn_constraints(m,p, _n=_n)
add_binGenIsOnInTS_constraints(m,p, _n=_n)
add_gen_can_run_constraints(m,p, _n=_n)
add_gen_rated_prod_constraint(m,p, _n=_n)

m[:TotalGenPerUnitProdOMCosts] = @expression(m, p.third_party_factor * p.pwf_om *
m[Symbol("TotalGenPerUnitProdOMCosts"*_n)] = @expression(m, p.third_party_factor * p.pwf_om *
sum(p.s.generator.om_cost_per_kwh * p.hours_per_time_step *
m[:dvRatedProduction][t, ts] for t in p.techs.gen, ts in p.time_steps)
)
m[:TotalGenFuelCosts] = @expression(m,
sum(p.pwf_fuel[t] * m[:dvFuelUsage][t,ts] * p.fuel_cost_per_kwh[t][ts] for t in p.techs.gen, ts in p.time_steps)
m[Symbol("dvRatedProduction"*_n)][t, ts] for t in p.techs.gen, ts in p.time_steps)
)
m[Symbol("TotalGenFuelCosts"*_n)] = @expression(m,
sum(p.pwf_fuel[t] * m[Symbol("dvFuelUsage"*_n)][t,ts] * p.fuel_cost_per_kwh[t][ts] for t in p.techs.gen, ts in p.time_steps)
)
end
19 changes: 16 additions & 3 deletions src/constraints/storage_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function add_elec_storage_dispatch_constraints(m, p, b; _n="")
m[Symbol("dvStoredEnergy"*_n)][b, ts] == m[Symbol("dvStoredEnergy"*_n)][b, ts-1] + p.hours_per_time_step * (
sum(p.s.storage.attr[b].charge_efficiency * m[Symbol("dvProductionToStorage"*_n)][b, t, ts] for t in p.techs.elec)
+ p.s.storage.attr[b].grid_charge_efficiency * m[Symbol("dvGridToStorage"*_n)][b, ts]
- m[Symbol("dvDischargeFromStorage"*_n)][b,ts] / p.s.storage.attr[b].discharge_efficiency
- ((m[Symbol("dvDischargeFromStorage"*_n)][b,ts] + m[Symbol("dvStorageToGrid"*_n)][b,ts])/ p.s.storage.attr[b].discharge_efficiency)
)
)
# Constraint (4g)-2: state-of-charge for electrical storage - no grid
Expand Down Expand Up @@ -102,32 +102,45 @@ function add_elec_storage_dispatch_constraints(m, p, b; _n="")

#Constraint (4k)-alt: Dispatch to and from electrical storage is no greater than power capacity
@constraint(m, [ts in p.time_steps_with_grid],
m[Symbol("dvStoragePower"*_n)][b] >= m[Symbol("dvDischargeFromStorage"*_n)][b, ts] +
m[Symbol("dvStoragePower"*_n)][b] >= m[Symbol("dvDischargeFromStorage"*_n)][b, ts] + m[Symbol("dvStorageToGrid"*_n)][b,ts] +
sum(m[Symbol("dvProductionToStorage"*_n)][b, t, ts] for t in p.techs.elec) + m[Symbol("dvGridToStorage"*_n)][b, ts]
)

#Dispatch from electrical storage is no greater than power capacity
@constraint(m, [ts in p.time_steps_without_grid],
m[Symbol("dvStoragePower"*_n)][b] >= m[Symbol("dvDischargeFromStorage"*_n)][b,ts] + m[Symbol("dvStorageToGrid"*_n)][b,ts])

#Constraint (4l)-alt: Dispatch from electrical storage is no greater than power capacity (no grid connection)
@constraint(m, [ts in p.time_steps_without_grid],
m[Symbol("dvStoragePower"*_n)][b] >= m[Symbol("dvDischargeFromStorage"*_n)][b,ts] +
sum(m[Symbol("dvProductionToStorage"*_n)][b, t, ts] for t in p.techs.elec)
)

# Remove grid-to-storage as an option if option to grid charge is turned off
#Constraint (4m)-1: Remove grid-to-storage as an option if option to grid charge is turned off
if !(p.s.storage.attr[b].can_grid_charge)
for ts in p.time_steps_with_grid
fix(m[Symbol("dvGridToStorage"*_n)][b, ts], 0.0, force=true)
end
end

#Constraint (4m)-2: Force storage export to grid to zero if option to grid export is turned off
if !p.s.storage.attr[b].can_export_to_grid
for ts in p.time_steps
fix(m[Symbol("dvStorageToGrid"*_n)][b, ts], 0.0, force=true)
end
end

if p.s.storage.attr[b].minimum_avg_soc_fraction > 0
avg_soc = sum(m[Symbol("dvStoredEnergy"*_n)][b, ts] for ts in p.time_steps) /
(8760. / p.hours_per_time_step)
@constraint(m, avg_soc >= p.s.storage.attr[b].minimum_avg_soc_fraction *
sum(m[Symbol("dvStorageEnergy"*_n)][b])
)
end

end


function add_hot_thermal_storage_dispatch_constraints(m, p, b; _n="")

# Constraint (4j)-1: Reconcile state-of-charge for (hot) thermal storage
Expand Down
2 changes: 1 addition & 1 deletion src/core/electric_utility.jl
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ function cambium_emissions_profile(; scenario::String,
emissions_year::Int=2017
)

url = "https://scenarioviewer.nrel.gov/api/get-levelized/" # Production
url = "https://scenarioviewer.nlr.gov/api/get-levelized/" # Production
project_uuid = "82460f06-548c-4954-b2d9-b84ba92d63e2" # Cambium 2022

payload=Dict(
Expand Down
Loading
Loading