In working to calculate the marginal cost of electricity of all of the generating units across the country, we first had to calculate the heat rate (MMBtu per MWhr) for each generating unit. The heat rate allows us to attribute the fuel costs, reported at the plant level, to the electric generation, reported at the generating unit level. The heat rate is derived from fuel consumption (MMBtu), reported at the boiler level, and electricity generation (MWh), reported at the generating unit level. To understand the heat rate, one must link up all the boilers with the generators in a given generating unit. Our work to this end uncovered a hole in EIA’s 860 reported boiler generator associations. We filled this hole through a series of matching cartwheels and network analysis.
We’ve recently reconfigured our database ingest process to move the new and improved boiler generator associations into its own table in PUDL. To see this process explained in a jupyter notebook with embedded notes, click here.
There are two essential elements of generating units – namely boilers and generators. You can think of them as the place where the fuel is burned – the boiler – and the place where the electricity is generated – the generator. Yes, this is a ridiculous simplification of a complex system, but it will do for our purposes. In order to understand anything interesting about a generating unit, we need to link the stuff being burned to the electricity generated.
We’ll also need to understand the basics of combined-cycle gas plants. Generally, they have two parts. The first cycle is a gas turbine – natural gas goes in, is burned, expands, and that turns a turbine to generate electricity… and a bunch of very hot exhaust. The second cycle takes that exhaust and uses it to boil water and make steam, which turns a steam turbine. In the first cycle, the gas turbine functions as the boiler as well as the generator. In the second cycle, there’s little to no separate fuel being burned — it just uses the leftover heat from the first cycle.
State of the (EIA) Union
I can’t tell you how excited I was to find the EIA 860 environmental associations table, which lists boiler generator associations. Subsequently, I can’t tell you how confused I was to realize that the table showed complete associations for some plants but not others. So we reached out to EIA to better understand this. Here was their response:
“As I am sure you are aware, we account for combined cycle facilities using three prime mover codes:
– CA – combined cycle steam part
– CS – combined cycle single shaft
– CT – combined cycle turbine part.
For our EIA-860 and EIA-923 reports, plants are only supposed to submit data on their boilers and associated equipment. Therefore, since boilers are associated with steam generators, only the generators that have a prime mover of a “CA” or “CS” (when referring to combined cycle facilities) are listed in the boiler/generator association table. The gas turbine parts of combined cycle facilities (prime mover “CT”) are not included in this association table.”
Well, that’s clear enough, although not particularly useful. The combustion turbines in the combined cycle plants were not associated with the steam turbines. Some very strange heat rates resulted. All of the generation was assigned to generators connected to “boilers” that used little to no fuel. This is what the heat rate looked like when we calculated it on a per plant basis before we added additional layers of mapping, with the anomalously low heat rates on the left:
In order to build more complete boiler generator associations, we compiled all of the tables from EIA 860 (released in individual files) and EIA 923 (released as tabs in a single file) which have boilers or generators (here with original EIA table name / a PUDL table name that we assigned):
- EIA 860 Tables:
- Enviro_Assoc / ‘boiler_generator_assn_eia860’ – the (limited) boiler generator associations
- Generator / ‘generators_eia860’: generator info, including capacity and (limited) unit codes
- EIA 923 Tables:
- Generator / ‘generation_eia923’: monthly net generation by generator
- Boiler Fuel / ‘boiler_fuel_eia923’: monthly fuel consumption (in number of physical units and MMBTU per unit) by boiler
From these tables, we created a list of generators from generation_eia923, boiler_generator_assn_eia860 and generators_eia860. We then created a list of boilers from boiler_fuel_eia923 and boiler_generator_assn_eia860. We also used the existing associations from boiler_generator_assn_eia860. Those three tables became the building blocks of our more complete associations.
The Cobbling Begins: 4 Steps to Boiler Generator Associations
After many white boards full of flow charts and pretend gas plants, we finally figured out how to connect the dots. A more complete set of boiler generator associations occurs through just four steps:
- Use the associations in the ‘boiler_generator_assn_eia860’ table
- String match remaining unmapped generators to unmapped boilers
- Use unit codes reported in generators_eia860
- Use network analysis to create our own unit id’s
We’re going to show this process with Barry (Alabama Power Company, and the plant that is almost always at the top of every table) because it’s a relatively good example.
Use what yo (EIA) mamma gave ya…
First, we compiled a complete list of generators from EIA 923 and EIA 860. Then, we merged the EIA 860 boiler generator associations onto that list, seen in the ‘boiler_id’ column. For the entire data set, this got us 57% of the annual boiler/generator mappings. For Barry, we get nine out of thirteen.
In our sleuthing, we realized that many of the unmapped boilers and generators id’s actually are the same strings. This is weird because most of the id’s mapped in the EIA 860 association table have wildly different id’s. So we simply merged the remaining unmapped generators to the unmapped boilers. Using the report date, EIA plant id, and the respective boiler or generator id, this mapped another 3,621 records. Another 2% of the possible annual mappings!
String associations result in a complete mapping for Barry:
Using the Unit Codes
Next we used the unit code reported in the EIA 860 generators table. EIA 860 does not report unit codes for every single generator record. There are 9592 records from 2011-2016 with some unit code, which helped connect the remaining, unmapped steam turbine portion of the combined-cycle plants to the natural gas turbine portion. Suddenly, we had 80% of the generators mapped!
That left 577 records – representing 216 individual plants – unmapped. Out of those 216 plants, only 70 reported any generation on Form EIA 923. Compared to the 10,139 plants mapped through our process, we thought that was pretty darn good.
Unit Mapping Through Network Analysis
We really care about the collection of boilers and generators at the generating unit level – i.e. the collection of all connected and interdependent boilers and generators. It doesn’t make sense to talk about a “heat rate” at any smaller unit, since the fuel consumption and electricity output are mingled at the unit level. In order to connect the relatively disparate associated generators and boilers into units, we did some simple network analysis. This analysis relied on the NetworkX python package originally developed at the Los Alamos National Laboratory. For every plant, we created a graph of all of the connections between the boilers and generators, with every connected subgraph assigned a unique unit id.
After compiling these network connections, we had a relatively complete set of boiler generator associations. Sadly the EIA only started requiring utilities to report the fuel consumption for both the gas and steam turbine portions of combined-cycle plants in 2014. So the heat rates for combined-cycle plants are only really useful from then forward. But at least for the last couple of years, we now have pretty cleanly and completely mapped generating units, and we can see what fuel costs look like at the smallest meaningful unit of infrastructure.