Skip to content

Comments

Integrated heat storage and e-conversion asset#396

Open
FJanssen-TNO wants to merge 17 commits intomainfrom
heat_storage_e_input
Open

Integrated heat storage and e-conversion asset#396
FJanssen-TNO wants to merge 17 commits intomainfrom
heat_storage_e_input

Conversation

@FJanssen-TNO
Copy link
Collaborator

Start on creating an integrated heat storage asset that can be charged using electricity.
Using a heatbuffer with an additional electricity port.

  • Check setup
  • Add the parsing of the new relevant efficiencies --> e.g. charging efficiency (conversion of e to heat)
  • Check that still efficiency of the buffer can be set, e.g. self discharge rate or something else.
  • Add test
  • Update changelog

@tolga-akan tolga-akan marked this pull request as ready for review February 6, 2026 14:38

# ToDo: Check if max_supply (and also elec_power_nominal)
# can be defined via hfr_charge_max.
max_supply = hfr_charge_max
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this max_supply is the maximum heatflow

Comment on lines 456 to 459
for port in asset.in_ports:
if isinstance(port.carrier, esdl.ElectricityCommodity):
min_voltage = port.carrier.voltage
i_max, i_nom = self._get_connected_i_nominal_and_max(asset)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This part can be generalized in a function. It is used at least at two other locations.

Copy link
Collaborator

Choose a reason for hiding this comment

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

self._get_min_voltage(asset) function is created

return HeatBuffer, modifiers
modifiers.update(
dict(
id_mapping_carrier=id_mapping,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why do we need an id_mapping_carrier? I don't see a use for it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

that is true actually. There is no need for this

dict(
**self._generic_heat_modifiers(-hfr_discharge_max, hfr_charge_max, q_nominal),
)
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

try to generalize this and the above __generic_heat_modifiers. The original implementation is okay.
In case "q_nominal" is a dict instead of a float due to the asset having more ports, you could also set q_nominal to q_nominal["Q_nominal"]

Copy link
Collaborator

Choose a reason for hiding this comment

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

good idea. suggestion is implemented


@add_variables_documentation_automatically
class HeatBuffer(_StorageComponent):
class HeatBufferModel(_StorageComponent):
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If this class is not supposed to be used directly, rather name it something like "_HeatBufferComponent" --> the underscore informs us that this model should not be used directly in MESIDO but only as an inherited model. Rather use "Component" instead of "Model" everything is a model...

Copy link
Collaborator

Choose a reason for hiding this comment

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

fair point!
Done!

Comment on lines 54 to 55
# Check heat flows into buffer coems from heat network and
# the electricity component of the buffer
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Don't need long explanations for every check, only if it is not self explanatory, then ensure that is concise but clear, like "checking energy flows in and out of buffer".

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes

np.testing.assert_allclose(
results["HeatStorage.Heat_buffer"],
results["HeatStorage.Heat_flow"] + results["HeatStorage.Heat_elec_charging"],
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

might be good to add additional check that actually derivative of stored heat is coming from heat loss and heat_buffer. This to ensure that really heat_buffer is used to calculate stored heat and not by accident heat_flow.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Check that derivative of stored heat is coming from heat loss and heat_buffer is added now

Comment on lines 12 to 17
The heat buffer component models heat storage in a tank. This component also incorporates the
ability to use electricity for charging this component. Like all heat storage components,
it loses heat to the surroundings, however here also an efficiency for the conversion of
electricity to heat is incorporated. Since this way of charging heat does not require water
flow through the inlet/outlet pipes, a separate variable is created to define the additional
heat charged.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the description only explain what has been added in this asset.
So the ability to charge heat using electricity.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Docstring is updated

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This ESDL is more complicated than needed. Instead of a e-boiler, just the use of a generic heat producer should be okay.
Furthermore, the location of this esdl file is confusing, since in this folder I would only expect esdls with sources and sinks but no storage assets.

Copy link
Collaborator

Choose a reason for hiding this comment

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

e-boiler is replaced by generic heater.

esdl and csv files are moved into "tests/models/simple_buffer"


class TestHeat(TestCase):

def test_elec_heat_buffer_elec(self):
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seems unlogical to place this test overhere.

Copy link
Collaborator

Choose a reason for hiding this comment

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

test is moved into "test_multiple_in_and_out_port_components"

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