Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New interface: make Network a container object #1

Open
lumbric opened this issue Apr 12, 2024 · 0 comments
Open

New interface: make Network a container object #1

lumbric opened this issue Apr 12, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@lumbric
Copy link
Contributor

lumbric commented Apr 12, 2024

This might be a neat change for the future. It should be possible to implement it in a backward compatible way.

Current interface

In the current interface, one needs to pass input nodes to the constructor of the output node to
create connections in the network:

some_node = Node(
    name='some_node'
    inputs=[input_node1, input_node2],
    inputs_commodities=['electricity', 'co2'],
    costs=10
    convert_factor=10,
)
Network([input_node1, input_node2, some_node])

This enforces implicitly that the resulting graph is acyclic and that way the Network object
immediately represents a complete graph and the optimization model can be generated its
constructor as there is no information missing.

Suggestion

some_node = Node(
    name='some_node'
    costs=10
    convert_factor=10,
)
network = Network()

network.connect_nodes(input_node1, some_node, commodity='electricity')
network.connect_nodes(input_node2, some_node, commodity='co2')

The method connect_nodes() would also add the nodes to the network if they are not there yet (is
this a good method name then if it also adds it to the network?).

Alternatively we could use a method add_node():

network.add_method(
    name='some_node'
    costs=10,
    convert_factor=10,
    node_type='node',
)

One more option which might make sense: similar to PyPsa, one could allow referencing to the nodes
in connect_nodes() as strings if the are already part of the network object:

network.connect_nodes('input_node1', 'some_node', commodity='electricity')

Motivation

This might be way more readable and many things are easier to be implemented if the network can be
passed around functions as a container object and the information for the network can be connected
piece by piece in any order.

Especially also for unit testing it might be helpful as one could create a base network and than
add stuff to it for testing specific features.

Hints for implementation

In the network class one needs to take care of:

  • generate graph on the fly, i.e. not in the constructor but only when it's needed
    • lazy generate the linopy.Model() object: set self.model to None and call _generate_optimization_model()inoptimize(), add_constraints()andadd_variables()ifself.modelis stillNone`
    • lazy generate the networkx object self.graph for plotting in Network.draw() or simply
      remove self.graph and call _create_graph() in draw() every time?
    • raise error if the network is changed somehow after the linopy.Model has been generated and
      self.model is not None, i.e. in add_node(), connect_nodes(), add_constraints(),
      add_variables() - basically the Network object should be modified only through methods
    • update or lazy generate the nodes_dict attribute, outputs of nodes and other things done in Network.__init__()
  • check that the graph is acyclic at some point (before optimize() is called?)
  • check that all nodes are connected (before optimize() is called?) - see _check_all_nodes_connected()
@lumbric lumbric added the enhancement New feature or request label Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant