所以我得到了这个代码。如果电压超出限制,我希望它执行到 pq 的切换,如果电压在下一次迭代的限制内,则切换回 pv。最近某处出现错误。我希望它每次迭代只切换一次总线,当它这样做时,它会更新总线的指定值,而不是该迭代中用于计算的值。
这是我创建开关的类文件
class Bus:
idx:int
u:complex
i_inj: complex
bus_type: int #define 0 slack, 1 pv, 2 pq
#y: complex # ?
p: float
q: float
q_min: float
q_max: float
def __init__(self, idx, bus_type, voltage_mag, voltage_ang, p, q, q_min, q_max):
self.idx = idx
self.bus_type = bus_type
self.u=complex(voltage_mag*np.cos(voltage_ang),voltage_mag*np.sin(voltage_ang))
self.voltage_mag = voltage_mag
self.voltage_ang = voltage_ang
self.p = p
self.q = q
#self.y=y # maybe
self.q_min = q_min
self.q_max = q_max
def set_to_pv(self): # , voltage_mag, active_power
#self.voltage_mag = voltage_mag
self.bus_type = 1
#self.p = active_power # Changed from "active_power" to p
print("Bus switched to PV")
def set_to_pq(self): # , active_power, reactive_power
self.bus_type = 2
#self.p = active_power # Changed from "active_power" to p
#self.q = reactive_power # Changed from "reactive power" to q
print("Bus switched to PQ")
def switch_pq (self):
if self.bus_type!=2:
if self.q < self.q_min:
self.q = self.q_min
self.set_to_pq() # Added self first
print("Reactive power inside limits, switch to pq")
return 1
elif self.q > self.q_max:
self.q = self.q_max
self.set_to_pq()
print("Reactive power outside limits, switch to pq")
return 1
else:
return 0
def switch_back(self):
if self.q_min <= self.q <= self.q <= self.q_max:
if self.bus_type == 2:
self.set_to_pv() # Added self, changed from "active_power" to p
print("Bus switched to PV")
return 1
else:
return 0
这是执行牛顿拉夫森的代码
import numpy as np
from Classes import *
from Ybus import *
from Jacobian import *
from DCLF import *
from FDLF import *
def main(e_lim, method: str, filename="BusData.txt"):
if e_lim<=0:
print("e_lim<=0")
return
if method=='DCPF' or method=='DCLF':
dcpf()
return
data=read_file(filename) # data = list [list of buses, list of lines]
buses=data[0]
lines=data[1]
ybus=Build_Ybus(buses, lines)
b1=fdlf_b(ybus, buses)[0]
b2=fdlf_b(ybus, buses)[1]
# initial guess:
for bus in buses:
if bus.bus_type==2:
bus.voltage_mag=1
bus.voltage_ang=0
elif bus.bus_type==1:
#bus.u.imag=0
bus.voltage_ang=0
'''
#check for q limit viol. + type switching
for bus in buses:
bus.switch_pq()
'''
error=e_lim+1
it=0
while error>e_lim and it<2:
print(f"reached loop, iteration {it+1}")
print(f"Error={error}")
# Calculate powers/mismatch
mism=calc_power_mismatch(ybus, buses)
p_mismatch=mism[0]
q_mismatch=mism[1]
#merge mismatches and change to column vector (not needed with matmul)
#du_row=np.concatenate((p_mismatch, q_mismatch))
#du=np.transpose(np.atleast_2d(du_row))
du=np.concatenate((p_mismatch, q_mismatch))
print('du', du)
if method=='FDLF':
dx=fdlf_dx(b1, b2, buses, p_mismatch, q_mismatch)
else:
# Calculate jacobian
jacobian=jacobian_matrix(ybus, buses, method)
print('\nJACOBIAN inv:\n', np.linalg.inv(jacobian))
print('du', du)
# Solve for dx
dx=np.matmul(np.linalg.inv(jacobian), du)
# Update states
#voltage and angle indexes
u_i=[]
angle_i=[]
for i in range(len(buses)):
if buses[i].bus_type==2:
u_i.append(i)
angle_i.append(i)
if buses[i].bus_type==1:
angle_i.append(i)
n_d=len(angle_i)
# TESTING:
print('DX', dx)
print('\nBus voltages before:')
for bus in buses:
print(bus.voltage_mag, bus.voltage_ang)
for i in range(len(angle_i)):
buses[angle_i[i]].voltage_ang+=dx[i]
for i in range(len(u_i)):
buses[u_i[i]].voltage_mag+=dx[n_d+i]
#this should update the values of u and d that have changed (that is, the unknowns)
print('Bus voltages after update:')
for bus in buses:
print(bus.voltage_mag, bus.voltage_ang)
print('\n')
# check for q limit viol. + type switching (before next iteration)
for bus in buses:
#bus.switch_pq()
if bus.switch_pq(): #will the values of the bus be changed this way?
bus.switch_back()
error=max(du) # calculate error (largest of mismatches)
it+=1
return
main(0.01, "NR", "BusData.txt")
这是总线数据文件
# Bus Data
# BusID, Type, VoltageMag, VoltageAng, ActivePower, ReactivePower, q_min, q_max, n9
1, 1, 1.0, 0.0, 1.0, 0.0, 0.27, 0.33
2, 2, 1.0, 0.0, 0.6, 0.3, 100, 101
3, 1, 1.0, 0.0, 0.0, 0.0, 0.27, 0.33
4, 2, 1.0, 0.0, 0.6, 0.2, 100, 101
5, 2, 1.0, 0.0, 0.5, 0.4, 100, 101
# Line Data
# Line, StartBus, EndBus, ImpedanceR, ImpedanceX, Capacitance, n7
1, 0, 1, 0.05, 0.25, 0.05
2, 1, 2, 0.05, 0.25, 0.05
3, 0, 3, 0.02, 0.2, 0.033333
4, 1, 3, 0.02, 0.2, 0.033333
5, 3, 4, 0.01, 0.1, 0.02
我还有多个其他文件,但我认为它们不受类型切换的影响。
问题有点不清楚,但我相信问题是这样的:
在
switch_back
函数中 if self.q_min <= self.q <= self.q <= self.q_max
似乎是错误的。这应该是 if self.q_min <= self.q <= self.q_max
。
此外,在主逻辑循环中,您需要确保每次迭代每个总线仅切换一次。您可以为此使用标志。
for bus in buses:
if bus.switch_pq(): # Only if a switch occurs to PQ
bus.switch_back()