Skip to content

Terminating terms change near-field edge-radiation flux by 30% - which setting is correct? #63

Description

@Anatoly1010

Environment: srwpy 4.2.1 from PyPI, Python 3.13, Windows.

I am computing the far-infrared flux collected by a mirror placed close to a bending magnet, for an IR beamline on a 3 GeV fourth-generation ring. The mirror is pushed 14 mm off the electron beam in the horizontal plane and sits 0.365 m downstream of the end of the magnetic structure, so the radiation it collects is edge radiation observed in the near field. At 10 um the formation length lambda*gamma^2/(2*pi) is about 55 m, far larger than any distance in the layout, and the mirror subtends 1.9 to 10 mrad, so gamma*theta runs from 11 to 60.

useTermin changes the answer by about 30% in this geometry, and I cannot tell which setting to trust.

case useTermin=1 useTermin=0
single magnet 0.52 T, 1.02 m, centre at z = -6.83 m 15.4 20.0
same magnet at z = -3.83 m 32.1 36.9
same magnet at z = -0.83 m 93.2 119.9

numbers are in 1e12 ph/s/0.1%bw.

For comparison, in the geometry of the official SRWLIB_Example13 (0.4 T, 4 m long magnet, screen at 5 m) the same switch is worth only 0.5%: 71.00 against 71.38. So the two settings agree where the example lives and disagree badly where I need the answer.

Three specific questions.

1. Which setting is right when the collected radiation is edge radiation in the near field?

The example sets useTermin = 1 with automatic integration limits and uses a magnet deliberately made long "to avoid observing eventual edge radiation". My case is the opposite: the edge is the source. Extending the integration range does not resolve it, because with useTermin = 0 the result is stable to about 1% against moving either limit (19.75, 19.91, 19.97, 19.79 for zEndInteg = 0.10, 0.20, 0.30, 0.34 m; unchanged when zStartInteg goes from -9.83 m to -20 m) yet still differs from the useTermin = 1 value by 30%.

2. Does the validity of the asymptotic expansion depend on the observation angle as well as the distance?

Moving the observation plane out to 1.0 and 2.7 formation lengths at fixed angular acceptance does not make the two settings converge; the ratio goes 1.300, 1.315, 1.324, drifting slightly away from 1.

3. The warning appears to be mesh dependent.

For the magnet at z = -0.83 m I get

Warning: Computation of terminating terms of radiation integrals WAS NOT PERFORMED for some values 
of input parameters because asymptotic expansion validity criterion was not satisfied.

and the flux is 93.2 with hand-set limits [-3.83, 0.3] but 898.7 with automatic limits [0, 0], a factor of ten, from the same magnet and the same observation mesh. Since the terms are skipped only "for some values of input parameters", the result mixes points computed with and without them. Is there a way to make the criterion pass for a geometry like this, or should useTermin = 0 be used whenever the warning appears?

Minimal reproducer

from array import array
from copy import deepcopy

import numpy as np
from srwpy.srwlib import SRWLMagFldC, SRWLMagFldM, SRWLPartBeam, SRWLWfr, srwl

WAVELENGTH_UM = 10.0
SCREEN_Z = 0.365                      # mirror plane [m]
MESH_X = (0.0140, 0.0730)             # mirror, 14 mm off the beam [m]
MESH_Y = (-0.02915, 0.02915)


def beam():
    b = SRWLPartBeam()
    b.from_Twiss(_Iavg=0.4, _e=3.0, _sig_e=0.001, _beta_x=15.2, _beta_y=2.8,
                 _emit_x=75e-12, _emit_y=75e-13)
    return b


def flux(field, integ, use_termin, samp_fact=1.0):
    wfr = SRWLWfr()
    wfr.allocate(1, 400, 400)
    wfr.mesh.zStart = SCREEN_Z
    wfr.mesh.eStart = wfr.mesh.eFin = 1239.8 / WAVELENGTH_UM / 1000.0
    (wfr.mesh.xStart, wfr.mesh.xFin) = MESH_X
    (wfr.mesh.yStart, wfr.mesh.yFin) = MESH_Y
    wfr.partBeam = beam()
    z0, z1 = integ
    srwl.CalcElecFieldSR(wfr, 0, field,
                         [2, 0.005, z0, z1, 20000, use_termin, samp_fact])
    mesh = deepcopy(wfr.mesh)
    ar = array('f', [0] * mesh.nx * mesh.ny)
    srwl.CalcIntFromElecField(ar, wfr, 6, 0, 3, mesh.eStart, 0, 0)
    img = np.array(ar, dtype=float).reshape(mesh.ny, mesh.nx)
    x = np.linspace(mesh.xStart, mesh.xFin, mesh.nx) * 1000.0
    y = np.linspace(mesh.yStart, mesh.yFin, mesh.ny) * 1000.0
    return np.trapezoid(np.trapezoid(img, x, axis=1), y) / 1e12


def one_magnet(z):
    return SRWLMagFldC([SRWLMagFldM(0.52, 1, 'n', 1.02)], [0], [0], [z])


for z, integ in ((-6.83, (-9.83, 0.3)), (-3.83, (-6.83, 0.3)),
                 (-0.83, (-3.83, 0.3)), (-0.83, (0.0, 0.0))):
    f = one_magnet(z)
    print('magnet at z=%6.2f m, limits %-14s  useTermin=1 %8.2f   useTermin=0 %8.2f'
          % (z, str(integ), flux(f, integ, 1), flux(f, integ, 0)))

Output:

magnet at z= -6.83 m, limits (-9.83, 0.3)   useTermin=1    15.36   useTermin=0    19.97
magnet at z= -3.83 m, limits (-6.83, 0.3)   useTermin=1    32.14   useTermin=0    36.85
magnet at z= -0.83 m, limits (-3.83, 0.3)   useTermin=1    93.19   useTermin=0   119.87
magnet at z= -0.83 m, limits (0.0, 0.0)     useTermin=1   898.72   useTermin=0    90.82

The last two lines carry the warning.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions