Commit 190160a0 authored by Markus Mirz's avatar Markus Mirz
Browse files

Merge branch 'mmo' into 'master'

Mmo

See merge request acs/core/simulation/state-estimation!6
parents b89cdb18 ca56b5a9
import numpy as np
import math
from network import Ymatrix_calc
from network import BusType
def Ymatrix_calc(system):
nodes_num = len(system.nodes)
branches_num = len(system.branches)
Ymatrix = np.zeros((nodes_num, nodes_num),dtype=np.complex)
Adjacencies = [[] for _ in range(nodes_num)]
for index in range(branches_num):
fr = system.branches[index].start_node.index
to = system.branches[index].end_node.index
Ymatrix[fr][to] -= system.branches[index].y
Ymatrix[to][fr] -= system.branches[index].y
Ymatrix[fr][fr] += system.branches[index].y
Ymatrix[to][to] += system.branches[index].y
Adjacencies[fr].append(to+1)
Adjacencies[to].append(fr+1)
return Ymatrix, Adjacencies
class Results():
def __init__(self):
self.V = []
self.I = []
self.Iinj = []
self.S1 = []
self.S2 = []
self.SInj = []
self.num_iter = []
def solve(system):
"""It performs Power Flow by using rectangular node voltage state variables."""
......@@ -132,4 +128,56 @@ def solve(system):
S1=np.append(S1, V[system.branches[i].start_node.index]*(I_conj[i]))
S2=np.append(S2, -V[system.branches[i].end_node.index]*(I_conj[i]))
return V, I, Iinj, S1, S2, Sinj, num_iter
\ No newline at end of file
return V, I, Iinj, S1, S2, Sinj, num_iter
def calculateI(network, V):
"""
To calculate the branch currents
"""
I = np.zeros((len(system.branches)), dtype=np.complex)
for idx in range(branches_num):
fr = system.branches[idx].start_node.index
to = system.branches[idx].end_node.index
I[idx] = - (V[fr] - V[to])*Ymatrix[fr][to]
def calculateInj(network, I):
"""
To calculate current injections at a node
"""
Iinj = np.zeros((len(system.nodes)), dtype=np.complex)
for k in range(0, (len(system.nodes))):
to=[]
fr=[]
for m in range(len(system.branches)):
if k==system.branches[m].start_node.index:
fr.append(m)
if k==system.branches[m].end_node.index:
to.append(m)
Iinj = np.sum(I[to]) - np.sum(I[fr])
return Iinj
def calculateS1(system, V, I):
"""
To calculate powerflow on branches
"""
S1 = np.zeros((len(system.branches)), dtype=np.complex)
for i in range(0, len(system.branches)):
S1 = np.append(S1, V[system.branches[i].start_node.index]*(np.conj(I[i])))
return S1
def calculateS2():
"""
To calculate powerflow on branches
"""
S2 = np.zeros((len(system.branches)), dtype=np.complex)
for i in range(0, len(system.branches)):
S2 = np.append(S2, -V[system.branches[i].end_node.index]*(I_conj[i]))
return S2
def calculateSinj(V, Iinj):
"""
To calculate power injection at a node
"""
Sinj = np.multiply(V, np.conj(Iinj))
return Sinj
\ No newline at end of file
import sys
import math
import numpy as np
from network import Ymatrix_calc
from network import BusType
sys.path.append("../../../dataprocessing")
from dpsim_reader import read_data
class PF_Results():
def __init__(self):
self.V = []
self.I = []
self.Iinj = []
self.S1 = []
self.S2 = []
self.SInj = []
self.num_iter = 0
def read_data(self, file_name, system):
"""
To read the voltages from a input file
"""
loadflow_results = read_data(loadflow_results_file)
#order readed data according to system.nodes
self.V = np.zeros(len(loadflow_results), dtype=np.complex_)
for elem in range(len(system.nodes)):
self.V[elem] = loadflow_results[system.nodes[elem].uuid]
def solve(system):
"""It performs Power Flow by using rectangular node voltage state variables."""
Ymatrix, Adj = Ymatrix_calc(system)
nodes_num = len(system.nodes)
branches_num = len(system.branches)
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
type = system.nodes[i].type
if type is BusType.SLACK:
z[m] = np.real(system.nodes[i].voltage)
z[m+1] = np.imag(system.nodes[i].voltage)
H[m][i] = 1
H[m+1][i2] = 1
elif type is BusType.PQ:
H[m][i] = - np.real(Ymatrix[i][i])
H[m][i2] = np.imag(Ymatrix[i][i])
H[m+1][i] = - np.imag(Ymatrix[i][i])
H[m+1][i2] = - np.real(Ymatrix[i][i])
idx1 = np.subtract(Adj[i],1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(Ymatrix[i][idx1])
H[m][idx2] = np.imag(Ymatrix[i][idx1])
H[m+1][idx1] = - np.imag(Ymatrix[i][idx1])
H[m+1][idx2] = - np.real(Ymatrix[i][idx1])
elif type is BusType.PV:
z[m+1] = np.real(system.nodes[i].power)
H[m][i] = - np.real(Ymatrix[i][i])
H[m][i2] = np.imag(Ymatrix[i][i])
idx1 = np.subtract(Adj[i],1)
idx2 = idx1 + nodes_num
H[m][idx1] = - np.real(Ymatrix[i][idx1])
H[m][idx2] = np.imag(Ymatrix[i][idx1])
epsilon = 10**(-10)
diff = 5
V = np.ones(nodes_num) + 1j* np.zeros(nodes_num)
num_iter = 0
State = np.ones(2*branches_num)
State = np.concatenate((np.array([1,0]),State),axis=0)
while diff > epsilon:
for i in range(0, nodes_num):
m = 2*i
i2 = i + nodes_num
type = system.nodes[i].type
if type is BusType.SLACK:
h[m] = np.inner(H[m],State)
h[m+1] = np.inner(H[m+1],State)
elif type is BusType.PQ:
z[m] = (np.real(system.nodes[i].power)*V[i].real + np.imag(system.nodes[i].power)*V[i].imag)/(np.abs(V[i])**2)
z[m+1] = (np.real(system.nodes[i].power)*V[i].imag - np.imag(system.nodes[i].power)*V[i].real)/(np.abs(V[i])**2)
h[m] = np.inner(H[m],State)
h[m+1] = np.inner(H[m+1],State)
elif type is BusType.PV:
z[m] = (np.real(system.nodes[i].power)*V[i].real + np.imag(system.nodes[i].power)*V[i].imag)/(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)
Delta_State = np.inner(Hinv,r)
State = State + Delta_State
diff = np.amax(np.absolute(Delta_State))
V = State[:nodes_num] + 1j * State[nodes_num:]
num_iter = num_iter+1
return V, num_iter
def calculateI(system, V):
"""
To calculate the branch currents
"""
Ymatrix, Adj = Ymatrix_calc(system)
I = np.zeros((len(system.branches)), dtype=np.complex)
for idx in range(len(system.branches)):
fr = system.branches[idx].start_node.index
to = system.branches[idx].end_node.index
I[idx] = - (V[fr] - V[to])*Ymatrix[fr][to]
return I
def calculateInj(system, I):
"""
To calculate current injections at a node
"""
Iinj = np.zeros((len(system.nodes)), dtype=np.complex)
for k in range(0, (len(system.nodes))):
to=[]
fr=[]
for m in range(len(system.branches)):
if k==system.branches[m].start_node.index:
fr.append(m)
if k==system.branches[m].end_node.index:
to.append(m)
Iinj[k] = np.sum(I[to]) - np.sum(I[fr])
return Iinj
def calculateS1(system, V, I):
"""
To calculate powerflow on branches
"""
S1 = np.zeros((len(system.branches)), dtype=np.complex)
for i in range(0, len(system.branches)):
S1[i] = V[system.branches[i].start_node.index]*(np.conj(I[i]))
return S1
def calculateS2(system, V, I):
"""
To calculate powerflow on branches
"""
S2 = np.zeros((len(system.branches)), dtype=np.complex)
for i in range(0, len(system.branches)):
S2[i] = -V[system.branches[i].end_node.index]*(np.conj(I[i]))
return S2
def calculateSinj(V, Iinj):
"""
To calculate power injection at a node
"""
Sinj = np.multiply(V, np.conj(Iinj))
return Sinj
\ No newline at end of file
......@@ -5,14 +5,15 @@ import copy
import logging
import matplotlib.pyplot as plt
sys.path.append("../../cimpy")
sys.path.append("../../../cimpy")
import cimpy
sys.path.append("./acs/state_estimation")
import network
import nv_powerflow_cim
from measurement_generator import *
from dpsim_reader import * # TODO replace with functions from villas.dataprocessing
sys.path.append("../../../dataprocessing")
from villas.dataprocessing.readtools import *
import nv_state_estimator_cim
logging.basicConfig(filename='CIGRE.log', level=logging.INFO)
......@@ -33,12 +34,13 @@ system = network.System()
system.load_cim_data(res)
Ymatr, Adj = network.Ymatrix_calc(system)
loadflow_results = read_data(loadflow_results_file)
#read Input-Ergebnisdatei
ts_dpsim = read_timeseries_csv(loadflow_results_file)
#order readed data according to system.nodes
Vtrue=np.zeros(len(loadflow_results), dtype=np.complex_)
Vtrue=np.zeros(len(ts_dpsim), dtype=np.complex_)
for elem in range(len(system.nodes)):
Vtrue[elem] = loadflow_results[system.nodes[elem].uuid]
Vtrue[elem] = ts_dpsim[system.nodes[elem].uuid].values[0]
""" Write here the indexes of the nodes/branches where the measurements are"""
V_idx = np.array([])
......
def read_data(file_name):
file = []
with open(file_name, "r") as filestream:
for line in filestream:
file.append([x.strip() for x in line.split(',')])
#remove "time"
file[0].pop(0)
file[1].pop(0)
results={}
for elem in range(len(file[0])):
node, type = file[0][elem].split('.')
if not node in results:
results[node] = 0.0 + 0.0j
if type=="real":
results[node] += float(file[1][elem])
elif type=="imag":
results[node] += complex(0,float(file[1][elem]))
return results
\ No newline at end of file
Supports Markdown
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