Been a while since I released a version, so I am going to release it soon. Also, the next step will be to move on to version 0.2.0 which will look at structural changes to the code that will bring in error messages and directions of usage.
Anyway, 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 Current_Source: | |
""" Current source class. Contains functions to initiliaze | |
the resistor according to name tag, unique cell position, | |
update system matrix on each iteration. """ | |
def __init__(self, cs_index, cs_pos, cs_tag): | |
""" Constructor to initialize value. | |
Also, takes in the identifiers - | |
index (serial number), cell position and tag. """ | |
self.type="CurrentSource" | |
self.cs_number=cs_index | |
self.cs_pos=cs_pos | |
self.cs_tag=cs_tag | |
self.cs_peak=5.0 | |
self.cs_freq=60.0 | |
self.cs_phase=0.0 | |
self.cs_level=120.0 | |
self.resistor=1.0 | |
self.current=0.0 | |
self.voltage=0.0 | |
self.op_value=0.0 | |
self.cs_polrty=[-1, -1] | |
def display(self): | |
print "Current Source is ", | |
print self.cs_tag, | |
print "of %f A (peak), %f Hz(frequency) and %f (degrees phase shift)" %(self.cs_peak, self.cs_freq, self.cs_phase), | |
print " located at ", | |
print self.cs_pos, | |
print " with positive polarity towards %s" %(csv_element(self.cs_polrty)) | |
return | |
def ask_values(self, x_list, ckt_mat, sys_branch): | |
""" Writes the values needed to the spreadsheet.""" | |
cs_params=["CurrentSource"] | |
cs_params.append(self.cs_tag) | |
cs_params.append(self.cs_pos) | |
cs_params.append("Peak (Amps) = %f" %self.cs_peak) | |
cs_params.append("Frequency (Hertz) = %f" %self.cs_freq) | |
cs_params.append("Phase (degrees) = %f" %self.cs_phase) | |
if self.cs_polrty==[-1, -1]: | |
# Looking for a default value of polarity | |
# in the neighbouring cells | |
self.cs_elem=csv_tuple(self.cs_pos) | |
if self.cs_elem[0]>0: | |
if ckt_mat[self.cs_elem[0]-1][self.cs_elem[1]]: | |
self.cs_polrty=[self.cs_elem[0]-1, self.cs_elem[1]] | |
if self.cs_elem[1]>0: | |
if ckt_mat[self.cs_elem[0]][self.cs_elem[1]-1]: | |
self.cs_polrty=[self.cs_elem[0], self.cs_elem[1]-1] | |
if self.cs_elem[0]<len(ckt_mat)-1: | |
if ckt_mat[self.cs_elem[0]+1][self.cs_elem[1]]: | |
self.cs_polrty=[self.cs_elem[0]+1, self.cs_elem[1]] | |
if self.cs_elem[1]<len(ckt_mat)-1: | |
if ckt_mat[self.cs_elem[0]][self.cs_elem[1]+1]: | |
self.cs_polrty=[self.cs_elem[0], self.cs_elem[1]+1] | |
else: | |
for c1 in range(len(sys_branch)): | |
if csv_tuple(self.cs_pos) in sys_branch[c1]: | |
if not self.cs_polrty in sys_branch[c1]: | |
print "!"*50 | |
print "ERROR!!! Current source polarity should be in the same branch as the current source. Check source at %s" %self.cs_pos | |
print "!"*50 | |
cs_params.append("Positive polarity towards (cell) = %s" %csv_element(self.cs_polrty)) | |
x_list.append(cs_params) | |
return | |
def get_values(self, x_list, ckt_mat): | |
""" Takes the parameter from the spreadsheet.""" | |
self.cs_peak=float(x_list[0].split("=")[1]) | |
self.cs_freq=float(x_list[1].split("=")[1]) | |
self.cs_phase=float(x_list[2].split("=")[1]) | |
curr_polrty=x_list[3].split("=")[1] | |
# Convert the human readable form of cell | |
# to [row, column] form | |
while curr_polrty[0]==" ": | |
curr_polrty=curr_polrty[1:] | |
self.cs_polrty=csv_tuple(curr_polrty) | |
if not ckt_mat[self.cs_polrty[0]][self.cs_polrty[1]]: | |
print "Polarity incorrect. Branch does not exist at %s" %csv_element(self.cs_polrty) | |
return | |
def transfer_to_sys(self, sys_loops, mat_e, mat_a, mat_b, mat_u, source_list): | |
""" The matrix A in E.dx/dt=Ax+Bu will be updated by the | |
resistor value.""" | |
for c1 in range(len(sys_loops)): | |
for c2 in range(c1, len(sys_loops)): | |
# Updating the elements depending | |
# on the sense of the loops (aiding or opposing) | |
for c3 in range(len(sys_loops[c1][c2])): | |
# Check if current source position is there in the loop. | |
if csv_tuple(self.cs_pos) in sys_loops[c1][c2][c3]: | |
# Add current source series resistor | |
# if branch is in forward direction | |
if sys_loops[c1][c2][c3][-1]=="forward": | |
mat_a.data[c1][c2]+=self.resistor | |
else: | |
# Else subtract if branch is in reverse direction | |
mat_a.data[c1][c2]-=self.resistor | |
# Because the matrices are symmetric | |
mat_a.data[c2][c1]=mat_a.data[c1][c2] | |
return | |
def transfer_to_branch(self, sys_branch, source_list): | |
""" Update the resistor info of the voltmeter | |
to the branch list """ | |
if csv_tuple(self.cs_pos) in sys_branch: | |
sys_branch[-1][0][0]+=self.resistor | |
if csv_tuple(self.cs_pos) in sys_branch: | |
if sys_branch.index(self.cs_polrty)<sys_branch.index(csv_tuple(self.cs_pos)): | |
sys_branch[-1][1][source_list.index(self.cs_pos)]=-1.0 | |
else: | |
sys_branch[-1][1][source_list.index(self.cs_pos)]=1.0 | |
return | |
def generate_val(self, source_lst, sys_loops, mat_e, mat_a, mat_b, mat_u, state_vec, t, dt): | |
""" The source current is updated in the matrix u in | |
E.dx/dt=Ax+Bu. The matrix E has a row set to zero. The | |
matrix B has the diagonal element in the row set to 1, | |
others set to zero.""" | |
# Updating the current source value | |
self.current=self.cs_peak*math.sin(2*math.pi*self.cs_freq*t+self.cs_phase) | |
# The value passed to the input matrix is | |
# the voltage calculated | |
mat_u.data[source_lst.index(self.cs_pos)][0]=self.voltage | |
# The output value of the source will the current | |
# even though it is actually modelled as a | |
# voltage source with a series resistance. | |
self.op_value=self.current | |
return | |
def update_val(self, sys_loops, lbyr_ratio, mat_e, mat_a, mat_b, state_vec, mat_u): | |
""" This function calculates the actual current in | |
the current source branch. With this, the branch voltage is | |
found with respect to the existing voltage source. The branch | |
voltage is then used to calculate the new voltage source value. """ | |
# Local variable to calculate the branch | |
# current from all loops that contain | |
# the current source branch. | |
act_current=0.0 | |
for c1 in range(len(sys_loops)): | |
for c2 in range(len(sys_loops[c1][c1])): | |
if csv_tuple(self.cs_pos) in sys_loops[c1][c1][c2]: | |
# If current source polarity is before the source | |
# position, it means actual current is negative. | |
if sys_loops[c1][c1][c2].index(self.cs_polrty)<sys_loops[c1][c1][c2].index(csv_tuple(self.cs_pos)): | |
# Then check is the loop is aiding or opposing | |
# the main loop. | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
act_current+=state_vec.data[c1][0] | |
else: | |
act_current-=state_vec.data[c1][0] | |
else: | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
act_current-=state_vec.data[c1][0] | |
else: | |
act_current+=state_vec.data[c1][0] | |
# The branch voltage is the KVL with the | |
# existing voltage source and the branch current | |
branch_voltage=self.voltage+act_current*self.resistor | |
# The new source voltage will be the branch voltage | |
# in addition to the desired value of current. | |
self.voltage=branch_voltage+self.current*self.resistor | |
return |
No comments:
Post a Comment