[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnucap-devel] New version 0.34 and "kneechord" strategy

From: Al Davis
Subject: Re: [Gnucap-devel] New version 0.34 and "kneechord" strategy
Date: Sun, 14 Mar 2004 15:16:44 -0500
User-agent: KMail/1.6.1

Sorry about the slow response.  The list server has been very slow 

On Sunday 07 March 2004 01:25 am, Telford Tendys wrote:
> Good to see a new version of gnucap out...
> I couldn't help noticing that my kneechord code has been merged
> with the core to some extent but for anyone who wants to use it
> they will have to add a -DKNEECHORD to the Makefile and also
> add and inverse.o to the list of sources and objects
> respectively.

I started on it, then had other things get in the way of finishing it.  
By including it this way, people wanting to get involved can try work 
in progress, but people who just want to use it are not exposed to the 
extra risk of experimental code.  Some other experimental code is 
compiled in and available through undocumented options.

> I found a few issues with the current kneechord strategy as
> installed in gnucap 0.34. In a nutshell, the problem is that
> the strategy only makes sense for non-linear components. It is
> useless to call it for completely linear components (although
> the knee_chord() detects perfectly linear components within a
> few iterations and drops out quickly) and it's a big waste of
> calculating cycles to call it for a constant.

It is not called for purely linear components.  Actually, even "do_tr" 
is not called for purely linear components, except in rare 
circumstances.  Because of these rare circumstances, it must work.

The separation isn't perfect, as you say later.

> Consider the case of an ordinary current source connected to the
> generator() function. Because this is an element, it will be
> subject to the kneechord strategy and because of the generator,
> it will attempt to call the tr_eval().
> The problem here is that the generator provides a time dependent
> function which is a fixed output (not dependent on any other
> variables in the network) so with regards to converging the matrix
> equations this element is really just a constant. But the
> knee_chord() doesn't understand that it has been handed a constant so
> it tries to find the inverse function (and fails with a warning).
> This is not actually harmful, but it is counterproductive because it
> keeps trying for 200 evaluations until it decides that there is no
> inverse function.

Maybe a fixed number of iterations here is not a good idea, but these 
things happen in experimental code.

A similar situation could exist for a nonlinear component operating in a 
linear region, where no iterations take it outside.

> What is really needed is some meta-data available for the tr_eval()
> function call. Thanks to the magic of g++ and inheritance, the
> tr_eval() has become all things to all elements throughout
> the simulator. That's fine from the point of view of getting
> values for elements but I can't find a way for the knee_chord()
> function to detect whether the tr_eval() it gets is going to be a
> nonlinear function dependent on the element x or a time dependent
> constant or some other such thing. The only way to find out what
> tr_eval() does is to send in some values and see what comes back.

> My suggestion is that has_tr_eval() should not return boolean but
> return an unsigned 32 bit number that contains useful flags like:
>   * Does it depend on time ?
>   * Does it depend on local element x ?
>   * Is it non-linear ?

That violates encapsulation, so it will not change.  "has_tr_eval" tells 
you whether the element has a tr_eval.  Nothing else.  There are other 
query methods that give different information.  The way to handle this 
is to add other query methods "depends_on_time()", "depends_on_x()", 
"is_nonlinear()", etc. as needed.  These would all be inline const 
methods returning bool.

> And probably a few other things like whether the first derivative
> is available (current presumption is yes but that may not always
> be true). 

Not only that...  Even if the answer is "no", it is the responsibility 
of tr_eval to supply one.  This strategy is used throughout.  a few 
examples ...  Even if there is no tr_eval(), it is ok to call 
element->tr_eval(), and the fake must give the illusion of the real 
thing.  The output of a logic device is a logic state.  The voltage 
doesn't exist.  Perhaps the node doesn't exist.  If there are analog 
components hooked there, it will fake it.

> Possibly also some indication of how expensive a call to 
> tr_eval() is likely to be.

That is easy to do.  Add a method "tr_eval_cost()", that returns some 
constant.  How about the number of lines of code in tr_eval()?  That 
will be needed as part of cached model evaluation, to make the decision 
of how much to cache.  It would belong to the common.  Calling 
common->tr_eval() would get the real function.  Calling 
element->tr_eval() might fake it by giving you a cached value.

> If is necessary to keep has_tr_eval() boolean then some other
> inheritable meta-data mechanism would be useful. 

You need to stop thinking C. :-)
> I'm not sure how 
> many other non-linear coping strategies are likely to be employed;
> the secant strategy is probably safe to employ on everything,
> more complex algorithms (like kneechord) are only beneficial on
> some element functions.

secant, false position, relaxation, bisection, various homotopy methods, 
steepest descent minimization, harmonic balance, AWE, krylov subspace 
methods, ......

> This also makes me think about whether it would be good to be able
> to select a strategy on an element by element basis. Admittedly,
> the ideal would be automatic strategy selection but allowing user
> override is always a good idea and just supporting the concept of
> element by element strategy might be a first step towards
> auto-selection.

Eventually, that is the intent.

> Aside from the above, if anyone is trying to model nonlinear
> inductors (e.g. saturating cores in snubber networks) then I'd be
> curious to hear from them. I don't mind giving a hand with a few
> suggestions if anyone is having trouble.
> I'm also curious if anyone has tried kneechord on saturating
> semiconductor models. It should be good for that but I haven't
> tried it myself, if anyone is having convergence problems with
> such models then it might be worth a try.

The current implementation doesn't work on semiconductor models, because 
they are multi-variable.  Calling it from ELEMENT::tr_eval only works 
for elements that have a simple "x".  The multi-variable elements are 
where the help is needed most.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]