Sunday, January 12, 2014

Releasing version 0.2.4

Releasing the next version with those minor changes.

http://sourceforge.net/projects/pythonpowerelec/

Global variables for control code

So far, the only data that are being plotted in the output file are the values measured by the meters. But when writing control code, the user would need to plot control variables to debug the control code. Also, in the case when there are multiple control blocks and some may be cascaded - that is the output of one is the input of the other, this can't be done in the present form as the inputs are only from meters.

To solve these two shortcomings, I thought of creating another category of variables called "VariableStorage". From the name, the primary use of these are to tag certain variables in the control code as variables that can be plotted. Also, these are global variables for all the control code - this means one such global variable defined for one control code can be used anywhere. So the output of one can be used as the input of another.

But, the creation of such global variables is a major threat because some stupid statement somewhere in some control code could be resetting a variable to an arbitrary value. Not sure what protection I need to incorporate to prevent random usage. For now this is that I will do. (click on "view raw" below the code box to see the code in another window):





Thursday, January 9, 2014

Events and simulation time step - continued

A solution to the problem of running certain control algorithms at a faster rate than the simulation is to create a time event list. The closest time event will be the next simulation time instant. This will result in a variable time-step solver and am not sure how this will affect the future network analysis. The user simulation time step therefore becomes the maximum allowable time step. The code is as follows (click on "view raw" below the code box to see the code in a new window):



In the control function, one of the last statements updates the time event vector with the time events in the individual control code. So, __control.py will look like this (click on "view raw" below the code box to see the code in a new window):


The last statement appends the time event t1 to the sys_t_events list. In case they were multiple time events, all of them would be appended to the list.

Wednesday, January 8, 2014

Events and simulation time step

There is a serious flaw in the way I handle simulation time steps. So far there are only two time events - the simulation time step that is decided by the user and the control time step that is decided by the user in the control file. However, it is assumed that the control time step will be larger than the simulation time step which is completely wrong.

For example, the controller of the buck converter will update the duty cycle once every switching cycle. But the comparison between the duty cycle and the carriers sawtooth waveform has to take place much faster - actually at least 9 times faster than the carrier frequency to get the crossover points accurately.

For now a simple way to resolve this would be to include two time events in the control code. However, at a later stage, the pulse width modulator would have to made into another block where the time step would default to a value appropriate with the switching frequency.

In general, the control philosophy will change. Instead of having the controllers as functions, it might be better to have them as objects. This would enable inputs and outputs to be connected together and also control signals will need to be measured to debug errors.

Sunday, January 5, 2014

Releasing version 0.2.3

And with the changes made, releasing the next version of the circuit simulator.

http://sourceforge.net/projects/pythonpowerelec/

Not sure if this will work in every case. So that will be the next step, to test this for all the different types of power electronic converters. Will keep updating this blog as and how new findings are made.

As before, feel free to email me at pythonpowerelectronics@gmail.com if you have any questions.

Solving ODEs

This was an error I am surprised I was even able to locate to the solver because I thought it was something related to the circuit solver. So far, the ODE is solved as an entire state vector at a time. This means, all states are calculated together and when one state needs the information of another state it used the previous value of the state. So even if a more updated value of a state is available, with this method the previous value is used.

This actually defeats the purpose of solving ODEs in a backward manner. That is we solve from the last state to the first state since the matrices have been made upper triangular.

So, the ODE was changed such that a particular state is calculated completely, its value is updated and this updated value is available for the next state to be calculated.

Here is the code (click on "view raw" below the code box to view the code in another window):


Simplifying loop manipulation

Initially, all the code was written with respect to system loops. Also, when manipulating loops either for removing stiffness or for any other reason, the loops themselves were manipulated. And this means the entire loop information, including the branch elements. All this only adds to overhead. Particularly since two other elements have been defined - branch_params which contains information of the branch - the elements, the resistance, inductance, voltages, and current. The other element is the system_loop_map which contains information of which branch exists in each loop.

So why not get rid of system_loops in further manipulations? All that is needed to be done is to extend the definition of system_loop_map. Before system_loop_map had only "stiff", "yes" and "no" as entries. Now it will have:

forward - branch is in the direction of loop
reverse - branch is against loop direction
stiff_forward - stiff branch but same direction
stiff_reverse - stiff branch but opposite direction

With this the entire information of the loop is contained in a far more compact manner. And all the functions were rewritten. For example, the remove_stiffness function is as follows (click on "view raw" below the code box to see the code in another window):



And the resultant code is much cleaner, the loop manipulations much easier. This will also change the code in the circuit elements (click on "view raw" below the code box to see the code in another window):



Diode freewheeling - continued

There were a couple of fatal flaws in the previous code. When I expand the circuit to a buck converter with two diodes connected in parallel as shown below, it doesn't work.

So essentially there are two freewheeling paths. In the previous algorithms, I had considered as current sources:
1. Inductors
2. Voltage sources without any resistance and inductance
3. Branches without any resistance and inductance and also no voltage - short branches or wires.

The 3rd point was wrong. A wire will carry any current and to fix the current through it will be wrong. For now, I think my assumption of a voltage source with zero impedance as a current source is acceptable because the sources should continue supplying what they were during an event to check which branches can change their status.

So, to include the third point, I came up with the concept of shortnode. A supernode will be a node having a zero impedance branch with a voltage. On the other hand, a short node is a node that has a zero impedance branch with no voltage - or a node with a "wire" connected to it. The significance of a short node will be that a "wire" will have two short nodes at the same voltage and in this manner, nodes connected through wires will end up as a group of short nodes. Similar to supernodes, a circuit could have many groups of short nodes. The only difference between a super node and a short node is that when performing KCL, is a node is encountered that is a short node, only the voltage of the first node in that group of short nodes will be included.

To expand on this. If there is a group of four short nodes. All these short nodes are connected by "wires" and so they are at the same voltage. So when performing KCL only one node voltage needs to be included. The reason is that there can be a large number of short nodes and therefore, to write separate equations V1-V2=0 will increase the number of equations well beyond the number of nodes, messing up the KCL.

Once this is done, the KCL is performed. All the node voltages are calculated and all the branch currents too. Except for the short branches or "wires". There is no way to calculate the current through them by the above method as they do not have a resistance. So, for this another KCL is written. The code for this is completely new and so is below (click on "view raw" below the code box to view the code in another window):



After this change, the code now works for the circuit shown above.