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 Diode: | |
""" Diode class. Contains functions to initiliaze | |
the diode according to name tag, unique cell position, | |
update system matrix on each iteration. """ | |
def __init__(self, diode_index, diode_pos, diode_tag): | |
""" Constructor to initialize value. | |
Also, takes in the identifiers - | |
index (serial number), cell position and tag. """ | |
self.type="Diode" | |
self.number=diode_index | |
self.pos=diode_pos | |
self.tag=diode_tag | |
self.has_voltage="yes" | |
self.diode_level=120.0 | |
self.current=0.0 | |
self.voltage=0.0 | |
self.polrty=[-1, -1] | |
self.resistor_on=0.01 | |
self.status="off" | |
def display(self): | |
print "Diode is ", | |
print self.tag, | |
print " located at ", | |
print self.pos, | |
print " with cathode polarity towards %s" %(csv_element(self.polrty)) | |
return | |
def ask_values(self, x_list, ckt_mat, sys_branch): | |
""" Writes the values needed to the spreadsheet.""" | |
diode_params=["Diode"] | |
diode_params.append(self.tag) | |
diode_params.append(self.pos) | |
diode_params.append("Voltage level (V) = %f" %self.diode_level) | |
if self.polrty==[-1, -1]: | |
# Looking for a default value of polarity | |
# in the neighbouring cells | |
self.diode_elem=csv_tuple(self.pos) | |
if self.diode_elem[0]>0: | |
if ckt_mat[self.diode_elem[0]-1][self.diode_elem[1]]: | |
self.polrty=[self.diode_elem[0]-1, self.diode_elem[1]] | |
if self.diode_elem[1]>0: | |
if ckt_mat[self.diode_elem[0]][self.diode_elem[1]-1]: | |
self.polrty=[self.diode_elem[0], self.diode_elem[1]-1] | |
if self.diode_elem[0]<len(ckt_mat)-1: | |
if ckt_mat[self.diode_elem[0]+1][self.diode_elem[1]]: | |
self.polrty=[self.diode_elem[0]+1, self.diode_elem[1]] | |
if self.diode_elem[1]<len(ckt_mat)-1: | |
if ckt_mat[self.diode_elem[0]][self.diode_elem[1]+1]: | |
self.polrty=[self.diode_elem[0], self.diode_elem[1]+1] | |
else: | |
for c1 in range(len(sys_branch)): | |
if csv_tuple(self.pos) in sys_branch[c1]: | |
if not self.polrty in sys_branch[c1]: | |
print "!"*50 | |
print "ERROR!!! Diode polarity should be in the same branch as the diode. Check diode at %s" %self.pos | |
print "!"*50 | |
diode_params.append("Cathode polarity towards (cell) = %s" %csv_element(self.polrty)) | |
x_list.append(diode_params) | |
return | |
def get_values(self, x_list, ckt_mat): | |
""" Takes the parameter from the spreadsheet.""" | |
self.diode_level=float(x_list[0].split("=")[1]) | |
# Choosing 1 micro Amp as the leakage current that | |
# is drawn by the diode in off state. | |
self.resistor_off=self.diode_level/1.0e-6 | |
self.resistor=self.resistor_off | |
diode_polrty=x_list[1].split("=")[1] | |
# Convert the human readable form of cell | |
# to [row, column] form | |
while diode_polrty[0]==" ": | |
diode_polrty=diode_polrty[1:] | |
self.polrty=csv_tuple(diode_polrty) | |
if not ckt_mat[self.polrty[0]][self.polrty[1]]: | |
print "Polarity incorrect. Branch does not exist at %s" %csv_element(self.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 of the diode.""" | |
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.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] | |
# If the positive polarity appears before the voltage position | |
# it means as per KVL, we are moving from +ve to -ve | |
# and so the voltage will be taken negative | |
if sys_loops[c1][c1][c2].index(self.polrty)>sys_loops[c1][c1][c2].index(csv_tuple(self.pos)): | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
mat_b.data[c1][source_list.index(self.pos)]=-1.0 | |
else: | |
mat_b.data[c1][source_list.index(self.pos)]=1.0 | |
else: | |
if sys_loops[c1][c1][c2][-1]=="forward": | |
mat_b.data[c1][source_list.index(self.pos)]=1.0 | |
else: | |
mat_b.data[c1][source_list.index(self.pos)]=-1.0 | |
return | |
def transfer_to_branch(self, sys_branch, source_list): | |
""" Update the resistor info of the diode | |
to the branch list """ | |
if csv_tuple(self.pos) in sys_branch: | |
sys_branch[-1][0][0]+=self.resistor | |
if csv_tuple(self.pos) in sys_branch: | |
if sys_branch.index(self.polrty)>sys_branch.index(csv_tuple(self.pos)): | |
sys_branch[-1][1][source_list.index(self.pos)]=-1.0 | |
else: | |
sys_branch[-1][1][source_list.index(self.pos)]=1.0 | |
return | |
def generate_val(self, source_lst, sys_loops, mat_e, mat_a, mat_b, mat_u, t, dt): | |
""" The diode forward drop voltage is updated | |
in the matrix u in E.dx/dt=Ax+Bu .""" | |
if self.status=="on": | |
mat_u.data[source_lst.index(self.pos)][0]=0.7 | |
else: | |
mat_u.data[source_lst.index(self.pos)][0]=0.0 | |
return | |
def update_val(self, sys_loops, lbyr_ratio, mat_e, mat_a, mat_b, state_vec, mat_u, sys_branches, sys_events): | |
""" This function calculates the actual current in the | |
diode branch. With this, the branch voltage is found | |
with respect to the existing diode resistance. The diode | |
voltage is then used to decide the turn on condition. """ | |
# 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.pos) in sys_loops[c1][c1][c2]: | |
# If diode cathode polarity is after the diode | |
# position, the current is positive. | |
if sys_loops[c1][c1][c2].index(self.polrty)>sys_loops[c1][c1][c2].index(csv_tuple(self.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] | |
self.current=act_current | |
self.voltage=self.current*self.resistor | |
for c1 in range(len(sys_branches)): | |
if csv_tuple(self.pos) in sys_branches[c1]: | |
branch_pos=c1 | |
if self.status=="off" and self.voltage>0.9: | |
sys_events[branch_pos]="yes" | |
self.status="on" | |
if self.status=="on" and self.current<-1.0e-5: | |
sys_events[branch_pos]="yes" | |
self.status="off" | |
if self.current<-1.0e-5: | |
self.status="off" | |
if self.status=="off": | |
self.resistor=self.resistor_off | |
else: | |
self.resistor=self.resistor_on | |
return |
The diode resistance changes with the status whether "ON" or "OFF". The diode is ON when it is forward biased beyond a certain threshold voltage. It turns "OFF" when current becomes negative. The ON resistance, forward bias threshold voltage and the ON drop voltage can be made user defined parameters.
No comments:
Post a Comment