-
Notifications
You must be signed in to change notification settings - Fork 28
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
refactor: improve mapping of generators to buses #267
Conversation
96a2164
to
727f654
Compare
I've refactored this so that it ignores states completely, and uses the voltage(s) available at each substation to help ensure that generators don't get mapped to substations with inadequate transmission capacity, based on their listed 'grid voltage' within Form 860. In a quick one-day test on Eastern, it seems to help: previously the transmission violations were > 17 GW in every hour of the year, but in the test day we have transmission violations as low as 1.3 GW. I'll run the full year over the weekend and report more detailed results. The nonsensical-interconnection listing is at least partially fixed by using the Balancing Authority column of each generator within Form 860 to map to interconnects, rather than the NERC region. For whatever reason, BA seems more reliable, and we only use the NERC region as a fall-back. The generators which end up getting mapped more than 50 miles away now all seem to be either:
|
67377d5
to
39058fb
Compare
Results for full-year runs with the new voltage-class and interconnection mapping of generators to substations:
We're down to only 138 branches with violations across the whole USA. The next thing I'm going to try is revising the configuration of transformers within substations, which should hopefully increase the effective impedance between the higher-voltage buses at which large generators are connected and the lower-voltage buses connected to low-voltage branches with transmission violation. |
The 'cascade' configuration (every bus within a substation is connected via a transformer to the next-highest bus) reduces transmission violation energy only barely compared to the previous configuration (every bus is connected to the substation's highest-voltage bus), but has a larger impact on reducing the number of branches at which transmission violations occur:
The remaining transmission violations are pretty heavily concentrated among a few branches, with what I believe are a few common root causes:
|
616b948
to
b7d62bb
Compare
1cd3e14
to
8e7ec12
Compare
8e7ec12
to
071ddf5
Compare
071ddf5
to
ea66a5b
Compare
subs_voltage_lookup = { | ||
(interconnect, voltage_level): substations_with_xyz.loc[ | ||
(substations_with_xyz["interconnect"] == interconnect) | ||
& (substations_with_xyz["MAX_VOLT"] >= voltage_range["min"]) |
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.
So we only care about lower bound here instead of the exact voltage_range
defined in the dict voltage_ranges
?
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.
The primary goal of this PR was to avoid large generators getting mapped to substations without at least one high-enough voltage bus (and therefor probably too low of a transfer capacity). I guess we could make it more strict by ensuring that there's at least one bus that's truly within the range, which will have the tradeoff that the distance to the connection location may sometimes increase. What do you think?
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.
Yeah, you are right. Having more strict filter will potentially give us farther mapping if there is no match nearby. Which side in the trade-off is more important, the location or the voltage range? If the voltage range turns out to be more important, let's go with the more strict way, otherwise, let's keep what we have.
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.
Hard to say really. Locations will give us more representative renewable profiles, but voltage ranges can help ensure that generators aren't hooked up to substations with more transmission capacity than they should be (will impact the renewable curtailment). I'm leaning towards locations, but could probably be convinced otherwise.
1abbf65
to
6641a32
Compare
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.
I think this is good to go. Thanks!
6641a32
to
ffb2d4d
Compare
…_mapping refactor: improve mapping of generators to buses
…_mapping refactor: improve mapping of generators to buses
Pull Request doc
Purpose
In preliminary testing, the
hifld
grid model had shown a lot of infeasibilities caused by mismatches between inflexible generators (namely coal, nuclear, and hydro) and local transmission capacities. This PR aims to improve this in two primary ways:Hydro aggregation is relevant to the
improving how generators are mapped to buses within substations
step, since we decide which bus within a substation to map to based on generator capacity.The most complicated part by far is the how generators are mapped to substations. The old logic was:
The new logic is:
The no-coordinates case is a fraction of a percent; the big changes are from the cases where we do have coordinates and now use those as the primary substation mapping tool, rather than ZIP codes.
What the code is doing
Aggregating hydro units: a new
aggregate_hydro_generators_by_plant_id
function is added, which groups hydro units by plant ID, sums Pmin and Pmax, and returns all other attributes and index from the first unit in the group.Improving the mapping of generators to substations:
map_generator_to_sub_by_location
and add a replacementmap_generators_to_sub_by_location
. These function names differ because the previous one operated on onegenerator
at a time as a part of anapply
call, while the new one operates on the entiregenerators
dataframe.substations
and generators dataframes into (x, y, z) pairs in 3d space, where the center of the earth is (0, 0, 0) and the radius is 1. We use a newlatlon_to_xyz
function that we add to prereise, rather than the existingll2uv
implementation in powersimdata to loosen the coupling of the two packages and to avoid ambiguity between (lat, lon) and (lon, lat). Then, aKDTree
is instantiated for each combination of (interconnect, state). If there exists one or more generators labelled with (interconnect, state) for which there are no substations with corresponding (interconnect, state):KDTree
for that entire interconnection (e.g. a plant that's physically located in Oklahoma may have a single transmission line that connects it to ERCOT).Improving how generators are mapped to buses within substations:
map_generator_to_bus_by_sub
is refactored from the previous logic (always map to the lowest-voltage bus within the substation) to branching logic:There's also a small unrelated fix to prevent duplicate
'interconnect'
columns in some output CSVs, which was preventing thegrid.mat
files created from REISE.jl from being read back into PowerSimData for post-simulation analysis.Testing
Tested manually. The printouts for the edge cases of mapping generators to substations looks like:
With this change, about 25% of generators end up mapped to a different substation (2,837 out of 12,735). In addition, 29 generators can be mapped which were not mapped with the previous logic. The most impactful change may have been how Palo Verde's generator were mapped: previously they ended up at a 69 kV substation within metro Phoenix; now they're appropriately connected to the 500 kV substation at their true location. Many other large inflexible generators are relocated as well, and generators in WECC seem to be particularly affected.
Running powerflows with the results shows drastic improvement in WECC, where infeasibilities were initially the worst. Previously, the total amount of transmission line limit violation energy that was required was about 25% of the total demand. After the change, this is down to 0.45%. In addition, transmission violations occur at fewer than half as many lines as before. Eastern powerflows are still running but I expect to see significant improvements there as well. EDIT: Eastern is done. The improvements aren't quite as good as in Western, but are still big improvements. Transmission violation energy is down to 5.1% (from 18.2% before) and at 0.19% of branches (from 0.61% before). That puts the overall USA-wide number of violating branches down to around 200, less than 1 out of every 400 branches, and about a third as many as before the refactor.
Usage Example/Visuals
All code is still launched via:
Time estimate
1 hour. Most of the new code is pretty straightforward, but about half of it is designed to combat edge cases caused by strange data inputs from the original EIA Form 860 data.