Friday, August 22, 2014

Voltage measurement

Have been working furiously on modifying the simulator for larger circuits. But found there is a fatal error in voltage measurement. Take a look at the test circuit for a three-phase diode rectifier.

The voltmeter is modelled as a large resistance which does not disturb the current in the remaining circuit. The problem is that the branch containing the voltmeter is a stiff branch that appears in the loop equations. These equations appear randomly. So in the above circuit, when the simulation begins, suppose diodes D1 and D6 conduct. This means voltage vac appears across the capacitor Cdc and the voltmeter Vo. What would need to happen is that the voltmeter loop should be written with Cdc and therefore as Cdc charges, Vo output voltage should increase. But what is Vo appears in the loop with vac, D1 and D6? This is perfectly possible the way the program works now. This means Vo will jump to the voltage vac even though Cdc is charging gradually.

So Vo does not reflect the voltage that appears across the nodes but rather on the voltage impressed on it through the loop it appears on. And this inevitably happens whenever the circuit becomes large and loop equations become more and more random. Also, if the voltmeter were connected across a largely inductive circuit or for that matter over two fairly distant nodes in the circuit. What then?

The only error free way to solve this seems to be to do a nodal analysis with only the voltmeters for the nodes where they exist. This calls for a fairly large additional piece of code that will run at simulation time step.

Monday, July 21, 2014

Revised nodal analysis

When must nodal analysis take place?
  1. When there are inductors with sufficient energy and that energy might be abruptly interrupted.
  2. When does an inductor have sufficient energy? When it has been in at least one non stiff loop in the previous iteration. This way, the circuit is power independent.
The code is below (click on "view raw" below the code box to see the code in a new window):

The process is as follows:

  1. In the beginning, a new branch event is assumed by default whenever a branch event occurs.
  2. Look if there are any inductors that have previously been in non stiff loops.
  3. If so, nodal analysis is required.
  4. Following nodal analysis, check if there is a continuity event with branch currents from nodal analysis being different from the branch currents from previous iteration of loop analysis.
  5. If so, execute the determine_state function to check if any of the elements will change their state. If any of the elements do change state, the respective branches will have branch events.
  6. Check if there are any branch events that had not occurred in the previous iteration. If so, go back to step 2.
  7. This will repeat until no new branch events occur.

In nodal analysis, there has been one significant change. In order to perform nodal analysis, it is essential to calculate the node voltages. So the entire circuit has to be solved. However, the branch currents will be calculated only if:
  1. At a node, check if there has been an branch which has a "hard" event.
  2. A hard event is when a switch turns on or when it turns off while carrying a non negligible current. When a switch or a diode turns off when the current goes negative, that is a soft event. When a diode turns on when it is forward biased, it is a soft event.
  3. If a single branch incident at a node has a "hard" event, the currents of all the branches incident at the node will have to calculated. If not, the branch currents remain at their initial values - either zero or a current it is an inductor.
The code is below (click on "view raw" below the code box to see the code in a new window):

There has been another tag created called function_purpose. When determining state, function purpose will only calculate branch currents at nodes where there has been a "hard" event. But while calculating currents before the next loop analysis, all branch currents will be recalculated.

Determining switch and diode state

The code for determining switch state is below (click on "view raw" below the code box to view the code in a new window):

The code for the determining diode state is below (click on "view raw" below the code box to view the code in a new window):

This function is called after performing nodal analysis to check if the inductor current has caused an non linear device to change state. The difference between the code for switch and diode is that a switch can only turn off during nodal analysis while a diode can both turn on and turn off. My guess is that the switch should turn on only in the update_value function. If for some reason, the switch were to turn off during the nodal analysis because the current through it was negative due to an inductor, the switch remains off and only a diode can turn on to freewheel the current.

The reason for doing this will be the next detailed blog post.

Stiff loop evaluation

Been a long time since I have posted. One of the reasons has been that I have made change after change in the solver. With every change, the circuit that I am working on gets fixed but a previously tested one breaks. Even now I am not totally sure until I test them all. But I will start posting code anyway.

To begin with, the stiff loop evaluation. The concept until now has been:
  1. Sort out the loops into stiff loops and non-stiff loops.
  2. With stiff loops, there are those loops that were non-stiff until the previous iteration and became stiff. So these will have a non-negligible current because a diode may have turned off causing the current to be slightly negative.
  3. So the currents of these stiff loops will have to be re-evaluated to brought back to values that correspond to their being stiff sloops with large resistances. A failure to do so will cause these loops to disrupt the calculation of the other stiff loops.
  4. Simple way to do this is to have another function. The code is below.

This is the function that calls the stiff equation solver which has not changed from before (click "view raw" link below the code box to see code in a new window):

There is a bit of guessing here as well. Out of "n" loops, let us suppose "m" loops (m<n) have turned stiff in the previous iteration. The remove_stiffness function makes the stiff loops into a upper triangular matrix with the first stiff branch of every stiff loop being present only in that loop. However, as the number of stiff branches can be larger than the number of stiff loops, the last few stiff branches may appear in multiple loops. As an example, take a look at these loops:

stiff_forward no no no no no no stiff_reverse reverse reverse no no reverse no reverse reverse no reverse
no stiff_forward no no no no no stiff_forward forward forward no no forward no forward forward no forward
no no stiff_forward no no no no stiff_reverse no reverse no no no reverse reverse reverse reverse no
no no no stiff_reverse no no no stiff_reverse no reverse no no no reverse reverse reverse reverse no
no no no no stiff_reverse no no stiff_reverse no no forward forward no no reverse reverse no reverse
no no no no no stiff_reverse no stiff_forward no no reverse reverse no no forward forward no forward
no no no no no no stiff_reverse stiff_reverse no no no no no no no no no no

All the loops are stiff and the 8th branch appears in all the stiff loops. And for all you know, this 8th branch could be the branch that became recently stiff. So there is a possibility that these newly formed loops could disrupt the calculation of other new formed loops. So thus there is the initialization of newly formed stiff loop currents to zero.

The current of a stiff loop is decided only by the voltage in that loop and the resistance of that loop. The loop has no dynamics di/dt. So repeatedly calculating the loops will not change the loop currents unless the currents of one of the other stiff loops has changed. Which is why if the newly formed stiff loops are recalculated a number of times (thrice for now), the values should stabilize. In any case without a di/dt, they should not blow up out of bounds.

Following this, when it comes to calculating loop currents from branches, there were two parts to that function. The code is below (click "view raw" link below the code box to see code in a new window):

As can be seen, the entire block of code that would compute currents of stiff loops has been commented out. The reason is that if the currents of stiff loops are being calculated from the stiff equation solver, there is no need to repeat the process. On the contrary repeating the process has the capacity to disrupt the loop current values.

Wednesday, June 25, 2014


Been a long time since I posted. Have been busy with building my hardware setup for my research and now they are almost working the way I want. With this done, I now will have to divert some of my time towards this project.

Spent the past week or so reading most of the code all over again. Another task has been portability to Python 3. Have to look into compatibility issues with respect to that. But before that to complete a tested power electronics library.

One of the problems with combining mesh analysis and nodal analysis was that if both are performed whenever an event occurs, freewheeling can be said to occur even when it is not meant to occur. For example, in a three-phase diode bridge rectifier fed by a source with a finite inductance, the turning off of a diode can be seen as cause for freewheeling of the inductor current and causing the other diode in the leg to freewheel.

So, my guess is there comes the need to distinguish between nonlinear element events -  a hard switched event or a soft switched event. A soft switched event is when a device (diode or switch) turns off when the current through it becomes negative. In that case, freewheeling should not happen. However, when a switch is turned off, and the current through it (irrespective of the magnitude) is broken, freewheeling needs to occur if there was an inductor in a branch connected to the node.

That is the immediate next step.

Tuesday, April 22, 2014

Hardware setup

Been a while since I posted about the simulator. Have been crazy busy with my day job but am happy to announce, that my microgrid setup is finally ready!

Inverter and control board with sensors and microcontroller:

Intelligent power module with dc bus capacitors:

Hopefully I will be able to work on the simulator again before my trip to Japan.

Saturday, April 5, 2014

Initializing new stiff equations

Another problem that arises when there are a large number of nonlinear devices is that nonstiff loops become stiff loops but their current has still not become negligible because the diode has turned off at the previous iteration. For example, current through a diode is -0.1A causing the diode to turn off and it's resistance to change to megaohms. When this stiff loops interacts with other stiff loops and the currents of those stiff loops are calculated, all other stiff loops end up having currents of close magnitudes of 0.1 A. Result: entire simulation is disrupted.

Two things need to be done:
1. Need to identify which loops have just become stiff.
2. Calculate those stiff loops before running the ode solver.

The code to identify the newly formed stiff loops is:

And running the stiff loop ode:

One other thing still needs to be done. What if the newly formed stiff loops themselves are interacting with each other through a stiff branch? Now even this ode solver would fail because they would disrupt each other. The only thing to do would be do perform an upper triangularization of the newly formed stiff loops with respect to the newly formed stiff branches and solve them backwards. Will do this later.