-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathnetwork_class.py
202 lines (143 loc) · 5.68 KB
/
network_class.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
"""
Author: Joel Rieger
October 29, 2016
Description: Classes and functions to perform basic network abstraction and plotting
"""
from numpy import pi as pi
class network(object):
"""Class for one dimension network (i.e. a matching network)."""
element_array=[]
def __init__(self):
self.ZP2=lambda freq: 50.0 #Network termination on output
self.ZP1=lambda freq: 50.0 #Network termination on output
def compute_node_impedances(self,freq):
"""Calculate impedances at each node walking back from the output impedance, Zp2"""
Zarr=[self.ZP2(freq)]
for elem in self.element_array:
if elem.orientation==0: #series
Zarr.append(Zarr[-1]+elem.Z(freq))
elif elem.orientation==1: #shunt
Zarr.append(1.0/(1.0/Zarr[-1]+elem.Y(freq)))
#Zarr.reverse()
return Zarr
def print_net(self):
for elem in self.element_array:
print elem.name, elem.val
def move_element(self,n_a,n_b):
"""
Moves element to new index shifting other elements accordingly.
Simplies drag-drop action of components
"""
self.element_array.insert(n_b,self.element_array.pop(n_a))
class element(object):
"""Class for a single impedance/admittance element (i.e. capacitor, indcutor, etc.)."""
def __init__(self,*args,**kargs):
self.name=''
self.icon=''
self.orientation=0
self.default=''
if kargs.has_key('shunt'):
self.orientation=kargs['shunt'] # 0: Series, 1:Shunt
self.val={}
self.Zfunc=lambda self,x: 1e-14 #function to define series impedance
self.Yfunc=lambda self,x: 1e14 #function to define admittance
# def __setval__(self,val):
# self.val=val
def Z(self,freq):
return self.Zfunc(self,freq)
def Y(self,freq):
return self.Yfunc(self,freq)
def set_val(self,val,**kargs):
self.val[self.default]=val
#Populate self.val with kargs dictionary at later date
class cap(element):
"""Modification of element class to model an ideal capacitor"""
def __init__(self,*args,**kargs):
element.__init__(self,*args,**kargs)
self.name='cap'
self.default='C'
if 'min' in kargs:
self.val['min']=kargs['min']
else:
self.val['min']=1e-12
if 'max' in kargs:
self.val['max']=kargs['max']
else:
self.val['max']=12.1e-12
if 'step' in kargs:
self.val['step']=kargs['step']
else:
self.val['step']=0.1e-12
self.val['unit']='pF' #Unit not used to scale value variable
if len(args)!=1:
print "ERROR: cap(element) requires 1 argument"
else:
self.val[self.default]=args[0]
#self.Zfunc=lambda self,freq: 1j/(2*pi*freq*self.val['C']) #function to define series impedance
self.Yfunc=lambda self,freq: (1j*2*pi*freq*self.val['C']) #function to define admittance
self.Zfunc=lambda self,freq: 1.0/self.Yfunc(self,freq)
class ind(element):
"""Modification of element class to model an ideal capacitor"""
def __init__(self,*args,**kargs):
element.__init__(self,*args,**kargs)
self.name='ind'
self.default='L'
if 'min' in kargs:
self.val['min']=kargs['min']
else:
self.val['min']=1e-9
if 'max' in kargs:
self.val['max']=kargs['max']
else:
self.val['max']=12.1e-9
if 'step' in kargs:
self.val['step']=kargs['step']
else:
self.val['step']=0.1e-9
self.val['unit']='nH' #Unit not used to scale value variable
if len(args)!=1:
print "ERROR: ind(element) requires 1 argument"
else:
self.val['L']=args[0]
self.Zfunc=lambda self,freq: 1j*2*pi*freq*self.val['L'] #function to define series impedance
self.Yfunc=lambda self,freq: 1.0/self.Zfunc(self,freq)
class indQ(element):
"""Modification of element class to model an capacitor with a fixed Q"""
def __init__(self,*args,**kargs):
element.__init__(self)
self.name='indQ'
if len(args)!=2:
print "ERROR: indQ(element) requires 2 arguments"
else:
self.val['L']=args[0]
self.val['Q']=args[1]
#function to define series impedance
self.Zfunc=lambda self,freq: 2*pi*freq*self.val['L']/self.val['Q']+1j*2*pi*freq*self.val['L']
#function to define admittance
self.Yfunc=lambda self,freq: 1.0j/self.Zfunc(self,x)
class capQ(element):
"""Modification of element class to model an capacitor with a fixed L"""
def __init__(self,*args,**kargs):
element.__init__(self)
self.name='capQ'
if len(args)!=2:
print "ERROR: capQ(element) requires 2 arguments"
else:
self.val['C']=args[0]
self.val['Q']=args[1]
#function to define series impedance
self.Zfunc=lambda self,freq: (1.0/(2*pi*freq*self.val['C']))/self.val['Q']+1.0j/(2*pi*freq*self.val['C'])
#function to define admittance
self.Yfunc=lambda self,freq: 1.0/self.Zfunc(self,x)
if __name__=='__main__':
net=network()
#TEST CASE -- matching 50.0 Ohms to ~5.0 Ohms at 2 GHz
L1=ind(0.75e-9)
C1=cap(6.3e-12,shunt=1)
L2=ind(2.0e-9)
C2=cap(1.6e-12,shunt=1)
net.element_array.append(C2)
net.element_array.append(L2)
net.element_array.append(C1)
net.element_array.append(L1)
print net.compute_node_impedances(2.0e9)