Give the 9n_H2 electrolyzers hydrogen storage and a weekly target - #158
Merged
Conversation
The documentation defines the "Electrolyzer (ELZ)" unit type as an ESS with electric energy outflows and a production function to hydrogen. The two electrolyzers in this case had the production function but neither outflows nor storage, so they were the shape the documentation describes only in part. Give each one a 1.512 GWh buffer and a weekly outflow cycle, and state the hydrogen demand as the electricity needed to make it. The case asks for 0.3 tH2/h and the production function is 60 kWh/kgH2, which is 18 MW of electrolysis, split evenly between the two units at 9 MW each. One week of that obligation is 1.512 GWh, which is how the buffer is sized. The point of the change is that the outflow fixes how much energy is withdrawn over a week, not when it is drawn. The electrolyzers can now consume when electricity is cheap and carry energy between weeks in the buffer, which is how hydrogen behaves as a medium-term store.
With the hydrogen demand now expressed as an energy outflow on the electrolyzers, the nodal hydrogen demand and the pipeline network describe the same demand a second time. Keeping both would ask the electrolyzers to produce it twice: once into the hydrogen balance at the moment they consume electricity, and again to satisfy the outflow. openTEPES decides whether to build the hydrogen sector from whether these two files are present, so removing them is what turns it off. This does cost the case its hydrogen network coverage. sSEP still exercises that path, with hydrogen demand, a pipeline network and nine hydrogen generators, so the suite does not lose it altogether.
Update the expected cost of the 7-day run to 242.89492215294186 and correct the coverage matrix, which still described 9n_H2 as carrying hydrogen demand and pipes. Add four tests, because the case can keep solving and keep matching a cost while the storage quietly stops doing anything: - the energy-outflow constraint is built and has rows. It is only written at load levels that are a whole multiple of the outflow cycle, so a cycle longer than the horizon skips it everywhere and silently removes the obligation to produce anything. The cost then falls to that of a system with no electrolyzers. - each electrolyzer withdraws exactly the energy the case asks of it. - consumption varies across the week rather than tracking a flat profile, which is the flexibility the archetype exists to provide. - the electrolyzers do not spill. Without storage or outflows the inventory balance is met by sending the whole charge to spillage, which costs nothing, so the reported spillage equalled every unit of electricity drawn. The third test deliberately does not assert that the buffer fills. The fixture is exactly one weekly cycle, and within a single cycle the withdrawal can move too, so the electrolyzer can shift its charging without storing anything. Storage earns its keep between cycles, which needs a horizon longer than a week.
erikfilias
marked this pull request as ready for review
July 28, 2026 10:47
erikfilias
marked this pull request as draft
July 28, 2026 10:57
Contributor
Author
|
The cycle-length problem noted under "Related bug" is now filed separately as #159. It also affects the energy limits of a unit, not only the energy outflows, and in that case the reported cost was 10.4 per cent too low. |
arght
approved these changes
Jul 28, 2026
erikfilias
marked this pull request as ready for review
July 28, 2026 14:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An electrolyzer turns electricity into hydrogen. In the
9n_H2example case, the two electrolyzers hadto make hydrogen at the exact moment it was needed, every hour, with nowhere to put it. Real hydrogen is
usually stored and used over days or weeks.
This changes the case so the electrolyzers have a storage buffer and a weekly target instead of an hourly
one. They still make the same amount of hydrogen, but they can now choose when to draw the electricity.
Changes
The documentation defines the "Electrolyzer (ELZ)" unit type as an ESS with electric energy outflows and
a production function to hydrogen. These two units had the production function but no outflows and no
storage, so they only matched that description in part.
18 MW, split evenly at 9 MW per unit.
Removed files
The demand is now counted through the outflows. The nodal hydrogen demand and the pipe network describe
the same demand a second time, and keeping both would ask the electrolyzers to produce it twice. openTEPES
builds the hydrogen sector only when those two files are present, so removing them turns it off.
Results
Over a full year, solved with Gurobi:
Nearly all of the saving is in generation operating cost, 165.700 → 163.326. Both electrolyzers are now
used, where before only the first one ran.
The case also stops reporting 157.248 GWh of wasted electricity. With no storage and no outflows, the
inventory balance was satisfied by writing off the whole charge as spillage, which costs nothing. Giving
that energy somewhere to go brings the figure to zero.
Related bug
An outflow cycle longer than the modelled horizon removes the production target without warning.
pStorageTimeStepis capped by the stage duration inopenTEPES_DataConfiguration.py:513, butpOutflowsTimeStepis not, andmTEPES.nesois built from the uncapped value. If no load level satisfiesord(n) % pOutflowsTimeStep == 0, the constraint is skipped everywhere.A monthly cycle under the 7-day test fixture still solved and returned the cost of a system with no
electrolyzers at all. That is why this PR uses a weekly cycle. Probably worth a separate issue.