Monday, April 22, 2013

Capacitor class

Been a long time since I updated the blog.

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):


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
print "!"*50
print "ERROR!!! Capacitor polarity should be in the same branch as the capacitor. Check source at %s" %self.cap_pos
print "!"*50
print
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
view raw capacitor.py hosted with ❤ by GitHub

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