felix-andreas / apace

Another Particle Accelerator Code
https://apace.readthedocs.io
GNU General Public License v3.0
7 stars 1 forks source link

Rounding error in floating point numbers for `length` attribute #69

Open felix-andreas opened 4 years ago

felix-andreas commented 4 years ago

Maybe it is better to use Decimal floating point numbers instead of the default binary floating point numbers. Another possiblity would be to use mm and an int type to store the length.

For the length attribute, the wrong representation of decimal numbers can become a problem: When accumulating the element ending position for a FODO lattice

{
  "name": "FODO_RING",
  "description": "This is the simplest possible strong focusing lattice.",
  "elements": {
    "D1": ["Drift", {"length": 0.55}],
    "Q1": ["Quadrupole", {"length": 0.2, "k1": 1.2}],
    "Q2": ["Quadrupole", {"length": 0.4, "k1": -1.2}],
    "B1": ["Dipole", {"length": 1.5, "angle": 0.392701, "e1": 0.1963505, "e2": 0.1963505}]
  },
  "sub_lattices": {
    "FODO": ["Q1", "D1", "B1", "D1", "Q2", "D1", "B1", "D1", "Q1"]
  },
  "lattice": ["FODO", "FODO", "FODO", "FODO", "FODO", "FODO", "FODO", "FODO"]
}

the length of the first cell gets calculated correctly. Cells beginning with the 6th cell have the wrong length:

First cell:
------------
end 0.75 D1
end 2.25 B1
end 2.8 D1
end 3.1999999999999997 Q2
end 3.75 D1
end 5.25 B1
end 5.8 D1
end 6.0 Q1
...
6th cell:
----------
end 30.200000000000003 Q1
end 30.750000000000004 D1
end 32.25 B1
end 32.8 D1
end 33.199999999999996 Q2
...
8th cell:
end 47.799999999999976 D1
end 47.99999999999998 Q1

The problem is, that this is inconsistent with the length attribute of the ring:

>>> ap.Lattice.from_file("fodo_ring.json").length
48.0

which, returns the "correct" length. This is because the Lattice object will add the length of all its sub_lattices (which have length 6.0) instead of adding the length of all its elements (like shown above).