Menu

#308 Bug in expression parsing for behavioural resistor?

v1.0 (example)
closed-rejected
None
5
2015-06-02
2015-05-20
No

Hi,

I hope this is just me being stupid but I have found what seems to be
a bug in parsing the expressions used for a behavioural resistor.

I have two soft switches made using the behavioural form of resistor.

One is normally closed (nc), the other normally open (no).

The expressions used for each are essentially the same except that one
uses a subtraction to invert the sense of the switch.

The subtracted form works but the basic form (without the subtraction)
does not (the switch is stuck open).

This is the working, subtracted form used for the no switch:

R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron

This is the non-working form used for the nc switch:

R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron

Please see the netlist below (but watch out for errors due to line wrapping):


* Bug in expression parsing for behavioural resistor?
*
.tran 200u 200m ; comment out for LTspice
.probe V(CONTROL) I(Vimonno) I(Vimonnc) ; comment out for LTspice
*.tran 200m ; uncomment for LTspice
*
V2 CONTROL 0 SINE(0.5 0.5 10 0 0 -90)
V1 VCC 0 1
Vimonno VCC NOx ; current in normally open switch
Vimonnc VCC NCx ; current in normally closed switch
R5 NOx NO1 1
R7 NCx NC1 1
.param
+ Ron = 1m ; Ohms. Contact resistance.
+ Roff = 1G ; Ohms. Open circuit resistance.
+ ncopens = 0.3 ; nc contact opens at 0.3V
+ nocloses = 0.7 ; no contact closes at 0.7V
+ gain = 1k ; gain of switch tanh function
**
* Switches
R_nc 0 NC1 R=0.5*(tanh( (V(CONTROL)-ncopens)*gain )+1)*Roff + Ron ;
this does not work
*R_nc 0 NC1 R=(1-0.5*(tanh( ((1-V(pullin1))-(1-ncopens))*gain )+1))*Roff + Ron ; this works but looks clumsy!
*R_nc 0 NC1 R=(1-0.5*(tanh( (V(CONTROL)-ncopens)*gain )+1))*Roff + Ron
; this works (but is the wrong polarity for the nc switch)
R_no 0 NO1 R=(1-0.5*(tanh( (V(CONTROL)-nocloses)*gain )+1))*Roff + Ron
; this works
*R_no 0 NO1 R=(0.5*(tanh( (V(CONTROL)-ncocloses)*gain )+1))*Roff + Ron
; this does not work
*
* Implementing the normally closed behavioural resistor as a B source works too, so is it only in 
* the expression parsing for the behavioural resistor that the problem appears?
*B_nc COM1 NC1 I=V(NC1,COM1)/(0.5*(tanh( (V(pullin1)-ncopens)*gain )+1)*Roff + Ron) ; this works
*
.end

The same netlist runs with no problems in LTspice.

What am I missing?

Thanks,

     Andy.

Related

Bugs: #308

Discussion

  • marcel hendrix

    marcel hendrix - 2015-05-21

    What am I missing?

    Quotes around the expressions :-)

    Unfortunately, there is more. I suspect a bug
    in the translation to a behavioral source
    (what you view with "listing extended"). It might
    be that we get negative resistance because
    of a sign error somewhere in the translation.
    This needs further investigation.

    -marcel

     

    Last edit: marcel hendrix 2015-05-21
    • Andy Fierman

      Andy Fierman - 2015-05-21

      Thanks Marcel,

      I have seen a number of errors (some already reported here as bugs) to do
      with differences in interpreting the sign in front of numbers, variables
      and parameters.

      There have been occasions when I have wanted to do things like:

      B out 0 V=1-V(in)

      but have had to write it as:

      B out 0 V=1-1*V(in)

      to make it work.

      One of the "this works" versions is written in that sort of format.

      It would be nice if ngspice could be made to treat the sign in front of
      things the way it would be expected, i.e:

      -anything is always interpreted as exactly equivalent to -1*(anything)

      :)

      Cheers,

           Andy.
      

      signality.co.uk

      On 21 May 2015 at 06:29, marcel hendrix mhx_at_sf@users.sf.net wrote:

      What am I missing?

      Quotes around the expressions :-)

      Unfortunately, there is more. I suspect a bug
      in the translation to a behavioral source
      (what you view with "listing extended"). It might
      be that you we get negative resistance because
      of a sign error somewhere in the translation.
      This needs further investigation.

      -marcel

      Status: open
      Group: v1.0 (example)
      Created: Wed May 20, 2015 08:59 PM UTC by Andy Fierman
      Last Updated: Wed May 20, 2015 09:00 PM UTC
      Owner: nobody

      Hi,

      I hope this is just me being stupid but I have found what seems to be
      a bug in parsing the expressions used for a behavioural resistor.

      I have two soft switches made using the behavioural form of resistor.

      One is normally closed (nc), the other normally open (no).

      The expressions used for each are essentially the same except that one
      uses a subtraction to invert the sense of the switch.

      The subtracted form works but the basic form (without the subtraction)
      does not (the switch is stuck open).

      This is the working, subtracted form used for the no switch:

      R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron

      This is the non-working form used for the nc switch:

      R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron

      Please see the netlist below (but watch out for errors due to line
      wrapping):


      • Bug in expression parsing for behavioural resistor?.tran 200u 200m ; comment out for LTspice.probe V(CONTROL) I(Vimonno) I(Vimonnc) ; comment out for LTspice.tran 200m ; uncomment for LTspiceV2 CONTROL 0 SINE(0.5 0.5 10 0 0 -90)V1 VCC 0 1Vimonno VCC NOx ; current in normally open switchVimonnc VCC NCx ; current in normally closed switchR5 NOx NO1 1R7 NCx NC1 1.param+ Ron = 1m ; Ohms. Contact resistance.+ Roff = 1G ; Ohms. Open circuit resistance.+ ncopens = 0.3 ; nc contact opens at 0.3V+ nocloses = 0.7 ; no contact closes at 0.7V+ gain = 1k ; gain of switch tanh function SwitchesR_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)Roff + Ron ;this does not workR_nc 0 NC1 R=(1-0.5(tanh( ((1-V(pullin1))-(1-ncopens))gain )+1))Roff + Ron ; this works but looks clumsy!R_nc 0 NC1 R=(1-0.5(tanh( (V(CONTROL)-ncopens)gain )+1))Roff + Ron; this works (but is the wrong polarity for the nc switch)R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))Roff + Ron; this worksR_no 0 NO1 R=(0.5(tanh( (V(CONTROL)-ncocloses)gain )+1))Roff + Ron; this does not work Implementing the normally closed behavioural resistor as a B source works too, so is it only in * the expression parsing for the behavioural resistor that the problem appears?B_nc COM1 NC1 I=V(NC1,COM1)/(0.5(tanh( (V(pullin1)-ncopens)gain )+1)Roff + Ron) ; this works*.end

      The same netlist runs with no problems in LTspice.

      What am I missing?

      Thanks,

       Andy.
      

      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/ngspice/bugs/308/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #308

  • marcel hendrix

    marcel hendrix - 2015-05-21

    Where is "V(pullin1))" ?

    -marcel

     
    • Andy Fierman

      Andy Fierman - 2015-05-21

      "Where is "V(pullin1))" ?"

      Sorry about that: V(pullin1) should have been corrected to V(CONTROL).

      The two lines with V(pullin1) in them were copied across from another
      netlist that I had been trying things out in and I forgot to correct the
      netname.

      Cheers,

           Andy.
      

      signality.co.uk

      On 21 May 2015 at 21:18, marcel hendrix mhx_at_sf@users.sf.net wrote:

      Where is "V(pullin1))" ?

      -marcel

      Status: open
      Group: v1.0 (example)
      Created: Wed May 20, 2015 08:59 PM UTC by Andy Fierman
      Last Updated: Thu May 21, 2015 05:29 AM UTC
      Owner: nobody

      Hi,

      I hope this is just me being stupid but I have found what seems to be
      a bug in parsing the expressions used for a behavioural resistor.

      I have two soft switches made using the behavioural form of resistor.

      One is normally closed (nc), the other normally open (no).

      The expressions used for each are essentially the same except that one
      uses a subtraction to invert the sense of the switch.

      The subtracted form works but the basic form (without the subtraction)
      does not (the switch is stuck open).

      This is the working, subtracted form used for the no switch:

      R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron

      This is the non-working form used for the nc switch:

      R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron

      Please see the netlist below (but watch out for errors due to line
      wrapping):


      • Bug in expression parsing for behavioural resistor?.tran 200u 200m ; comment out for LTspice.probe V(CONTROL) I(Vimonno) I(Vimonnc) ; comment out for LTspice.tran 200m ; uncomment for LTspiceV2 CONTROL 0 SINE(0.5 0.5 10 0 0 -90)V1 VCC 0 1Vimonno VCC NOx ; current in normally open switchVimonnc VCC NCx ; current in normally closed switchR5 NOx NO1 1R7 NCx NC1 1.param+ Ron = 1m ; Ohms. Contact resistance.+ Roff = 1G ; Ohms. Open circuit resistance.+ ncopens = 0.3 ; nc contact opens at 0.3V+ nocloses = 0.7 ; no contact closes at 0.7V+ gain = 1k ; gain of switch tanh function SwitchesR_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)Roff + Ron ;this does not workR_nc 0 NC1 R=(1-0.5(tanh( ((1-V(pullin1))-(1-ncopens))gain )+1))Roff + Ron ; this works but looks clumsy!R_nc 0 NC1 R=(1-0.5(tanh( (V(CONTROL)-ncopens)gain )+1))Roff + Ron; this works (but is the wrong polarity for the nc switch)R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))Roff + Ron; this worksR_no 0 NO1 R=(0.5(tanh( (V(CONTROL)-ncocloses)gain )+1))Roff + Ron; this does not work Implementing the normally closed behavioural resistor as a B source works too, so is it only in * the expression parsing for the behavioural resistor that the problem appears?B_nc COM1 NC1 I=V(NC1,COM1)/(0.5(tanh( (V(pullin1)-ncopens)gain )+1)Roff + Ron) ; this works*.end

      The same netlist runs with no problems in LTspice.

      What am I missing?

      Thanks,

       Andy.
      

      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/ngspice/bugs/308/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #308

  • marcel hendrix

    marcel hendrix - 2015-05-21

    What is not straightforward about the attached behavior?

    -marcel

    ::html
    
    Bug in expression parsing for behavioural resistor?
    
    Vc      s3  0  SINE(0.5 0.5 10 0 0 -90)
    Rc      s3  0  1MEG 
    Vs      1   0  dc  10
    Rs      1  s1  10
    Rt      s2  0  10
    B_test  s2 s1   I = V(s1,s2) / (V(s3) > ncopens ? Ron : Roff)
    
    Vs2     2     0  dc 10
    Rs2     2   s11  10
    Rt2     s12   0  10
    Rno     s11 s12  R = 'V(s3) > ncopens  ? Ron : Roff'
    
    Vs3     3     0  dc 10
    Rs3     3   s21  10
    Rt3     s22   0  10
    Rnc     s21 s22  R = 'V(s3) > nocloses ? Roff : Ron'
    
    
    .param
    
    + Ron      = 1m  ; Ohms. Contact resistance.
    + Roff     = 1G  ; Ohms. Open circuit resistance.
    + ncopens  = 0.3 ; nc contact opens at 0.3V
    + nocloses = 0.7 ; no contact closes at 0.7V
    + gain     = 1k  ; gain of switch tanh function
    
    .tran 0 200m 0 200u
    
    .end
    
     

    Last edit: marcel hendrix 2015-05-21
    • Andy Fierman

      Andy Fierman - 2015-05-21

      Hi Marcel,

      Clearly there are many ways to implement a change over or SPDT switch and
      of avoiding the bug I have reported at the same time.

      I could simply have used a pair of voltage controlled switches instead of
      behavioural resistors or I could have used a B source implementation of a
      controlled resistor as in one of the commented out lines that did actually
      work in my example. In fact I will be using the rearranged form of the
      expression:

      "R_nc 0 NC1 R=(1-0.5(tanh( ((1-V(CONTROL))-(1-ncopens))gain )+1))*Roff +
      Ron ; this works but looks clumsy!".

      Your alternative solution is also fine and is another way of avoiding the
      bug I have found but there are two reasons I would not want to implement
      the switches that way using an 'a > b ? c : d' type of function.

      i) unless there is something special about the way it is implemented in
      ngspice, 'a > b ? c : d' function introduces an inherent discontinuity.
      There is no way to control the speed of the transition between the two
      possible outcomes (I know of a sort of soft IF statement in SIMetrix but
      not in any other spice).

      Because the outcome of the 'a > b ? c : d' function is discontinuous and
      drives the transition in the value of the resistors directly then the
      change in the resistance is itself discontinuous.

      In my experience and understanding of spice:

      discontinuity = bad, bad, naughty bad, wicked bad;

      smooth transition = goooooood.

      ii) the switches in my netlist are based on a tanh function which allows
      them to switch in a smooth, continuous transition between Ron and Roff. The
      'gain' parameter allows the "sharpness" of the transition to be adjusted.
      This forms a kind of soft switch. Again, in my experience, this improves
      convergence in most simulations compared to having the discontinuous action
      of something like the 'a > b ? c : d' function or simply using the voltage
      controlled switch, which is a hard switching action.

      The bug I found was in the course of developing a rather more complex
      subcircuit where the V(CONTROL) input to the switches is a smoothly varying
      voltage however, for the purpose of demonstrating the bug, rather than
      confusing things with this complicated subcircuit, I put the same switches
      and associated expressions which demonstrate the bug into a much simpler
      test jig. It's the bug I'm reporting rather than a problem with the
      implementation.

      And as you say, there seems to be an underlying problem related to
      differences in the parsing of signs in expressions used in B sources as
      compared to those in expressions for parameters and so on, of which I
      suspect this is just one manifestation.

      :)

      Cheers,

           Andy.
      

      signality.co.uk

      On 21 May 2015 at 22:03, marcel hendrix mhx_at_sf@users.sf.net wrote:

      What is not straightforward about the attached behavior?

      -marcel

      Bug in expression parsing for behavioural resistor?

      Vc s3 0 SINE(0.5 0.5 10 0 0 -90)
      Rc s3 0 1MEG
      Vs 1 0 dc 10
      Rs 1 s1 10
      Rt s2 0 10
      B_test s2 s1 I = V(s1,s2) / (V(s3) > ncopens ? Ron : Roff)

      Vs2 2 0 dc 10
      Rs2 2 s11 10
      Rt2 s12 0 10
      Rno s11 s12 R = 'V(s3) > ncopens ? Ron : Roff'

      Vs3 3 0 dc 10
      Rs3 3 s21 10
      Rt3 s22 0 10
      Rnc s21 s22 R = 'V(s3) > nocloses ? Roff : Ron'

      .param
      + Ron = 1m ; Ohms. Contact resistance.
      + Roff = 1G ; Ohms. Open circuit resistance.
      + ncopens = 0.3 ; nc contact opens at 0.3V
      + nocloses = 0.7 ; no contact closes at 0.7V
      + gain = 1k ; gain of switch tanh function

      .tran 0 200m 0 200u

      .end

      Attachment: swbehavior.png (32.3 kB; image/png) switchbugs.cir (1.5 kB;
      application/octet-stream)


      Status: open
      Group: v1.0 (example)
      Created: Wed May 20, 2015 08:59 PM UTC by Andy Fierman
      Last Updated: Thu May 21, 2015 08:18 PM UTC
      Owner: nobody

      Hi,

      I hope this is just me being stupid but I have found what seems to be
      a bug in parsing the expressions used for a behavioural resistor.

      I have two soft switches made using the behavioural form of resistor.

      One is normally closed (nc), the other normally open (no).

      The expressions used for each are essentially the same except that one
      uses a subtraction to invert the sense of the switch.

      The subtracted form works but the basic form (without the subtraction)
      does not (the switch is stuck open).

      This is the working, subtracted form used for the no switch:

      R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron

      This is the non-working form used for the nc switch:

      R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron

      Please see the netlist below (but watch out for errors due to line
      wrapping):


      • Bug in expression parsing for behavioural resistor?.tran 200u 200m ; comment out for LTspice.probe V(CONTROL) I(Vimonno) I(Vimonnc) ; comment out for LTspice.tran 200m ; uncomment for LTspiceV2 CONTROL 0 SINE(0.5 0.5 10 0 0 -90)V1 VCC 0 1Vimonno VCC NOx ; current in normally open switchVimonnc VCC NCx ; current in normally closed switchR5 NOx NO1 1R7 NCx NC1 1.param+ Ron = 1m ; Ohms. Contact resistance.+ Roff = 1G ; Ohms. Open circuit resistance.+ ncopens = 0.3 ; nc contact opens at 0.3V+ nocloses = 0.7 ; no contact closes at 0.7V+ gain = 1k ; gain of switch tanh function SwitchesR_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)Roff + Ron ;this does not workR_nc 0 NC1 R=(1-0.5(tanh( ((1-V(pullin1))-(1-ncopens))gain )+1))Roff + Ron ; this works but looks clumsy!R_nc 0 NC1 R=(1-0.5(tanh( (V(CONTROL)-ncopens)gain )+1))Roff + Ron; this works (but is the wrong polarity for the nc switch)R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))Roff + Ron; this worksR_no 0 NO1 R=(0.5(tanh( (V(CONTROL)-ncocloses)gain )+1))Roff + Ron; this does not work Implementing the normally closed behavioural resistor as a B source works too, so is it only in * the expression parsing for the behavioural resistor that the problem appears?B_nc COM1 NC1 I=V(NC1,COM1)/(0.5(tanh( (V(pullin1)-ncopens)gain )+1)Roff + Ron) ; this works*.end

      The same netlist runs with no problems in LTspice.

      What am I missing?

      Thanks,

       Andy.
      

      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/ngspice/bugs/308/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #308

  • marcel hendrix

    marcel hendrix - 2015-05-22

    Hi Andy,

    As there were an uncharacteristically high amount of
    puzzling inaccuracies in your test circuit I recreated
    it such that, I at least, could understand what was
    going on. My first attempt removed the tanh() because
    I thought it was unimportant for the problem at hand.
    I have put it back in now the main problem is clearer.

    I hope that the new test file matches your
    intention and its output (although mislabeled)
    is correct. I checked it with LTspice -- the results
    are the same (although LTspice takes much longer to
    run the file, of course).

    There are two other points you make that I want to
    comment on:

    And as you say, there seems to be an underlying
    problem related to differences in the parsing of
    signs in expressions used in B sources as
    compared to those in expressions for parameters
    and so on, of which I suspect this is just one
    manifestation.

    You have to understand that these errors, that you
    reported to the NGSPICE maintainers, thanks, are
    not corrected within the 5-minute timespan that you
    are used to from LTspice ;-) If you download the
    latest GIT sources I think you will find that they
    reproduce the results that I have attached.

    there are two reasons I would not want to implement
    the switches that way using an 'a > b ? c : d' type
    of function. [...]

    Of course these are excellent points. Indeed,
    current NGSPICE does not have the magic that is
    present in SIMetrix, and indeed, LTspice is a lot
    smarter in detecting discontinuities. We
    are working on XSPICE code models that will lead
    to large improvements in this area.

    Making sure functions are smooth is not enough,
    as it will cause big time steps being made, which
    cause large errors when completely unpredictable
    events take place (like a switch driven by
    arbitrary timing signals.) The best solution that
    I know for this is that all (user) models generate
    breakpoints. Some current NGSPICE models already
    implement this idea, but incorrectly.

    Please keep the bug reports coming, they are really
    appreciated.

    -marcel

     
    • Andy Fierman

      Andy Fierman - 2015-06-02

      Hi Marcel,

      I just realised that I bungled sending a reply to your last post about 9
      days ago ... still getting the hang of emailing via smartphone.

      Sorry about the mistakes in my original posting. It was done in too much of
      a hurry.

      Thanks for the switchbugs.cir
      http://sourceforge.net/p/ngspice/bugs/_discuss/thread/3257a26d/0f1e/attachment/switchbugs.cir
      netlist, I've tried it and it works exactly as required.

      Looking at it carefully I realise that the problem was just me being stupid
      after all.

      In my original netlist I had:

      • Switches

      R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron ;
      this does not work

      R_nc 0 NC1 R=(1-0.5(tanh( ((1-V(CONTROL))-(1-ncopens))gain
      )+1))
      Roff + Ron ; this works but looks clumsy!

      R_nc 0 NC1 R=(1-0.5(tanh( (V(CONTROL)-ncopens)gain )+1))Roff + Ron
      ; this works (but is the wrong polarity for the nc switch)

      R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron
      ; this works

      R_no 0 NO1 R=(0.5(tanh( (V(CONTROL)-ncocloses)gain )+1))Roff + Ron
      ; this does not work

      My mistake was that I had not enclosed the expressions with apostrophes.

      Your netlist correctly uses apostrophes around the expressions:

      R_nc1 0 21 R= ' 0.5(tanh(( V(CONTROL) - ncopens) gain )+1 )*Roff +
      Ron'

      R_nc2 0 22 R= '(1-0.5(tanh( ((1-V(CONTROL))-(1-ncopens))gain )+1))*Roff +
      Ron'

      R_nc3 0 23 R= '(1-0.5(tanh( ( V(CONTROL) - ncopens) gain )+1))*Roff +
      Ron'

      R_no1 0 24 R= '(1-0.5(tanh( ( V(CONTROL) - nocloses) gain )+1))*Roff +
      Ron'

      R_no2 0 25 R= '( 0.5(tanh( ( V(CONTROL) - nocloses) gain )+1))*Roff +
      Ron'

      and all the variants of the expressions work as expected.

      If I edit my original netlist to include the apostrophes then my problem
      goes away.

      So it was all my fault for being sloppy with the syntax differences between
      my use of ngspice and LTspice.

      "Making sure functions are smooth is not enough, as it will cause big
      time steps being made, which cause large errors when completely
      unpredictable events take place (like a switch driven by arbitrary timing
      signals.) "

      I was trying to use functions that are not only smooth and continuous but
      are also continuous in their first derivative.

      Is the problem then that by using smooth functions, this allows ngspice to
      use big timesteps - because there is less change from point to point in the
      short timescale - and so when an event such as a fast switching edge occurs
      somewhere between these big timesteps, large errors can occur?

      If that is the case then I think I understand why:

      "The best solution that I know for this is that all (user) models
      generate breakpoints."

      I must read up about "breakpoints". I don't know enough about this to
      understand the significance and how to make use of them yet.

      Far from complaining about the speed of bug fixing in ngspice, I was just
      trying to put my post Into a bit more context. I didn't have the bug report
      numbers to hand to help bring the other instances of this type of problem
      together.

      In fact one of the things I've always been so impressed with in the ngspice
      forums is the speed with which bug reports and user questions do get
      sensible, constructive responses and actions.

      As this thread has just demonstrated, the ngspice and the gEDA forums I
      think showcase the best that FOSS communities have to offer. I often tell
      people who are dubious about FOSS that the speed and quality of response of
      FOSS communities puts many paid-for commercial support services well into
      the shade.

      Once again, many thanks for your help.

      :)

      Cheers,

           Andy.
      

      signality.co.uk

      On 22 May 2015 at 21:17, marcel hendrix mhx_at_sf@users.sf.net wrote:

      Hi Andy,

      As there were an uncharacteristically high amount of
      puzzling inaccuracies in your test circuit I recreated
      it such that, I at least, could understand what was
      going on. My first attempt removed the tanh() because
      I thought it was unimportant for the problem at hand.
      I have put it back in now the main problem is clearer.

      I hope that the new test file matches your
      intention and its output (although mislabeled)
      is correct. I checked it with LTspice -- the results
      are the same (although LTspice takes much longer to
      run the file, of course).

      There are two other points you make that I want to
      comment on:

      And as you say, there seems to be an underlying
      problem related to differences in the parsing of
      signs in expressions used in B sources as
      compared to those in expressions for parameters
      and so on, of which I suspect this is just one
      manifestation.

      You have to understand that these errors, that you
      reported to the NGSPICE maintainers, thanks, are
      not corrected within the 5-minute timespan that you
      are used to from LTspice ;-) If you download the
      latest GIT sources I think you will find that they
      reproduce the results that I have attached.

      there are two reasons I would not want to implement
      the switches that way using an 'a > b ? c : d' type
      of function. [...]

      Of course these are excellent points. Indeed,
      current NGSPICE does not have the magic that is
      present in SIMetrix, and indeed, LTspice is a lot
      smarter in detecting discontinuities. We
      are working on XSPICE code models that will lead
      to large improvements in this area.

      Making sure functions are smooth is not enough,
      as it will cause big time steps being made, which
      cause large errors when completely unpredictable
      events take place (like a switch driven by
      arbitrary timing signals.) The best solution that
      I know for this is that all (user) models generate
      breakpoints. Some current NGSPICE models already
      implement this idea, but incorrectly.

      Please keep the bug reports coming, they are really
      appreciated.

      -marcel

      Attachment: notswitchbug.png (47.4 kB; image/png)
      notswitchbug_continuity.png (17.3 kB; image/png) switchbugs.cir (1.1 kB;
      application/octet-stream)


      Status: open
      Group: v1.0 (example)
      Created: Wed May 20, 2015 08:59 PM UTC by Andy Fierman
      Last Updated: Thu May 21, 2015 09:03 PM UTC
      Owner: nobody

      Hi,

      I hope this is just me being stupid but I have found what seems to be
      a bug in parsing the expressions used for a behavioural resistor.

      I have two soft switches made using the behavioural form of resistor.

      One is normally closed (nc), the other normally open (no).

      The expressions used for each are essentially the same except that one
      uses a subtraction to invert the sense of the switch.

      The subtracted form works but the basic form (without the subtraction)
      does not (the switch is stuck open).

      This is the working, subtracted form used for the no switch:

      R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))*Roff + Ron

      This is the non-working form used for the nc switch:

      R_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)*Roff + Ron

      Please see the netlist below (but watch out for errors due to line
      wrapping):


      • Bug in expression parsing for behavioural resistor?.tran 200u 200m ; comment out for LTspice.probe V(CONTROL) I(Vimonno) I(Vimonnc) ; comment out for LTspice.tran 200m ; uncomment for LTspiceV2 CONTROL 0 SINE(0.5 0.5 10 0 0 -90)V1 VCC 0 1Vimonno VCC NOx ; current in normally open switchVimonnc VCC NCx ; current in normally closed switchR5 NOx NO1 1R7 NCx NC1 1.param+ Ron = 1m ; Ohms. Contact resistance.+ Roff = 1G ; Ohms. Open circuit resistance.+ ncopens = 0.3 ; nc contact opens at 0.3V+ nocloses = 0.7 ; no contact closes at 0.7V+ gain = 1k ; gain of switch tanh function SwitchesR_nc 0 NC1 R=0.5(tanh( (V(CONTROL)-ncopens)gain )+1)Roff + Ron ;this does not workR_nc 0 NC1 R=(1-0.5(tanh( ((1-V(pullin1))-(1-ncopens))gain )+1))Roff + Ron ; this works but looks clumsy!R_nc 0 NC1 R=(1-0.5(tanh( (V(CONTROL)-ncopens)gain )+1))Roff + Ron; this works (but is the wrong polarity for the nc switch)R_no 0 NO1 R=(1-0.5(tanh( (V(CONTROL)-nocloses)gain )+1))Roff + Ron; this worksR_no 0 NO1 R=(0.5(tanh( (V(CONTROL)-ncocloses)gain )+1))Roff + Ron; this does not work Implementing the normally closed behavioural resistor as a B source works too, so is it only in * the expression parsing for the behavioural resistor that the problem appears?B_nc COM1 NC1 I=V(NC1,COM1)/(0.5(tanh( (V(pullin1)-ncopens)gain )+1)Roff + Ron) ; this works*.end

      The same netlist runs with no problems in LTspice.

      What am I missing?

      Thanks,

       Andy.
      

      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/ngspice/bugs/308/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #308

  • marcel hendrix

    marcel hendrix - 2015-06-02

    Is the problem then that by using smooth functions, this allows ngspice to
    use big timesteps - because there is less change from point to point in the
    short timescale - and so when an event such as a fast switching edge occurs
    somewhere between these big timesteps, large errors can occur?

    Yes. The following explanation may be inaccurate, but I hope it
    illustrates the point...

    Assume there is only a nice perfectly sinusoidal signal and a random signal that
    triggers a switch that connects the sine to an output pin.

    After each time step the simulator checks the errors made in each signal.
    Actually it asks all circuit matrix elements in turn to check themselves.
    Of course for the smooth continuous signal(s) the error is very low. Then
    (we think that) the simulator should ask the random gate signal to
    check itself. However, as this signal comes from a source and SPICE
    sources have no memory, SPICE will simply not do that. It will query the
    source if it is high or low and uses that for the next step.

    This description suggests what one could do to improve performance with
    event-based discontinuities. One possibility is to have continuous, smooth
    sources. This helps speed-up the Newton-Raphson process but does not much
    for timestep control - for that there also must be a mechanism that SPICE
    asks sources their opinion on how the time step went, not only elements
    in the circuit matrix.

    An LTspice trick is to add a small RC low-pass filter over each voltage source
    and let the circuit matrix handle it.

    The other possibility, that NGSPICE uses, is to have (built-in) sources raise
    events when they go discontinuous (breakpoints). This leaves B-sources a
    problem (as they are user-defined and there is no mechanism to post a
    breakpoint). Another tough problem is e.g. a diode, by nature discontinuous.
    Posting a breakpoint will work, but that is conventionally not how diode
    models are written.

    This explains why a SPICE written especially for power electronics might be
    quite different from one written for RF and low-voltage analog stuff.
    XSPICE allows to write models that are specifically tuned for these problems
    and still can be very efficient.

    -marcel

     
    • Andy Fierman

      Andy Fierman - 2015-06-02

      Marcel,

      Thanks for that. Your explanation is very helpful.

      "An LTspice trick is to add a small RC low-pass filter over each voltage
      source
      and let the circuit matrix handle it. "

      As far as I understand it, spice deals with Norton sources with parallel RC
      circuits more efficiently than Thevenin sources with a series R followed by
      a parallel C.

      Therefore, where possible, instead of using a V source with a series R
      followed by a parallel C, I try to use a current source with a parallel RC.

      Also when using B sources, instead of using a BV source, I try to use a BI
      sources with a 1R resistor and a capacitor in parallel (usualy 1pF works
      OK) with it. That means I can use the same expression as for the intended
      BV source but the source becomes a lowpass filtered Norton Source.

      I think the only problem I have seen with this in LTspice is that for B
      sources that need a very low source resistance (i.e. R << 1), the
      multiplication factor applied to the expression to scale the output voltage
      back up again can slow the simulation down quite significantly. Now, I
      don't know if this is true in ngspice because I have not used it enough
      yet. It may be that the slow down is a data compression thing in LTspice
      and not a function of the multiplication itself. (Bump! I have just hit the
      endstop of my understanding of spice again.)

      A really dirty trick I have used once or twice is to set up a gated high
      frequency (relative to the rest of the circuit) source that is off and so
      does nothing for most of the simulation but is turned on only around some
      event(s) that have been observed to cause a convergence problem - or needs
      a higher time resolution - but which can be solved by using smaller step
      sizes. That way the whole of the simulation is not slowed by the need for
      small timesteps but does exercise them when needed bracketing the trouble
      spots.

      The hf source has to be something like a gated RC or behavioural schmitt
      based oscillator or some function of TIME that completely stops when gated
      off because obviously simply gating the output of a SIN() or PULSE() source
      leaves the source itself always running and so slowing the simulation down.

      I know what you're thinking: it is hard to believe that anyone could stoop
      so low to achieve their murky goals ...

      Cheers,

           Andy.
      

      signality.co.uk

      On 2 June 2015 at 12:37, marcel hendrix mhx_at_sf@users.sf.net wrote:

      Is the problem then that by using smooth functions, this allows ngspice
      to
      use big timesteps - because there is less change from point to point in the
      short timescale - and so when an event such as a fast switching edge occurs
      somewhere between these big timesteps, large errors can occur?

      Yes. The following explanation may be inaccurate, but I hope it
      illustrates the point...

      Assume there is only a nice perfectly sinusoidal signal and a random
      signal that
      triggers a switch that connects the sine to an output pin.

      After each time step the simulator checks the errors made in each signal.
      Actually it asks all circuit matrix elements in turn to check themselves.
      Of course for the smooth continuous signal(s) the error is very low. Then
      (we think that) the simulator should ask the random gate signal to
      check itself. However, as this signal comes from a source and SPICE
      sources have no memory, SPICE will simply not do that. It will query the
      source if it is high or low and uses that for the next step.

      This description suggests what one could do to improve performance with
      event-based discontinuities. One possibility is to have continuous, smooth
      sources. This helps speed-up the Newton-Raphson process but does not much
      for timestep control - for that there also must be a mechanism that SPICE
      asks sources their opinion on how the time step went, not only elements
      in the circuit matrix.

      An LTspice trick is to add a small RC low-pass filter over each voltage
      source
      and let the circuit matrix handle it.

      The other possibility, that NGSPICE uses, is to have (built-in) sources
      raise
      events when they go discontinuous (breakpoints). This leaves B-sources a
      problem (as they are user-defined and there is no mechanism to post a
      breakpoint). Another tough problem is e.g. a diode, by nature
      discontinuous.
      Posting a breakpoint will work, but that is conventionally not how diode
      models are written.

      This explains why a SPICE written especially for power electronics might
      be
      quite different from one written for RF and low-voltage analog stuff.
      XSPICE allows to write models that are specifically tuned for these
      problems
      and still can be very efficient.

      -marcel

       
      • marcel hendrix

        marcel hendrix - 2015-06-02

        I know what you're thinking: it is hard to believe
        that anyone could stoop so low to achieve their
        murky goals ...

        No Andy, to the contrary. I am always delighted to find such creative use of existing resources, that's why I became an engineer. What I don't like is premature optimizations, or 'optimizations' that are pointless or not the result of some hard constraints, or come from blindly following rules of thumb.

        I think you have found a way of adding breakpoints to standard SPICE. The only way to improve on it would be to minimize the number of breakpoints.

        -marcel

         
        • Andy Fierman

          Andy Fierman - 2015-06-02

          I'm glad you like the idea!

          It's a bit inelegant to make it work well. The technique relies on running
          the sim a few times to find the trouble spots first and then adjusting the
          gating signal to the oscilaltor so that it just brackets them.

          The frequency and the waveshape of the oscillator also affects where these
          "breakpoints" actually end up in relation to the event you're trying to
          work through.

          The gating signal can be a PWL source to allow arbitrary placement of the
          on/off pulses.

          What would be good would be if someone could find a way to automate it or
          to predict where the hf source needs to be switched on. Maybe that's
          something that XSPICE can already deal with.

          :)

          Cheers,

               Andy.
          

          signality.co.uk

          p.s. I think you can probably close the bug report on my original question.

           
  • marcel hendrix

    marcel hendrix - 2015-06-02
    • status: open --> closed-rejected
    • assigned_to: marcel hendrix
     

Log in to post a comment.

MongoDB Logo MongoDB