Why is f1 not equal to zero in this C code for a six spring mass simulation?

  • Thread starter Thread starter Beeza
  • Start date Start date
  • Tags Tags
    Physics
Click For Summary

Discussion Overview

The discussion revolves around a C code simulation of a mass attached to six springs oscillating in three dimensions. Participants explore the unexpected behavior of a variable, f1, which does not equal zero under certain initial conditions, and the implications of floating-point arithmetic and compiler optimizations on the simulation results.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant notes that despite setting initial conditions where y = 0, the variable f1 does not equal zero as expected, yielding a value on the order of 10^(-20).
  • Another participant attributes the small value of f1 to round-off error due to the use of double precision in the compiler.
  • There are mentions of different behaviors observed when using various compiler optimization flags, particularly with GCC.
  • A participant discusses the non-associative nature of floating-point math and how compiler optimizations can affect the order of operations, potentially leading to unexpected results.
  • One participant raises a concern about the conservation of energy in the simulation, suggesting that the total energy appears to oscillate rather than remain constant, indicating potential issues with energy calculations.
  • Another participant suggests simplifying the model to verify energy conservation through controlled oscillation scenarios.
  • A later reply indicates that the original energy calculations were corrected after re-deriving the Lagrangian equations, although the title of the energy plot was noted to be incorrect.

Areas of Agreement / Disagreement

Participants express differing views on the causes of the unexpected behavior in the simulation, particularly regarding floating-point arithmetic and energy conservation. There is no consensus on the exact reasons for the observed discrepancies.

Contextual Notes

Limitations include potential dependencies on compiler behavior, assumptions regarding floating-point precision, and the complexity of the simulation model affecting energy calculations.

Who May Find This Useful

This discussion may be useful for programmers and researchers working with simulations in physics, particularly those interested in the effects of numerical precision and compiler optimizations on computational results.

Beeza
Messages
118
Reaction score
0
I'll try to make this brief and more of a programming question than a physics question-- since I'm nearly positive my physics is correct.

I've written a simulation/code for a mass attached to six springs oscillating in 3-dimensions. The springs are each attached on the standard cartesian x-y-z axis. Take their anchor points to be + or - a on the x-axis. + or - b on the y axis, and + or - c on the z-axis. Now take a = b = c. Now, we should expect that given some initial displacement ONLY in the x-direction, there should be some oscillations only in the x-direction. This is true in my code, but I'm getting extremely small variations in the y and z directions.. oscillations on the order of 10^(-20).

One of the functions is as follows :
double result = 0.0,
f1 = 0.0,
f2 = 0.0,
f3 = 0.0,
f4 = 0.0;

f1 = b * ((y + b) / sqrt(x*x + y*y + z*z + 2.0*b*y + b*b) + (y - b) / sqrt(x*x + y*y + z*z - 2.0*b*y + b*b));
f2 = a * y * (1.0 / sqrt(x*x + y*y + z*z + 2.0*x*a + a*a) + 1.0 / sqrt(x*x + y*y + z*z - 2.0*x*a + a*a));
f3 = c * y * (1.0 / sqrt(x*x + y*y + z*z + 2.0*z*c + c*c) + 1.0 / sqrt(x*x + y*y + z*z -2.0*z*c + c*c));
f4 = 6.0 * y - (f1 + f2 + f3);
// printf ("%e %e %e %e\n", f1, f2, f3, f4);
result = - wo * wo * f4;
return (result);

Now, since given the initial conditions the first time through this function, as expected since y = 0, then f2 = 0 and f3 = 0. BUT, f1 does not equal zero! If we evaluate f1 for y = 0, then analytically equals zero, but the commented out print statement tells me something on the order of approximately 10^(-20). Is this just C being stupid and storing values wayyyy out in the decimals places or am I going crazy here? Have I just been staring at it too long and missed something stupid?
 
Last edited:
Technology news on Phys.org
You're compiler is using double precision, which machine are you using? When I was working with a CRAY, single precision was 16 decimals, double 32. If I remember correctly, on a PC single is 8 and double is 16 depending on the compiler. Now I would chalk up you 10^{-20} to round-off error and your compiler.
 
Thanks Dr. Transport!

I'm just using a PC windows machine with JGrasp as my compiler.

The results are interesting. I expected the trajectory to be much more bizarre.
 

Attachments

I'm getting weird errors too. I'm using GCC. When I add the compilation tag -O3, I get a different error.
 
dimensionless said:
I'm getting weird errors too. I'm using GCC. When I add the compilation tag -O3, I get a different error.


huh? I don't understand.
 
Floating point math is non-associative. More aggressive optimization levels permit the compiler to reorder operations, thus leading to different results.

You're counting on two numbers being identical except for sign and thus perfectly cancelling. That's not happening, indicating that perhaps the two numbers are arrived at with a different order of operations, or different operations are used. Without digging into the assembly, you probably won't know exactly what the compiler and the machine are doing.

On a Pentium-4 type PC (or Athlon, pretty much anything decent sold as a "PC" in the last five years) and with any reasonable compiler, a double means an IEEE-754 double. That's 64 bits. That doesn't map into an exact number of decimal digits, but typically I wouldn't worry too much about a relative error less than 10^{-14}.
 
One would expect a plot of the total energy, call it E, to be constant right? Am I going crazy?

<br /> <br /> E = KE(\dot{x},\dot{y},\dot{z}) + U(x,y,z)<br /> <br />

where U(x,y,z) is the potential energy function of the springs based on how far the mass is displaced from the origin (0,0,0). I'm getting a strange oscillating total energy. It seems as if not all of the potential energy is not being converted to kinetic energy.
 

Attachments

  • hehoo.jpg
    hehoo.jpg
    36.7 KB · Views: 429
Last edited:
If there are no external forces than energy should be conserved.

If your time-marching solution was not conserving energy, most likely the amplitude of the motion would increase with time, or die away to zero.

So I would guess your energy calculations are wrong.

Try making the model simpler, so you know what the "correct" answers are. For example set the springs in the Y and Z directions to zero and simulate

1. Oscillation along the X axis (simple harmonic motion)
2. Oscillation along the Y axis with springs in the X direction only. This is not simple harmonic motion, but you can check that the strain energy in the springs at the maximum displacement is correct.
 
It's fixed. I re-derived all three Lagrangian equations -- What a pain in the neck! Here is the fixed energy plot.. but the title is wrong, it's 10 seconds.

Thanks Alephzero.
 

Attachments

  • postphys.jpg
    postphys.jpg
    52.1 KB · Views: 451
  • #10
Beeza said:
huh? I don't understand.
I tried compiling some C code at the Linux command line. Adding " -O3" to the command tells the compiler to optimize the output executable for faster execution.
 

Similar threads

  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 4 ·
Replies
4
Views
8K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
Replies
1
Views
3K