forked from CURENT/andes
-
Notifications
You must be signed in to change notification settings - Fork 2
/
breaker.py
127 lines (109 loc) · 4.08 KB
/
breaker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import logging
from cvxopt import matrix # NOQA
from cvxopt import mul # NOQA
from .base import ModelBase
from ..utils.math import neg
logger = logging.getLogger(__name__)
class Breaker(ModelBase):
"""Simple line breaker model"""
def __init__(self, system, name):
super(Breaker, self).__init__(system, name)
self._group = 'Relay'
self._name = 'Breaker'
self._data.update({
'bus': None,
'line': None,
't1': 0.0,
't2': 0.0,
't3': 0.0,
't4': 0.0,
'u1': False,
'u2': False,
'u3': False,
'u4': False,
'fn': 60.0,
})
self._params.extend(['t1', 't2', 't3', 't4', 'u1', 'u2', 'u3', 'u4'])
self._descr.update({
'bus': 'Bus idx',
'line': 'Line idx',
't1': 'Time of the 1st switch',
't2': 'Time of the 2nd switch',
't3': 'Time of the 3rd switch',
't4': 'Time of the 4th switch',
'u1': 'Apply the 1st switch',
'u2': 'Apply the 2nd switch',
'u3': 'Apply the 3rd switch',
'u4': 'Apply the 4th switch',
'fn': 'rated frequency',
})
self._units.update({
't1': 's',
't2': 's',
't3': 's',
't4': 's',
'u1': 'boolean',
'u2': 'boolean',
'u3': 'boolean',
'u4': 'boolean',
})
self._mandatory.extend(['bus', 'line'])
self._service.extend(['times', 'time'])
self.param_remove('Sn')
self._init()
def setup(self):
super(Breaker, self).setup()
self.copy_data_ext('Line', 'bus1', dest='bus1', idx=self.line)
self.copy_data_ext('Line', 'bus2', dest='bus2', idx=self.line)
# check if `self.bus` is connected to `self.line`
for i in range(self.n):
if self.bus[i] not in (self.bus1[i], self.bus2[i]):
logger.warning(
'<Breaker> {} on line {} and bus {} is incorrect '
'and is thus disabled.'.
format(self.idx[i], self.line[i], self.bus[i]))
self.u[i] = 0
def get_times(self):
"""Return all the action times and times-1e-6 in a list"""
if not self.n:
return []
self.times = list(mul(self.u1, self.t1)) + \
list(mul(self.u2, self.t2)) + \
list(mul(self.u3, self.t3)) + \
list(mul(self.u4, self.t4))
self.times = matrix(list(set(self.times)))
self.times = list(self.times) + list(self.times - 1e-6)
return self.times
def is_time(self, t):
if not self.n:
return
return t in self.times
def apply(self, actual_time):
if self.time != actual_time:
self.time = actual_time
else:
return
n_applied = 0
for i in range(self.n):
tn = matrix([self.t1[i], self.t2[i], self.t3[i], self.t4[i]])
tn = mul(self.u[i], tn)
if actual_time in tn:
line_int = self.system.Line.uid[self.line[i]]
u0 = self.system.Line.u[line_int]
self.system.Line.switch(self.line[i], neg(u0))
if u0 == 1:
info = ' Breaker <{}>: Line <{}> disconnected at t = {}.'.format(self.idx[i], self.line[i],
actual_time)
n_applied += 1
elif u0 == 0:
info = ' Breaker <{}>: Line <{}> reconnected at t = {}.'.format(self.idx[i], self.line[i],
actual_time)
n_applied += 1
logger.info(info)
if n_applied > 0:
self.system.check_islands(show_info=True)
def insert(self, idx=None, name=None, **kwargs):
if self.n:
self._param_to_list()
self.elem_add(idx, name, **kwargs)
self._param_to_matrix()