From: Soeren D. S. <soe...@gm...> - 2013-07-21 12:03:32
|
Am 21.07.2013 04:14, schrieb al davis: > On Thursday 18 July 2013, Soeren D. Schulze wrote: >> Thanks. I checked gnucap, which does the same thing, and if >> I can trust some random web articles, Spice does it, >> too. I haven't used Spice that much, but convergence seems >> to be a bit better there, which I now can't explain any >> more. > > Yes, that's the way they do it. > > Can you show me an example of a real working circuit that fails > to converge in gnucap? I know that some do not converge. I > want examples that I can study. Sorry, I meant to say that convergence in Spice is better than in Qucs. In gnucap, it's even better. A set of "benchmark examples" would be actually nice. I know a test set created by mathematicians (https://pitagora.dm.uniba.it/~testset/report/testset.pdf) which has a few electronic examples, but they solve the equations globally using standard integrators. For an academic example, take a differentiator: * Double differentiatior .generator freq=10k phase=90 V1 1 0 generator(1) C1 1 0 10u IC=1 H2 2 0 V1 1 C2 2 3 10u IC=0 V2 3 0 0 H3 4 0 V2 1 IC=0.31831 .print tran V(1) V(2) V(3) V(4) .option reltol=0.001 method=trap short=10u .tran 3u 1m uic .END It fails once you lower "short". Mathematically speaking, the "short" option makes a lot of sense because it lowers the index of the underlying differential-algebraic equation. To make things more difficult, add a third differentiator. If Qucs gets a gnucap back-end for transient analysis anyway, maybe it's better to implement improved algorithms in gnucap first? Are the goals of gnucap and Qucs compatible? Maybe it's even possible to merge them into one. >> This is a bit surprising to me. For my Bachelor's thesis, I >> had primarily looked at mathematical literature on this >> topic, and they all write down the equation globally and >> then apply some standard solver, avoiding the condition >> problem. > > That works great for the simplest of simple problems. For the > complex issues in circuit simulation there are other issues, > leading to a need for a more heuristic approach. What you are > talking about might have been state of the art about 1970, > before Spice. Again, both approaches are mathematically equivalent, but the approach that Spice (and gnucap and Qucs) uses is numerically at a disadvantage. Things like that haven't really been researched until the 80's and early 90's, so I doubt that Spice is state-of-the-art concerning the numerical integration algorithms. Applying "gmin" and "short" to every node and every voltage source is a very effective measure because it transforms the differential-algebraic equation into an ordinary differential equation. [Unless there is an inductor in the circuit. Then you need to add "short" as a series resistance to the inductor. But even without that, the worst thing you can get is an index-1 DAE, which is already much better than a higher-index DAE.] But of course "gmin" and "short" are modifications to the circuit. I think it would be possible to reduce the need for them by a better implementation of the algorithm. > As a challenge to you .... Here's a really simple circuit, with > some commands to analyze it. It should run in any simulator > that supports spice syntax. I am curious what other simulators > say, and how your algorithm would handle it. Gnucap gives a > correct result. NGspice and LTspice do not. > > The "*>" lines are gnucap post-processing commands. It > calculates the period, rise time, and fall time. > > * switch as negative resistance oscillator > SW1 1 0 1 0 SWITCH1 > C1 1 0 1n > I1 0 1 100u > .MODEL SWITCH1 SW VT=2.5 VH=2.475 RON=1 ROFF=10MEG > .print tran V(1) > *>.print tran + r(SW1) iter(0) timef(sw1) control(0) > *>.store tran v(1) > .option method=trap numdgt=9 > .tran 100e-6 200e-6 uic trace all > *>.measure t2=cross("v(1)" cross=2 fall last) > *>.measure t1=cross("v(1)" cross=2 fall last before=t2) > *>.measure t0=cross("v(1)" cross=2 fall last before=t1) > *>.measure tmin0=min("v(1)" arg last after=t0 before=t1) > *>.measure tmin1=min("v(1)" arg last after=t1 before=t2) > *>.measure tmax1=max("v(1)" arg last before=t1 after=t0) > *>.param falltime=tmin1-tmax1 > *>.param risetime=tmax1-tmin0 > *>.param dt=t2-t1 > *>.eval falltime > *>.eval risetime > *>.eval dt > .END Works for me in NGSpice, if I lower RELTOL. But the initial DC fails everywhere. The circuit doesn't seem overly difficult to me, but gnucap has better stepsize control, apparently. Sören |