Saturday, November 26, 2016

Nonstiff loops

There was an issue that I partly solved and didn't rigorously check before and this was related to how non-stiff loops are solved. Nonstiff loops are those loops that have only non-stiff branches and therefore these loop currents will be those that have non-negligible values. Their solution is therefore critical to the simulation stability and accuracy.

This is the problem. Let us suppose there are four branches in parallel. One of the branches is the load resistor and is therefore small in value. The others are parasitic resistances that may be significantly large. These parallel branches may be connected to a larger circuit with inductances. If loops are to be written having only one of these parallel branches but with the rest of the circuit, each branch will have a different time constant which is the sum total of the inductance of the loop divided by the sum total of the resistance. A loop can only be solved as a differential equation if the time constant of the loop is smaller than around ten times the simulation time step. Theoretically, by Nyquist's criterion this would be twice, but in practice we need a margin of ten. If the time constant if less than ten times the simulation time step, the equation should be converted to a static equation and the inductance should be ignored as solving this as a differential equation will cause instability.

Now when there are parallel branches with different resistances but none of these resistances are large enough for the branches to be considered stiff (like voltmeter branches), any of these branches can appear in loops with the external circuit. Loops are completely random and therefore it is possible that a nonstiff loop containing inductance is formulated with a branch with high resistance. Such a loop will be approximated to a static equation. If care is not taken in formulating the loops, it might so happen that none of these parallel branches will appear with the external circuit in a differential equation. This means that a dynamic of the circuit has disappeared.

To ensure this doesn't happen, we use the concept that any loop in a circuit must follow the path of least resistance. Also, we need to ensure that every branch appears in at least one loop. To do this, divide loops into two types - those with more than two branches and those with only two branches. For loops with more than two branches, these play an important part in linking a circuit together. These therefore capture the dynamics of a circuit. It is extremely important that as far as possible, they have a time constant that can be solved as a differential equation. It may be possible that this may not happen, time constant is too low and the equation is solved as a static equation. If this happens, it means it is a bad selection of parameters and simulation time step. But, to minimize this occurrence, go through every branch in these loops and check if the branch is one of parallel connected branches between nodes. If so, check if the branch has minimum resistance. If not, exchange the branch with the branch that has minimum resistance. By doing so, as far as possible, loops with more than two branches will always follow the path of least resistance and therefore will be solvable as differential equations.

For the loops with only two branches. These are loops between branches connected in parallel between two nodes. If a number of branches are connected in parallel, the branch with the minimum resistance should be found. All loops between the parallel branches should be so chosen that they are between this branch with minimum resistance and all other branches. The reason, this branch with minimum resistance will be present in loops which link the circuit together and described above and therefore will introduce their dynamics into the parallel connected branches.

Now, by arranging the loops according to their time constants, it can be ensured that the circuit is always stable and dynamics are always captured when possible.

Thursday, November 17, 2016

Python 3 compatibility

Last weekend I gave a ten minute talk in PyCon Canada 2016. As usual met some wonderful people and attended some interesting talks. The video will not be online for a few weeks.

As usual a lot of items on the agenda. The simplest is continue building for larger systems. The next is something I have been putting off for quite a while but think I should get down to pretty soon - compatibility with Python 3. So far the simulator used Python 2 but this is now legacy software. All Linux OS ship with Python 3 and even my IDE complains of syntax errors when there is nothing wrong with the syntax except that it looks for Python 3. Will need to read into the differences between Python 2 and 3 to make sure this transition is smooth.

The next thing is a little more complicated. I have been trying to speed the simulator up. One simple way to do so is to try to store as many of the loops and computations in a dictionary so that they can be looked up rather than calculated every time. The only question is what is the limit of this storage and will I ever run out of memory? I am assuming that a dictionary will be stored in the heap which is limited by the RAM which nowadays is good enough. If however, this dictionary gets stored in the stack, it would be a serious problem as the stack is limited and running out of memory is possible. I will need to look into some analytic tools that can tell me how my simulator is performing with respect to memory - which functions use the most?

As always, follow me on LinkedIn or my Facebook page for regular updates: