To add another element to the library - the capacitor. Anyway, the code is just an extension/combination of the voltmeter/voltage source classes. Here is the code (click on "view raw" below the code box to see it in a new window):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Capacitor: | |
""" Capacitor class. Contains functions to initiliaze | |
the resistor according to name tag, unique cell position, | |
update system matrix on each iteration. """ | |
def __init__(self, cap_index, cap_pos, cap_tag): | |
""" Constructor to initialize value. | |
Also, takes in the identifiers - | |
index (serial number), cell position and tag. """ | |
self.type="Capacitor" | |
self.cap_number=cap_index | |
self.cap_pos=cap_pos | |
self.cap_tag=cap_tag | |
self.capacitor=10.0e-6 | |
self.current=0.0 | |
self.voltage=0.0 | |
self.v_dbydt=0.0 | |
self.cap_polrty=[-1, -1] | |
def display(self): | |
""" Displays info about the component.""" | |
print "Capacitor is ", | |
print self.cap_tag, | |
print "= %f" %self.capacitor, | |
print " located at ", | |
print self.cap_pos, | |
print " with positive polarity towards %s" %(csv_element(self.cap_polrty)) | |
def ask_values(self, x_list, ckt_mat, sys_branch): | |
""" Writes the values needed to the spreadsheet.""" | |
cap_params=["Capacitor"] | |
cap_params.append(self.cap_tag) | |
cap_params.append(self.cap_pos) | |
cap_params.append(self.capacitor) | |
if self.cap_polrty==[-1, -1]: | |
# Looking for a default value of polarity | |
# in the neighbouring cells | |
self.cap_elem=csv_tuple(self.cap_pos) | |
if self.cap_elem[0]>0: | |
if ckt_mat[self.cap_elem[0]-1][self.cap_elem[1]]: | |
self.cap_polrty=[self.cap_elem[0]-1, self.cap_elem[1]] | |
if self.cap_elem[1]>0: | |
if ckt_mat[self.cap_elem[0]][self.cap_elem[1]-1]: | |
self.cap_polrty=[self.cap_elem[0], self.cap_elem[1]-1] | |
if self.cap_elem[0]<len(ckt_mat)-1: | |
if ckt_mat[self.cap_elem[0]+1][self.cap_elem[1]]: | |
self.cap_polrty=[self.cap_elem[0]+1, self.cap_elem[1]] | |
if self.cap_elem[1]<len(ckt_mat)-1: | |
if ckt_mat[self.cap_elem[0]][self.cap_elem[1]+1]: | |
self.cap_polrty=[self.cap_elem[0], self.cap_elem[1]+1] | |
else: | |
for c1 in range(len(sys_branch)): | |
if csv_tuple(self.cap_pos) in sys_branch[c1]: | |
if not self.cap_polrty in sys_branch[c1]: | |
print "!"*50 | |
print "ERROR!!! Capacitor polarity should be in the same branch as the capacitor. Check source at %s" %self.cap_pos | |
print "!"*50 | |
cap_params.append("Positive polarity towards (cell) = %s" %csv_element(self.cap_polrty)) | |
x_list.append(cap_params) | |
def get_values(self, x_list, ckt_mat): | |
""" Takes the parameter from the spreadsheet.""" | |
self.capacitor=float(x_list[0]) | |
cap_polrty=x_list[1].split("=")[1] | |
# Convert the human readable form of cell | |
# to [row, column] form | |
while cap_polrty[0]==" ": | |
cap_polrty=cap_polrty[1:] | |
self.cap_polrty=csv_tuple(cap_polrty) | |
if not ckt_mat[self.cap_polrty[0]][self.cap_polrty[1]]: | |
print "Polarity incorrect or changed. Branch does not exist at %s" %csv_element(self.cap_polrty) | |
def transfer_to_sys(self, sys_loops, mat_e, mat_a, mat_b, mat_u, source_list): | |
""" The matrix B in E.dx/dt=Ax+Bu will be updated by the | |
polarity of the capacitor.""" | |
for c1 in range(len(sys_loops)): | |
for c2 in range(len(sys_loops[c1][c1])): | |
if csv_tuple(self.cap_pos) in sys_loops[c1][c1][c2]: | |
# If the positive polarity appears before the capacitor position | |
# it means as per KVL, we are moving from +ve to -ve | |
# and so the capacitor voltage will be taken negative | |
if sys_loops[c1][c1][c2].index(self.cap_polrty)<sys_loops[c1][c1][c2].index(csv_tuple(self.cap_pos)): | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
mat_b.data[c1][source_list.index(self.cap_pos)]=-1.0 | |
else: | |
mat_b.data[c1][source_list.index(self.cap_pos)]=1.0 | |
else: | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
mat_b.data[c1][source_list.index(self.cap_pos)]=1.0 | |
else: | |
mat_b.data[c1][source_list.index(self.cap_pos)]=-1.0 | |
return | |
def transfer_to_branch(self, sys_branch, source_list): | |
""" Transfers parameters to system branch if capacitor | |
exists in the branch. """ | |
if csv_tuple(self.cap_pos) in sys_branch: | |
if sys_branch.index(self.cap_polrty)<sys_branch.index(csv_tuple(self.cap_pos)): | |
sys_branch[-1][1][source_list.index(self.cap_pos)]=-1.0 | |
else: | |
sys_branch[-1][1][source_list.index(self.cap_pos)]=1.0 | |
return | |
def generate_val(self, source_lst, sys_loops, mat_u, t, dt): | |
""" The capacitor voltage is updated in the matrix u in | |
E.dx/dt=Ax+Bu .""" | |
self.v_dbydt=self.current/self.capacitor | |
self.voltage+=self.v_dbydt*dt | |
mat_u.data[source_lst.index(self.cap_pos)][0]=self.voltage | |
self.op_value=self.voltage | |
def update_val(self, sys_loops, lbyr_ratio, mat_e, mat_a, mat_b, state_vec, mat_u): | |
""" The capacitor current is calculated as a result of the KVL.""" | |
self.current=0.0 | |
for c1 in range(len(sys_loops)): | |
for c2 in range(len(sys_loops[c1][c1])): | |
if csv_tuple(self.cap_pos) in sys_loops[c1][c1][c2]: | |
# If capacitor polarity is before the capacitor | |
# position, it means current is positive. | |
if sys_loops[c1][c1][c2].index(self.cap_polrty)<sys_loops[c1][c1][c2].index(csv_tuple(self.cap_pos)): | |
# Then check is the loop is aiding or opposing | |
# the main loop. | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
self.current+=state_vec.data[c1][0] | |
else: | |
self.current-=state_vec.data[c1][0] | |
else: | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
self.current-=state_vec.data[c1][0] | |
else: | |
self.current+=state_vec.data[c1][0] | |
return |
I'll release another version after completing the current source class which I hope will be in a few days.
For the current source class, my guess it would be best to exclude it from the branch list so that it doesn't appear in any of the loops. For every current source a simple nodal equation can then be added.
No comments:
Post a Comment