Refresh

This website github.com/matzech/PyPSA/commit/532676a05bdb91c7d30f7e35056ff34ad7a89272 is currently offline. Cloudflare's Always Online™ shows a snapshot of this web page from the Internet Archive's Wayback Machine. To check for the live version, click Refresh.

Skip to content

Commit

Permalink
Allow multiple branches between buses; remove objects; import SciGRID…
Browse files Browse the repository at this point in the history
… example

Multiple branches between buses are allowed via nx.MultiGraph; the
branch object is the key for the edge.

Objects can now be gracefully removed.

A network.topology_determined switch indicates whether the topology
has already been calculated / needs to be recalculated.

An example of importing SciGRID is included.

Changes to be committed:
	modified:   .gitignore
	modified:   components.py
	modified:   descriptors.py
	new file:   examples/scigrid-151109/LICENSE
	new file:   examples/scigrid-151109/NOTICE
	new file:   examples/scigrid-151109/import_scigrid.py
	new file:   examples/scigrid-151109/links_de_power_151109.csvdata
	new file:   examples/scigrid-151109/vertices_de_power_151109.csvdata
	new file:   examples/scigrid-151109/vertices_ref_id.csvdata
	new file:   guidelines.org
	modified:   io.py
	modified:   opf.py
	modified:   pf.py
  • Loading branch information
nworbmot committed Dec 1, 2015
1 parent 063df14 commit 532676a
Show file tree
Hide file tree
Showing 13 changed files with 2,581 additions and 13 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

*.log

*.org

old/

*.ipynb

test/.cache/
test/.cache/

.~*
60 changes: 53 additions & 7 deletions components.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from collections import OrderedDict
from itertools import chain

from .descriptors import Float, String, OrderedDictDesc, Series, GraphDesc
from .descriptors import Float, String, OrderedDictDesc, Series, GraphDesc, OrderedGraph

from io import export_to_csv_folder, import_from_csv_folder, import_from_pypower_ppc

Expand Down Expand Up @@ -81,10 +81,10 @@ class Bus(Common):

list_name = "buses"

v_nom = Float()
v_nom = Float(default=1.)
control = String(default="PQ",restricted=["PQ","PV","Slack"])

#2-d location data (e.g. longitude and latitude)
#2-d location data (e.g. longitude and latitude; Spatial Reference System Identifier (SRID) set in network.srid)
x = Float()
y = Float()

Expand Down Expand Up @@ -309,8 +309,17 @@ class Network(Basic):
#limit of total co2-tonnes-equivalent emissions for period
co2_limit = None


#Spatial Reference System Identifier (SRID) for x,y - defaults to longitude and latitude
srid = Float(4326)

graph = GraphDesc()


#booleans for triggering recalculation
topology_determined = False


def __init__(self, csv_folder_name=None, **kwargs):

#hack so that Series descriptor works when looking for obj.network.snapshots
Expand Down Expand Up @@ -347,6 +356,12 @@ def add(self,class_name,name,**kwargs):
print(class_name,"not found")
return None

obj_list = getattr(self,cls.list_name)

if str(name) in obj_list:
print("Failed to add",name,"because there is already an object with this name in",cls.list_name)
return

obj = cls(self)

obj.name = name
Expand All @@ -355,7 +370,7 @@ def add(self,class_name,name,**kwargs):
setattr(obj,key,value)

#add to list in network object
getattr(self,cls.list_name)[obj.name] = obj
obj_list[obj.name] = obj

#build branches list
if isinstance(obj, Branch):
Expand All @@ -374,10 +389,33 @@ def add_from(self,object_list):
def remove(self,obj):
"""Remove object from network."""

obj_list = getattr(self,obj.__class__.list_name)

if obj.name not in obj_list:
print("Object",obj,"no longer in",obj.__class__.list_name)
return

obj_list.pop(obj.name)

if isinstance(obj, Branch):
self.branches.pop(obj.name)

if hasattr(obj,"bus"):
getattr(obj.bus,obj.__class__.list_name).pop(obj.name)

del obj

self.topology_determined = False


def build_graph(self):
"""Build networkx graph."""

self.graph.add_edges_from((branch.bus0, branch.bus1, {"obj" : branch}) for branch in self.branches.itervalues())
#reset the graph
self.graph = OrderedGraph()

#Multigraph uses object itself as key
self.graph.add_edges_from((branch.bus0, branch.bus1, branch, {}) for branch in self.branches.itervalues())


def determine_network_topology(self):
Expand All @@ -388,20 +426,25 @@ def determine_network_topology(self):

graph = self.graph.__class__(self.graph)

graph.remove_edges_from((branch.bus0,branch.bus1)
graph.remove_edges_from((branch.bus0, branch.bus1, branch)
for branch in chain(self.converters.itervalues(),
self.transport_links.itervalues()))


#now build connected graphs of same type AC/DC
sub_graphs = nx.connected_component_subgraphs(graph, copy=False)


#remove all old sub_networks
for sub_network in list(self.sub_networks.values()):
self.remove(sub_network)

for i, sub_graph in enumerate(sub_graphs):
#name using i for now
sub_network = self.add("SubNetwork", i, graph=sub_graph)

sub_network.buses.update((n.name, n) for n in sub_graph.nodes())
sub_network.branches.update((branch.name, branch) for (u, v, branch) in sub_graph.edges_iter(data="obj"))
sub_network.branches.update((branch.name, branch) for (u, v, branch) in sub_graph.edges_iter(keys=True))

for bus in sub_network.buses.itervalues():
bus.sub_network = sub_network
Expand All @@ -410,6 +453,9 @@ def determine_network_topology(self):
branch.sub_network = sub_network


self.topology_determined = True



class SubNetwork(Common):
"""Connected network of same current type (AC or DC)."""
Expand Down
6 changes: 3 additions & 3 deletions descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@



class OrderedGraph(nx.Graph):
class OrderedGraph(nx.MultiGraph):
node_dict_factory = OrderedDict
adjlist_dict_factory = OrderedDict

Expand Down Expand Up @@ -109,8 +109,8 @@ def __get__(self,obj,cls):
return graph

def __set__(self,obj,val):
if not isinstance(val, nx.Graph):
raise AttributeError("val must be an nx.Graph")
if not isinstance(val, OrderedGraph):
raise AttributeError("val must be an OrderedGraph")
else:
self.values[obj] = val

Expand Down
Loading

0 comments on commit 532676a

Please sign in to comment.