Commit 24368b4e authored by martin.moraga's avatar martin.moraga
Browse files

improve class switches in netwtork.py

parent 99a19093
......@@ -13,7 +13,7 @@ class BusType(Enum):
class Node():
def __init__(self, uuid='', name='', base_voltage=1.0, base_apparent_power=1.0, v_mag=0.0,
v_phase=0.0, p=0.0, q=0.0, index=0, bus_type='PQ', pu=False):
v_phase=0.0, p=0.0, q=0.0, index=0, bus_type='PQ', pu=False, ideal_connected_with=''):
self.uuid = uuid
self.name = name
self.index = index
......@@ -25,6 +25,7 @@ class Node():
self.power = complex(p, q)
self.power_pu = complex(p, q) / self.base_apparent_power
self.voltage_pu = self.voltage / self.baseVoltage
self.ideal_connected_with = ideal_connected_with
def __str__(self):
str = 'class=Node\n'
......@@ -62,19 +63,15 @@ class Branch():
class Breaker():
def __init__(self, node_load, node_breaker, branch_connected_with_node_breaker, connected=True):
def __init__(self, from_node, to_node, is_open=True):
"""
:param node_load: node which is connected with pq loads
:param node_breaker:
:param branch_connected_with_node_breaker: ACLineSegment which is connected with node_breaker
:param connected: True if the breaker is considered closed and False if the broker is open
:param from_node:
:param to_node:
:param is_open: True if the breaker is considered open and False if the broker is closed
"""
#node_breaker and node_load are used when the breaker is open
#only node_breaker is used when the breaker is closed
self.node_breaker = node_breaker
self.node_load = node_load
self.branch_connected_with_node_breaker = branch_connected_with_node_breaker
self.connected = connected
self.from_node = from_node
self.to_node = to_node
self.is_open = is_open
def __str__(self):
str = 'class=Breaker\n'
......@@ -83,44 +80,14 @@ class Breaker():
str = str + key + '={}\n'.format(attributes[key])
return str
def open_breaker(self, system):
self.connected == False
node_breaker_uuid = self.node_breaker.uuid
#check if node_breaker_uuid is in system.nodes
is_node_in_list = system.get_node_by_uuid(node_breaker_uuid)
#add node_breaker to list system.nodes
if not is_node_in_list:
system.nodes.append(self.node_breaker)
#connect branch_connected_with_node_breaker with node_load
if (self.branch_connected_with_node_breaker.start_node.uuid==self.node_load.uuid):
self.branch_connected_with_node_breaker.start_node = self.node_breaker
elif (self.branch_connected_with_node_breaker.end_node.uuid==self.node_load.uuid):
self.branch_connected_with_node_breaker.end_node = self.node_breaker
def open_breaker(self):
self.is_open == False
self.to_node.ideal_connected_with = ''
#reenumerate nodes
system.reindex_nodes_list()
def close_breaker(self, system):
self.connected == True
def close_breaker(self):
self.is_open == False
self.to_node.ideal_connected_with = self.from_node.uuid
#remove node_breaker from list system.nodes
node_breaker_uuid = self.node_breaker.uuid
node_to_remove = system.get_node_by_uuid(node_breaker_uuid)
if node_to_remove:
system.nodes.remove(node_to_remove)
#connect branch_connected_with_node_breaker with node_load
if (self.branch_connected_with_node_breaker.start_node.uuid==self.node_breaker.uuid):
self.branch_connected_with_node_breaker.start_node = self.node_load
elif (self.branch_connected_with_node_breaker.end_node.uuid==self.node_breaker.uuid):
self.branch_connected_with_node_breaker.end_node = self.node_load
#reenumerate nodes
system.reindex_nodes_list()
class System():
def __init__(self):
......@@ -134,11 +101,14 @@ class System():
for node in self.nodes:
print('{} {}'.format(node.name, node.index))
def print_branchs_names(self):
for branch in self.branches:
print('{} {}'.format(branch.start_node.name, branch.start_node.index))
print('{} {}'.format(branch.end_node.name, branch.end_node.index))
def print_node_types(self):
for node in self.nodes:
print('{} {}'.format(node.name, node.type))
def print_power(self):
for node in self.nodes:
print('{} {}'.format(node.name, node.power))
def get_node_by_uuid(self, node_uuid):
for node in self.nodes:
if node.uuid == node_uuid:
......@@ -146,11 +116,29 @@ class System():
return False
def get_nodes_num(self):
"""
return the number of nodes in the list system.nodes
"""
nodes_num=0
for node in self.nodes:
if node.ideal_connected_with == '':
nodes_num+=1
return nodes_num
def reindex_nodes_list(self):
index = 0
remaining_nodes_list = []
for node in self.nodes:
node.index=index
index+=1
if node.ideal_connected_with == '':
node.index=index
index+=1
else:
remaining_nodes_list.append(node)
for node in remaining_nodes_list:
node.index = self.get_node_by_uuid(node.ideal_connected_with)
def load_cim_data(self, res, base_apparent_power):
"""
......@@ -194,7 +182,7 @@ class System():
self._setNodeType(list_Terminals)
#create branches ACLineSegment
#create branches type ACLineSegment
for ACLineSegment in list_ACLineSegment:
uuid_ACLineSegment = ACLineSegment.mRID
nodes = self._get_nodes(list_Terminals, uuid_ACLineSegment)
......@@ -206,7 +194,7 @@ class System():
start_node=start_node, end_node=end_node,
base_voltage=base_voltage, base_apparent_power=base_apparent_power))
#create branches power transformer
#create branches type powerTransformer
for power_transformer in list_PowerTransformer:
uuid_power_transformer = power_transformer.mRID
nodes = self._get_nodes(list_Terminals, uuid_power_transformer)
......@@ -220,37 +208,16 @@ class System():
start_node=start_node, end_node=end_node, base_voltage=base_voltage,
base_apparent_power=base_apparent_power))
#create breakers
for obj_Breaker in list_Breakers:
connected = not(obj_Breaker.normalOpen)
is_open = obj_Breaker.normalOpen
nodes = self._get_nodes(list_Terminals, obj_Breaker.mRID)
#check which node has loads
if (nodes[0].power.real==0) and (nodes[0].power.imag == 0):
node_breaker = nodes[0]
node_load = nodes[1]
elif (nodes[1].power.real==0) and (nodes[1].power.imag == 0):
node_breaker = nodes[0]
node_load = nodes[1]
#search for branch_connected_with_node_breaker
branch_connected_with_node_breaker=None
for branch in self.branches:
if branch.start_node.uuid == node_breaker.uuid:
branch_connected_with_node_breaker = branch
break
if branch.end_node.uuid == node_breaker.uuid:
branch_connected_with_node_breaker = branch
break
self.breakers.append(Breaker(node_breaker=node_breaker, node_load=node_load,
connected=connected,
branch_connected_with_node_breaker=branch_connected_with_node_breaker))
self.breakers.append(Breaker(from_node=nodes[0], to_node=nodes[0], is_open=is_open))
#if the breaker.connected == closed --> close broker
if connected == False:
#if the breaker is open == closed --> close broker
if is_open == False:
self.breakers[-1].close_breaker(self)
elif connected==True:
self.breakers[-1].open_breaker(self)
#calculate admitance matrix
self.Ymatrix_calc()
......@@ -345,7 +312,8 @@ class System():
node.type = BusType["PV"]
def Ymatrix_calc(self):
nodes_num = len(self.nodes)
self.reindex_nodes_list()
nodes_num = self.get_nodes_num()
self.Ymatrix = np.zeros((nodes_num, nodes_num), dtype=np.complex)
self.Adjacencies = [[] for _ in range(nodes_num)]
for branch in self.branches:
......
......@@ -23,43 +23,44 @@ def solve(system):
V: same as state but with complex numbers (i.e. [V0_re+j*V0_im, V1_re+j*V1_im, ...])
"""
nodes_num = len(system.nodes)
branches_num = len(system.branches)
nodes_num = system.get_nodes_num()
z = np.zeros(2 * nodes_num)
h = np.zeros(2 * nodes_num)
H = np.zeros((2 * nodes_num, 2 * nodes_num))
for i in range(0, nodes_num):
m = 2 * i
i2 = i + nodes_num
node_type = system.nodes[i].type
if node_type == BusType.SLACK:
z[m] = np.real(system.nodes[i].voltage_pu)
z[m + 1] = np.imag(system.nodes[i].voltage_pu)
H[m][i] = 1
H[m + 1][i2] = 1
elif node_type is BusType.PQ:
H[m][i] = - np.real(system.Ymatrix[i][i])
H[m][i2] = np.imag(system.Ymatrix[i][i])
H[m + 1][i] = - np.imag(system.Ymatrix[i][i])
H[m + 1][i2] = - np.real(system.Ymatrix[i][i])
idx1 = np.subtract(system.Adjacencies[i], 1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(system.Ymatrix[i][idx1])
H[m][idx2] = np.imag(system.Ymatrix[i][idx1])
H[m + 1][idx1] = - np.imag(system.Ymatrix[i][idx1])
H[m + 1][idx2] = - np.real(system.Ymatrix[i][idx1])
elif node_type is BusType.PV:
z[m + 1] = np.real(system.nodes[i].power)
H[m][i] = - np.real(system.Ymatrix[i][i])
H[m][i2] = np.imag(system.Ymatrix[i][i])
idx1 = np.subtract(system.Adjacencies[i], 1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(system.Ymatrix[i][idx1])
H[m][idx2] = np.imag(system.Ymatrix[i][idx1])
for node in system.nodes:
if node.ideal_connected_with =='':
i = node.index
m = 2 * i
i2 = i + nodes_num
node_type = node.type
if node_type == BusType.SLACK:
z[m] = np.real(node.voltage_pu)
z[m + 1] = np.imag(node.voltage_pu)
H[m][i] = 1
H[m + 1][i2] = 1
elif node_type is BusType.PQ:
H[m][i] = - np.real(system.Ymatrix[i][i])
H[m][i2] = np.imag(system.Ymatrix[i][i])
H[m + 1][i] = - np.imag(system.Ymatrix[i][i])
H[m + 1][i2] = - np.real(system.Ymatrix[i][i])
idx1 = np.subtract(system.Adjacencies[i], 1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(system.Ymatrix[i][idx1])
H[m][idx2] = np.imag(system.Ymatrix[i][idx1])
H[m + 1][idx1] = - np.imag(system.Ymatrix[i][idx1])
H[m + 1][idx2] = - np.real(system.Ymatrix[i][idx1])
elif node_type is BusType.PV:
z[m + 1] = np.real(node.power)
H[m][i] = - np.real(system.Ymatrix[i][i])
H[m][i2] = np.imag(system.Ymatrix[i][i])
idx1 = np.subtract(system.Adjacencies[i], 1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(system.Ymatrix[i][idx1])
H[m][idx2] = np.imag(system.Ymatrix[i][idx1])
epsilon = 10 ** (-10)
#epsilon = 0.001
diff = 5
V = np.ones(nodes_num) + 1j * np.zeros(nodes_num)
num_iter = 0
......@@ -67,27 +68,29 @@ def solve(system):
state = np.concatenate((np.ones(nodes_num), np.zeros(nodes_num)), axis=0)
while diff > epsilon:
for i in range(0, nodes_num):
m = 2 * i
i2 = i + nodes_num
node_type = system.nodes[i].type
if node_type is BusType.SLACK:
h[m] = np.inner(H[m], state)
h[m + 1] = np.inner(H[m + 1], state)
elif node_type is BusType.PQ:
z[m] = (np.real(system.nodes[i].power_pu) * np.real(V[i]) + np.imag(system.nodes[i].power_pu) * np.imag(
V[i])) / (np.abs(V[i]) ** 2)
z[m + 1] = (np.real(system.nodes[i].power_pu) * np.imag(V[i]) - np.imag(
system.nodes[i].power_pu) * np.real(V[i])) / (np.abs(V[i]) ** 2)
h[m] = np.inner(H[m], state)
h[m + 1] = np.inner(H[m + 1], state)
elif node_type is BusType.PV:
z[m] = (np.real(system.nodes[i].power_pu) * np.real(V[i]) + np.imag(system.nodes[i].power_pu) * np.imag(
V[i]))(np.abs(V[i]) ** 2)
h[m] = np.inner(H[m], state)
h[m + 1] = np.abs(V[i])
H[m + 1][i] = np.cos(np.angle(V[i]))
H[m + 1][i2] = np.sin(np.angle(V[i]))
for node in system.nodes:
if node.ideal_connected_with =='':
i = node.index
m = 2 * i
i2 = i + nodes_num
node_type = node.type
if node_type is BusType.SLACK:
h[m] = np.inner(H[m], state)
h[m + 1] = np.inner(H[m + 1], state)
elif node_type is BusType.PQ:
z[m] = (np.real(node.power_pu) * np.real(V[i]) +
np.imag(node.power_pu) * np.imag(V[i])) / (np.abs(V[i]) ** 2)
z[m + 1] = (np.real(node.power_pu) * np.imag(V[i]) -
np.imag(node.power_pu) * np.real(V[i])) / (np.abs(V[i]) ** 2)
h[m] = np.inner(H[m], state)
h[m + 1] = np.inner(H[m + 1], state)
elif node_type is BusType.PV:
z[m] = (np.real(node.power_pu) * np.real(V[i]) +
np.imag(node.power_pu) * np.imag(V[i]))(np.abs(V[i]) ** 2)
h[m] = np.inner(H[m], state)
h[m + 1] = np.abs(V[i])
H[m + 1][i] = np.cos(np.angle(V[i]))
H[m + 1][i2] = np.sin(np.angle(V[i]))
r = np.subtract(z, h)
Hinv = np.linalg.inv(H)
......
......@@ -32,7 +32,8 @@ class Results():
self.Ymatrix = system.Ymatrix
self.Adjacencies = system.Adjacencies
for node in system.nodes:
self.nodes.append(ResultsNode(topo_node=node))
if node.ideal_connected_with == '':
self.nodes.append(ResultsNode(topo_node=node))
for branch in system.branches:
self.branches.append(ResultsBranch(topo_branch=branch))
......@@ -63,7 +64,8 @@ class Results():
if node.topology_node.index == index:
node.voltage_pu = V[index]
node.voltage = node.voltage_pu * node.topology_node.baseVoltage
continue
def calculate_all(self):
"""
calculate all quantities of the grid
......@@ -209,7 +211,7 @@ class Results():
I[branch_idx] = self.branches[branch_idx].current_pu
elif pu == False:
for branch_idx in range(len(self.branches)):
I[branch_idx] = self.es[branch_idx].current
I[branch_idx] = self.branches[branch_idx].current
return I
......
......@@ -4,7 +4,6 @@ from acs.state_estimation import nv_powerflow
from acs.state_estimation import results
import cimpy
import os
import csv
from villas.dataprocessing.readtools import read_timeseries_dpsim
......@@ -34,9 +33,10 @@ results_pf, num_iter = nv_powerflow.solve(system)
# print node voltages
print("Powerflow converged in " + str(num_iter) + " iterations.\n")
#print("Results: \n")
#for node in results_pf.nodes:
# print('{}={}'.format(node.topology_node.uuid, node.voltage))
print("Results: \n")
for node in results_pf.nodes:
#print('{}={}'.format(node.topology_node.uuid, node.voltage_pu))
print('{}={}'.format(node.topology_node.uuid, node.voltage))
print("\n\n\n")
#load results of csv file:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment