Repository navigation
Make CO2 storage run under PyPSA 1.x and split CCS CO2 correctly - #859
Conversation
With co2: storage: true the workflow stopped in add_extra_components (sector E) and add_sectors (sector E-G). - The add_extra_components rule provides the CO2 storage csv for sector E, as the script expects, rather than for an empty sector. - add_co2_storage, add_dac and add_co2_network filter by index instead of querying the pre-PyPSA 1.x index names (Carrier, Bus, Link), and the CC carriers are added under their new names. - CCS generators and links are renamed along with their time series. - Each CCS plant captures to the capture bus of its own node, rather than to the list of all storage nodes, and a node, state or nation gets one atmosphere bus however many CC plants vent to it. - Links without a fourth output get an empty bus4. - The sector-less DAC links are built per node with a CC plant, so their buses line up with more than one CCS technology. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Electricity-only studies: a CC plant sent all its CO2 to the atmosphere and (1 - cc) / cc of it to the capture bus. It now vents (1 - cc) and captures cc of the CO2 of the fuel it burns. - Sector studies: CCS links are rated on the fuel they draw, so their CO2 is the fuel's intensity, split into cc captured and (1 - cc) emitted. Dividing it by the efficiency overstated both by 1/(eff * cc). - get_pwr_co2_intensity gives coal CCS plants the CO2 intensity of coal rather than of gas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
trevorb1
left a comment
There was a problem hiding this comment.
LGTM! Just a couple clarification comments, @WeiAi-Energy. I only reviewed the sector things, and will let @ktehranchi review the electricity side of things if he wants. :)
| def rename_components(n: pypsa.Network, component: str, names: dict[str, str]) -> None: | ||
| """ | ||
| Renames components, along with their time series. | ||
|
|
||
| pypsa's rename_component_names also renames the references to them in the other components, but fails for | ||
| generators (it looks for a "generator" column in every component), which nothing refers to anyway. | ||
| """ | ||
| c = n.components[component] | ||
| c.static = c.static.rename(index=names) | ||
| for attr, df in c.dynamic.items(): | ||
| c.dynamic[attr] = df.rename(columns=names) | ||
|
|
||
|
|
There was a problem hiding this comment.
Is this same as rename_component_names? Like are we able to just use this built in function already? Or is this function different?
There was a problem hiding this comment.
I tried it first, but on PyPSA 1.3.0 it only works for buses. After renaming, it updates cross-references by looking for a {port} column (e.g. generator, link) in every component with ports:
For buses this finds bus, bus0, bus1, ..., but for Generator and Link it looks for generator or link columns that don't exist, so it raises KeyError: "None of [Index(['link'])] are in the [columns]". Nothing refers to generators or links by name, so we only need the first part (renaming the static index and the time series columns), which is all this helper does.
There was a problem hiding this comment.
Hmm... this is weird. I would think this method should be general for any of the pypsa components. I have reported to the pypsa maintainers here to get clarity. Lets keep this unresolved until we hear what they say. But I think your fix is good, @WeiAi-Energy, to merge and we can update if needed when we hear back! :)
Rules are parsed before the Snakefile pads an empty sector to "E", so the condition has to accept both spellings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closes #857, closes #858.
Changes proposed in this Pull Request
The first commit makes
co2: storage: truerun (#857):add_extra_componentsrule provides the storage csv forsector: E.query("Carrier/Bus/Link...")becomes plain index filtering. The CC carriers are added under their new names.The second commit splits CCS CO2 correctly (#858):
Testing
test_co2_storage.py(9 tests). The 6 storage tests fail on develop, and the 3 split tests fail without the second commit.simpl: 10,clusters: 2), with CO2 storage, the CO2 network, DAC, and a binding 10 kt REM limit:UT pwr-co2.pytest -m fast: 1003 passed, 11 skipped, 4 failed. The 4 failures also fail on develop: the three GoDEEEP CF registry tests andtest_dag_dryrun.py::test_interface_limits_input_follows_config_key.Checklist
pre-commitandpytest -m fastpass locally.workflow/envs/environment.yaml.workflow/repo_data/config/config.default.yaml.docs/source/configtables/*.csv.🤖 Generated with Claude Code