kklmn / xrt

Package xrt (XRayTracer) is a python software library for ray tracing and wave propagation in x-ray regime. It is primarily meant for modeling synchrotron sources, beamlines and beamline elements.
MIT License
84 stars 30 forks source link

Dynamically figured KB mirrors #197

Open phansandra opened 2 months ago

phansandra commented 2 months ago

Hi! I'm modelling a KB focusing system. It includes two trapezoidal mirrors bent elliptically by rods that apply force on both ends. Curvature of the mirror increases linearly toward the narrow end, as the cross-sectional area gets smaller. We routinely refocus these mirrors to correct for astigmatism at different energies, and would like our model to represent cases when a mirror is not perfectly elliptical.

I defined an equation for curvature parameterized by arc (mirror) length. It's a function of the two applied forces from the bender rods. Other physical properties, like elasticity and position of applied forces, are known and constant. Now, I'm trying to add a custom class in XRT for these mirrors and this is where I see a few options:

  1. By twice integrating the equation for curvature parameterized by arc length (with some other steps), I get a 2D vector equation that maps the mirror profile. I can refer to how EllipticalMirrorParam is defined and create a similar class that uses this map to find where rays intersect the mirror in local coordinates.
  2. I can work off the class ToroidMirror, and instead of getting R from the Coddington equations, I can get R by taking the inverse of my equation for curvature. Then, I think I would need new definitions for local_z and local_n. How are the current definitions under ToroidMirror derived?
  3. I can implement the KB mirrors as an instance of EllipticalMirrorParam, and then add a method for distorted local coordinates as is described in the docs. My understanding is that this approach is best if I have experimental data for distortion, which I may be able to arrange if you think the first two options are too complicated.

Could you let me know if any of these approaches seems most reasonable to you? Please let me know if I can be clearer in any part of my description.

kklmn commented 2 months ago

Hi,

As your mirror is not a closed shape (like a capillary) and you know the mirror’s n (normal) and z (height) as functions of x and y, you don’t need a parametric representation and you don’t need to start from a ready mirror class, such as EllipticalMirrorParam or ToroidMirror. I would subclass directly from OE and redefine local_n(x, y) as ~ln(b-ay), where the trapezoidal mirror width = b – ay, and local_z(x, y) as ~y ln(b-ay) +cy. If you need to supply some geometric parameters to the mirror class, you can modify its __init__().

If you have troubles with subclassing, ask again.

phansandra commented 2 months ago

Thank you, Konstantin. I'll let you know how it goes.