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

Integration into GridCal #1

Closed
SanPen opened this issue Oct 23, 2020 · 8 comments
Closed

Integration into GridCal #1

SanPen opened this issue Oct 23, 2020 · 8 comments

Comments

@SanPen
Copy link

SanPen commented Oct 23, 2020

Hi!,

Would you mind if we integrate this work into GridCal?

It would be a very nice addition.

Best regards,
Santiago

@luap-pik
Copy link
Member

Hi Santiago,

sure, I don't mind! That sounds great.
Let me know if I can assist.

Best wishes,
Paul

@SanPen
Copy link
Author

SanPen commented Oct 23, 2020

Hi Paul,

After a quick check I believe it would be hard to integrate because of the dependencies (igraph, pyunicorn)
pyunicorn fails to install, and I'd rather not impose a compilation dependency since then nobody would be able to run gridcal without a compiler.

If it would be possible to migrate to networkx it would be great, otherwise the cost of integration is too high.

thanks,
Santiago

@luap-pik
Copy link
Member

Hi Santiago,
the basic algorithm here operates on a sparse adjacency matrix and uses igraph only to construct a minimum spanning tree as well as to calculate shortest paths.
It would be straightforward to boil the dependencies down to networkx and numpy.
Which data structure are you using in GridCal to represent the power networks?
Best,
Paul

@SanPen
Copy link
Author

SanPen commented Oct 24, 2020

Hi Paul,

If we can reduce the dependencies to numpy and networkx it would be great.

In GridCal there is an object based data structure: The nodes are the Bus object, and the branches are represented by a series of different objects (Line, Transformer, DCLine, etc...)

My plan was to obtain the graph with its coordinates in the simplest structure that we can have (maybe a Graph object from networkx?) and then convert that result to Bus and Line objects to display in the GUI.

Best regards,
Santiago

@SanPen
Copy link
Author

SanPen commented Oct 24, 2020

This is my take so far:

Commented is the igraph code, and I have replaced it with what I believe it is a Networkx equivalent.

    def _get_mst(self):

        # full_graph = Graph.Full(self.n0)
        # factor = 1e5  # since small weights lead to MST problem
        # weights = [factor * self.distance[self._s((edge.source,edge.target))] for edge in full_graph.es]
        # G = full_graph.spanning_tree(weights).as_undirected()
        # return G.get_edgelist()

        g = nx.complete_graph(self.n0)
        factor = 1e5
        for u, v in g.edges():
            g[u][v]['weight'] = factor * self.distance[self._s((u, v))]
        nx.minimum_spanning_edges(g)
        return list(nx.minimum_spanning_edges(g))

However, in this function I fail to understand the iGraph outcome of G.shortest_paths() since it is a square matrix.

    def _get_graph_distances(self):
        elist = sorted(set([self._s(key) for key in self.adjacency.keys()]))
        G = Graph(self.added_nodes)
        G.add_edges(elist)
     
        # networkx code:
        g = nx.Graph(elist)
        pairs = list(nx.all_pairs_shortest_path(g))

        return np.array(G.shortest_paths())

@luap-pik
Copy link
Member

Hi Santiago,

I think G.shortest_paths() returns for each node all shortest path distances to all the other nodes, hence a matrix.
The equivalent in networkx seems to be

p = dict(nx.shortest_path_length(G))

where p[0][1] is the length of a shortest path from node 0 to node 1.

Maybe you can submit the adjustments you already made in a PR and I can finish this next week.
One possibility is to return a networkx graph object. Alternatively, it could also be just an array of bus
coordinates + an array of links, which you can use to directly create/update the Branch and Bus objects.

Note that, atm the algorithm does not yield different types of links (Line, Transformer, etc.) or buses.
The underlying assumption of the heuristic is that all links are transmission lines on the same voltage level.
So I'd recommend that in GridCal, all the links are Line objects and for the Bus object there needs to be some
(random?) rule to assign them as PQ, PV, etc.

Best,
Paul

@SanPen
Copy link
Author

SanPen commented Oct 25, 2020

Hi Paul,

I have integrated it already, and it seems to work (at least what I'd like to have working)

Captura de pantalla de 2020-10-25 18-53-22
Captura de pantalla de 2020-10-25 18-53-29

The modified code is here and the GUI dialogue here.

thanks for the help!
Santiago

@luap-pik
Copy link
Member

Hi Santiago,
fantastic, looks great! Thank's for the interest in our work.
Best wishes,
Paul

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

No branches or pull requests

2 participants