# Inaccuracy and mismatch of integrals in LTspice

I calculated the energy dissipation of a load R1 in a simple circuit within a duration of 1 second using two methods.

• Using an arbitrary behaviour current source to integrate the product of current and voltage applied to the load R1. Reading the final value of the corresponding trace gives the Energy $E_a$.
• Plotting the power over the load R1. Afterwards selecting the trace with Strg + Left Click which shows the integral of the trace $E_t$.

The circuit that was simulated in LTspice XVII:

$E_a$ and $E_t$ give different results. $E_a$ was always more accurate than $E_t$ for several combinations of frequency and amplitude of the sinusodial voltage source B1. When B1 is set to be a DC source there are no errors. Here are some of the results:

• f= 10Hz Amplitude = 1 $E$ = 0.25 J
$E_a$ [J] 0.249999 $E_t$ [J] 0.248911
• f= 50Hz Amplitude = 1 $E$ = 0.25 J
$E_a$ [J] 0.24999225
$E_t$ [J] 0.23473
• f= 10kHz Amplitude = 1 $E$ = 0.25 J
$E_a$ [J] 0.184319
$E_t$ [J] 0.14374
• f= 10kHz Amplitude = 10 $E$ = 25 J
$E_a$ [J] 24.6539
$E_t$ [J] 24.059

As can be seen increasing the frequency increases the error compared to the actual value $E$ as well as the difference between $E_a$ and $E_t$. Increasing the amplitude reduces the error at a given frequency.

So why do I get different results at all? As a discrete integration equals a summation of $P_i\cdot\Delta t_i$ at each timestep, I suspect that $E_t$ is calculated with larger timesteps leading to less resolution.

There is also the problem of reduced accuracy at higher frequency. How can I avoid this? For the given circuit this could be circumvented by only calculating a single period and scaling to the duration afterwards. But I am more concerned about more complex circuits where it can take some time until a steady state is reached (and would not notice this error).

Source Code:

Version 4
SHEET 1 880 680
WIRE 112 112 16 112
WIRE 208 112 112 112
WIRE 496 112 352 112
WIRE 608 112 496 112
WIRE 16 128 16 112
WIRE 208 128 208 112
WIRE 352 128 352 112
WIRE 608 128 608 112
WIRE 16 240 16 208
WIRE 208 240 208 208
WIRE 208 240 16 240
WIRE 352 240 352 208
WIRE 480 240 352 240
WIRE 608 240 608 208
WIRE 608 240 480 240
WIRE 208 256 208 240
WIRE 480 256 480 240
FLAG 112 112 u1
FLAG 208 256 0
FLAG 480 256 0
FLAG 496 112 u2
SYMBOL bv 16 112 R0
WINDOW 3 -109 153 Left 2
SYMATTR Value V= sin(2*pi*time* 10)
SYMATTR InstName B1
SYMBOL res 192 112 R0
SYMATTR InstName R1
SYMATTR Value 2
SYMBOL bi2 352 128 R0
SYMATTR InstName B3
SYMATTR Value I= idt(V(u1)*I(R1))
SYMBOL res 592 112 R0
SYMATTR InstName R2
SYMATTR Value 1
TEXT 272 296 Left 2 !.tran 0 1 0

• You need to be aware of the final data that is being plotted is compressed. For maximum accuracy you want options numdgt=15 and plotwinsize=0 and some rather small max timestep. and did you know about the .meas command ? – PlasmaHH Sep 2 '16 at 10:45
• @PlasmaHH: Helpful hints. I did not use .meas before. However I tried it now with .meas {E} INTEG V(u1)*I(R1) . This gives a result close to E_t, so it seems to be less accurate than the way E_a is calculated in this circumstance. Can I use the result of .meas for further computation? – Grebu Sep 2 '16 at 11:10
• yes you can, the optional first parameter is the name of a variable to store things in. Did you also do it with the numdgt thing? it controls whether floats or doubles are used... – PlasmaHH Sep 2 '16 at 11:28
• Using numdgt and plotwinsize the overall acuracy increased. But E_a remains to be more accurate than E_t. At 10 Hz E_a matches the correct value and it drops later with increased frequency. I will show more results next week, including adjusted timesteps, as I will be off line over the weekend. – Grebu Sep 2 '16 at 12:03
• @PlasmaHH No need to overdo it. There is a reply in the LTspice Yahoo Groups, msg #96035 (and some of the following), where there are a few very good points about why it's useless to have numdgt=15, or a too small timestep, for that matter. Still, plotwinsize=0 is probably the greatest help. #Grebu: Avoid behavioural sources as they are prone to dynamic range erros. For ex., in your case, a waveform that goes from 0 to inf will have it's higher values severely truncated, progessively. If you want integration use G+C combination. Add a tline for a definite integration. – a concerned citizen Sep 2 '16 at 12:19

Setup

According to the comments from PlasmaHH, a concerned citizen and my assumptions there are several possible error sources. Therefore I modified the SPICE simulation to do parameter sweeps over frequency and amplitude of the sine wave, as can be seen in the next figure. Additionally maximum timestep and numdgt were adjusted manually.

The image shows a normal voltage source V1 set to produce a sine wave. The last set used such a source, while the other two sets used an arbitrary voltage source as in the question.

Results
Setting a smaller maximum timestep reduced the Error of the energy tracking arbitrary voltage source (Error E_a) to negligble values, when tracking an arbitrary source. The error from calculating the energy directly (Error E_t) was reduced as well, but was still significant at 10 kHz when using a maximum timestep of 10 µs.
The differences between numdgt = 15 and numdgt = 6 have no impact on the error down to 0.01 %. Using a normal voltage source V1 reduces the error of outliers (e.g. at 10 kHz), while it elsewise decreases the accuracy of the tracking arbitrary voltage source.

Conclusion
For the given circuit tracking the power of the source with an arbitrary voltage source at 10 µs or faster leads to a good compromise in accuracy and speed.
When calculating the energy directly (.meas E INTEG V*I), a fine maximum timestep has to be used, in this case 2 µs.

Data
• I think the latter, but just to confirm, was the timestep adapted to the frequency, or fixed? As in {timestep/frequency} or just {timestep}? If the latter, it's only normal you should get those errors as you increase the frequency, else you would have gotten more consistent results. Either way, G+C shouldn't give too different results compared to idt(), given a small enough timestep (and maybe patience). This was an interesting test. I never used INTEG from .MEAS, but it's interesting to note the differences that lie underneath different methods. – a concerned citizen Sep 6 '16 at 8:06