Skip to content

Model storage water heaters as a heater charging a fixed-size tank - #867

Merged
WeiAi-Energy merged 3 commits into
PyPSA:developfrom
WeiAi-Energy:issue-865
Oct 28, 2026
Merged

WeiAi-Energy merged 3 commits into
PyPSA:developfrom
WeiAi-Energy:issue-865

Conversation

@WeiAi-Energy

@WeiAi-Energy WeiAi-Energy commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #865, closes #866, closes #696.

Changes proposed in this Pull Request

The first commit converts the EIA building equipment costs from 2022$ to 2023$ (CPI-U, ×1.0413) (#866).

The second commit replaces simple_storage (#865), following the discussion in #846:

  • simple_storage, n_hours, the false branch and add_water_heater_constraints are removed.
  • The charger is the heater: efficiency, CO2, and the unit cost per MW of input. The store is the hot water. The discharger draws from it at a nominal 1 USD/MW/yr and retires with the new heater.
  • add_water_heater_tank_constraints sets each new tank to the unit's energy to power ratio times the heater capacity.
  • Existing heaters charge their own fixed tanks of the same ratio.
  • eia_tech_costs.csv: the six storage water heaters are priced per unit (costs unchanged), with tank volume and input capacity. Commercial units and residential tank volumes are from the EIA report. Residential input capacities and the 50 gal electric tank are from the DOE 2024 consumer water heater TSD (Tables 7.3.2, 7.3.8). The ratios are 0.17–1.86 h.
  • Oil water heaters take marginal_oil instead of marginal_gas (both 0 today).

The third commit merges water_heating: split_space_water into split_space_water_heating (#696). The old key picked the technologies in build_heat.py and add_sectors.py, while split_space_water_heating picked the demand files in build_electricity.smk. Both are true in config.sector.yaml and no other config sets them, so results do not change. The config table now refers only to split_space_water_heating.

Testing

  • test_water_heaters.py (4 tests), including a solve in which each tank is tied to its heater. It fails without the constraint.
  • End to end on UT (simpl: 10, clusters: 2, E-G, January 2018): tanks match their heaters and dischargers settle at their peak draw. Residential electric water heating builds 25 MW of heaters with a 47 MWh tank, instead of a 2,504 MW charger and a 12,187 MWh tank with simple_storage.
  • pytest -m fast: 995 passed, 11 skipped, 4 failed. The 4 failures also fail on develop: the three GoDEEEP CF registry tests and test_dag_dryrun.py::test_interface_limits_input_follows_config_key.

Checklist

  • I tested my contribution locally and it seems to work fine.
  • pre-commit and pytest -m fast pass locally.
  • Code and workflow changes are sufficiently documented.
  • Changed dependencies are added to workflow/envs/environment.yaml.
  • Changes in configuration options are added in workflow/repo_data/config/config.default.yaml.
  • Changes in configuration options are also documented in docs/source/configtables/*.csv.

simple_storage, n_hours and water_heating: split_space_water are removed from config.sector.yaml; they were not in the config tables.

🤖 Generated with Claude Code

WeiAi-Energy and others added 2 commits October 28, 2026 02:48
The EIA 2023 equipment cost report is in 2022 dollars. Scale its
investment costs by CPI-U 2023/2022 (1.0413) to the model's 2023 dollars.

Closes PyPSA#866.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove `water_heating: simple_storage` and `n_hours`, which gave every
water heater a free, unlimited tank.

- The charger is the heater: efficiency, CO2, and the unit cost per MW
  of input. The store is the hot water. The discharger draws from it.
- `add_water_heater_tank_constraints` sets each new tank to the
  energy to power ratio of the unit times the heater capacity.
- Existing water heaters charge their own tanks of the same ratio.
- The six storage water heaters are priced per unit, with the tank
  volume and input capacity of the typical EIA/DOE unit.

Closes PyPSA#865.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@WeiAi-Energy
WeiAi-Energy requested a review from trevorb1 October 28, 2026 06:50

@trevorb1 trevorb1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, don't have time to review this one today and dont want to hold you up! Your PR description made sense to me though, so please feel free to merge! Can this one also close #696 ?

service_sector had both split_space_water_heating (read by
build_electricity.smk to pick demand files) and
water_heating.split_space_water (read by build_heat.py and
add_sectors.py to build technologies). Keep only
split_space_water_heating and document it.

Closes PyPSA#696.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@WeiAi-Energy

Copy link
Copy Markdown
Collaborator Author

Sorry, don't have time to review this one today and dont want to hold you up! Your PR description made sense to me though, so please feel free to merge! Can this one also close #696 ?

I added a third commit that also closes #696. service_sector had two keys for the same switch. I kept only split_space_water_heating and documented it.

@WeiAi-Energy
WeiAi-Energy merged commit ffc1364 into PyPSA:develop Oct 28, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants