Order of circuit elements in netlist affects simulation convergence?

47 views
Skip to first unread message

Jesus Perez

unread,
Nov 8, 2019, 11:14:14 AM11/8/19
to xyce-users
Hello,

I am following the analysis presented here and trying to "Xyce-ify" the netlist. I've come across some peculiar behavior.

In the attached netlist file if I move lines 21 and 22:

BDRAG2 DRAG 0 V={TABLE {V(SHAFT_SPEED)} = (-.001, -1) (.001, 1) }
RDUMMY1 DRAG 0 1 

to before line 18:

BDETENT SHAFT_SPEED LD2 I={D * SIN(2*A*P*V(SHAFT_ANGLE))} ; DETENT

the transient analysis aborts with a "time step too small" error.

The analysis completes successfully otherwise.

This is not a critical issue since there is a workaround, but I thought I'd bring it to your attention. Any thoughts?
Motor_Analog.mod

xyce-users

unread,
Nov 8, 2019, 5:38:16 PM11/8/19
to xyce-users
Thank you for your post, Jesus.  It is hard to see why your circuit should depend on netlist element ordering, but it is not unheard of for there to be such dependence (though it is exceptionally rare).  Changing the netlist ordering can change the order in which computations are evaluated, and if the circuit is extremely ill-behaved then differences in roundoff between the two differently ordered variants can lead one to succeed and the other to fail.  But it is not at all clear that that's what's going on here.

I am currently looking over this netlist and am seeing different results than you do, suggesting that this is a really sensitive problem that may be hard to pin down.  I am seeing that moving your two lines in the way you indicated has no effect on my system, where both versions run just fine to completion.   However, very slight modifications that *should* have no effect are then causing my simulations to fail, too.

We are aware of a bug in B source table derivatives that can sometimes show up as convergence failures that seems to be relevant when a table only has two points in it. In order to check if that were the source of problems in this case, I tried simply adding a (0.0,0.0) pair in the middle, which should have had no effect and should mask the bug were it relevant to this case --- yet when I ran it, THEN I started having convergence failures irrespective of where I put the BDRAG2 and RDUMMY lines.  This suggests that the table derivative bug is irrelevant to this issue.

I also tried changing BDRAG2 to:
   BDRAG2 DRAG 0 V={if((V(SHAFT_SPEED)< -0.001),-1.0,if((V(SHAFT_SPEED)>0.001),1.0,(-1+(V(SHAFT_SPEED)+0.001)*1e3)))}


which also should have created a B source identical to the table function you specified and should have no derivative bug, but it, too, crashed with a timestep too small at about 45% of the run.  In fact, everything I've tried other than your original circuit seems to lead to this failure at the same time, and on my system I can't make it work just by reordering the netlist at all.  This suggests to me that the problem is indeed quite sensitive to small numerical issues and you just happened to have stumbled upon one variant that worked.

I also worried that perhaps there was something about the discontinuous derivatives that the expression above produces, and tried using the "SMOOTHBSRC=1" option to the B source that adds a small RC network in the device to smooth out sharp transitions, but that didn't help at all (which I see now is because you had already specified that option to apply globally to all B sources).  What did help, though, was adding a 1pf capacitor in parallel with RDUMMY1 (i.e. between node DRAG and ground).  But this only worked with the original TABLE and my "IF" variant --- if I tried the table that had (-0.001,-1) (0.0,0.0) (0.001,1.0) it still failed with timestep too small.

So this circuit does appear to have some convergence issues on its own, and the exact formulation of the BDRAG2 device appears to be at the root of the problem, but beyond that I can only speculate on why without a lot more effort.  The fact that there are circuit elements (inductors) in this model that mention that they're there to "force timestep control" may indicate that they're relying on some specific PSPICE magic under the hood to keep  it stable, and you might have more work cut out for you to make it stable for Xyce.

Jesús Pérez

unread,
Nov 21, 2019, 5:41:41 PM11/21/19
to xyce-users
Thank you very much for responding. I've made some progress is making the netlist more stable in Xyce. Deleting all the circuit elements that were there "force timestep control" helped a great deal. I'd like to know your input on the following though:

Is there an advantage to having .FUNC statements (for "intermediate" mathematical operations) over arbitrary sources? For example, I've seen several netlists for SPICE and other simulators that will declare as many dependent or arbitrary sources as they need in order to realize a relatively complicated function. The outputs of these sources isn't truly a circuit element, but their voltage or current is later used in the expression for another source. Would it be better to have .FUNC statements instead?

Also, I did implement a version of the netlist using a YACC device and converted all of the intermediate sources to .FUNC statements but Xyce crashes upon reading the netlist. Do you have any advice or have you seen anything like this before?

xyce-users

unread,
Nov 21, 2019, 6:13:08 PM11/21/19
to xyce-users

Jesus:  .func statements simply create a simple way of naming subexpressions.  As they are used, their function expression is substituted into the containing expression almost as a macro expansion, so:
 
.func foobie(x) {x*x}
.func bletch(y)  {foobie(y)*foobie(y)}

B1
1 0 V={bletch(V(2,3))}

is exactly equivalent to:
B1 1 0 V={(V(2,3)*V(2,3))*(V(2,3)*V(2,3))}

by the time the B source ever gets told about the expression.  .func simply provides improved readability of the netlist.  (This macro expansion behavior of .func is also a problem that can cause complex, nested function usage to result in enormous expressions that cause serious parsing bottlenecks, and we are working to change it --- but the end result will still be that the purpose of .func is to make it easier to write netlists that are more readable).

Use of .func vs. explicit expression construction should be a matter of personal preference (so long as the .func use is not so complex that it trips the parsing bottleneck).

Without seeing exactly how you're using the YACC device (which is somewhat esoteric and not very widely used), exactly how you're using .funcs, and exactly what is happening in the crash, we can't really guess why you're experiencing a crash.

xyce-users

unread,
Nov 21, 2019, 6:34:31 PM11/21/19
to xyce-users
I overlooked answering one part of your mail: 
Is there an advantage to having .FUNC statements (for "intermediate" mathematical operations) over arbitrary sources?

Generally speaking, if you have a complex expression to build up, and the end result of that expression is what is needed in some B source, it is better to construct your expression directly (either as a single expression or with judicious application of .func) in the B source where it is desired than to build up the expression by creating many simple B sources and using the voltage nodes of those B sources as if they were subexpression values.  This approach may be common, especially in simulators that do not have a fully developed expression package, but the additional solution variables it introduces can lead to convergence problems or worse.

Use of B sources to build up a complex expression is actually a fairly dangerous practice and we advise against it.  This is primarily because doing so introduces additional solution variables into the system and can sometimes lead to badly behaving systems, especially if the expressions in these B sources are ill-defined or ill-behaved in ranges of their input that might be explored during the nonlinear solver's iterations.  We, too, have seen a number of netlists from users of other simulators where B sources are treated almost as if they are a sort of calculator object for evaluating subexpressions, and many times we have seen these netlists experience convergence problems, or worse, crash because some unconverged solution has fed them numbers that are out of the legal range for the builtin functions they use (for example, a negative number being fed to a sqrt function).

Because of this experience (which we saw from users very frequently in the early days of Xyce development), we even have guidance in the users' guide not to use B sources this way.  See section 6.3 of the users guide for details.
Reply all
Reply to author
Forward
0 new messages