|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# |
| 3 | +# Copyright 2022-2023 ImpactX contributors |
| 4 | +# Authors: Axel Huebl, Chad Mitchell |
| 5 | +# License: BSD-3-Clause-LBNL |
| 6 | +# |
| 7 | + |
| 8 | +import math |
| 9 | + |
| 10 | +import numpy as np |
| 11 | +import openpmd_api as io |
| 12 | + |
| 13 | +# initial/final beam |
| 14 | +series = io.Series("diags/openPMD/monitor.h5", io.Access.read_only) |
| 15 | +last_step = list(series.iterations)[-1] |
| 16 | +initial = series.iterations[1].particles["beam"].to_df() |
| 17 | +beam_final = series.iterations[last_step].particles["beam"] |
| 18 | +final = beam_final.to_df() |
| 19 | + |
| 20 | +# Basic input parameters |
| 21 | +g = 1.0e-3 |
| 22 | +phi = math.pi / 8.0 |
| 23 | +rc = 10.0 |
| 24 | +R = 1.0 |
| 25 | +K0 = math.pi**2 / 6.0 |
| 26 | +K3 = 1.0 / 6.0 |
| 27 | +Kar = [K0, 0, 0, K3, 0, 0, 0] |
| 28 | +delta = 0.0 |
| 29 | + |
| 30 | +# Derived quantities |
| 31 | +cs = math.cos(phi) |
| 32 | +sn = math.sin(phi) |
| 33 | +tn = sn / cs |
| 34 | +sc = 1.0 / cs |
| 35 | + |
| 36 | +# Lie generator coefficients |
| 37 | +c1 = g * Kar[1] / (rc * cs) |
| 38 | +c2 = sn * g**2 * Kar[0] / rc**2 * 1.0 / (2.0 * cs**3 * (1 + delta)) |
| 39 | +c3 = g**2 / rc * Kar[0] / (cs**2 * (1 + delta)) |
| 40 | +c4 = 1 / (1 + delta) * g / rc * Kar[1] * sn / cs**2 |
| 41 | +c5 = sn / cs * 1.0 / (2 * rc) |
| 42 | +c6 = g * Kar[1] / rc * sn**2 / (4 * rc * (1 + delta) * cs**3) |
| 43 | +c7 = ( |
| 44 | + 1 |
| 45 | + / (2 * cs**3 * (1 + delta)) |
| 46 | + * (g * Kar[1] / (2 * rc**2) + (1 + sn**2) * g / rc**2 * Kar[2]) |
| 47 | +) |
| 48 | +c8 = 1 / 6 * tn**3 / (2 * rc**2 * (1 + delta)) |
| 49 | +c9 = 1 / 2 * (tn * sc**2 / (2 * rc**2 * (1 + delta))) |
| 50 | +c10 = 1 / (2 * (1 + delta)) * tn**2 / rc |
| 51 | +c11 = 1 / (2 * rc * (1 + delta)) |
| 52 | +c12 = 1 / 24 * (4 / cs - 8 / cs**3) * Kar[3] / (rc**2 * g * (1 + delta)) |
| 53 | +c13 = sn**2 / (2 * cs**3) * g**2 / (rc * R) * Kar[4] |
| 54 | +c14 = 1 / 2 * sn / cs**3 * g / (rc * R) * Kar[5] |
| 55 | +c15 = Kar[6] / (rc * R) * 1 / cs**3 |
| 56 | + |
| 57 | +xi = initial["position_x"] |
| 58 | +pxi = initial["momentum_x"] |
| 59 | +yi = initial["position_y"] |
| 60 | +pyi = initial["momentum_y"] |
| 61 | +ti = initial["position_t"] |
| 62 | +pti = initial["momentum_t"] |
| 63 | + |
| 64 | +Omega_initial = ( |
| 65 | + xi * c1 |
| 66 | + - xi * c2 |
| 67 | + + pxi * c3 |
| 68 | + + (xi * pxi - yi * pyi) * c4 |
| 69 | + + (xi**2 - yi**2) * c5 |
| 70 | + - xi**2 * c6 |
| 71 | + + yi**2 * c7 |
| 72 | + - xi**3 * c8 |
| 73 | + + xi * yi**2 * c9 |
| 74 | + + (xi**2 * pxi - yi**2 * pxi - 2 * xi * yi * pyi) * c10 |
| 75 | + - yi**2 * pxi * c11 |
| 76 | + + yi**4 * c12 |
| 77 | + + xi * c13 |
| 78 | + + (yi**2 - xi**2) * c14 |
| 79 | + + (xi * yi**2 / 2 - xi**3 / 6) * c15 |
| 80 | +) |
| 81 | + |
| 82 | +xf = final["position_x"] |
| 83 | +pxf = final["momentum_x"] |
| 84 | +yf = final["position_y"] |
| 85 | +pyf = final["momentum_y"] |
| 86 | +tf = final["position_t"] |
| 87 | +ptf = final["momentum_t"] |
| 88 | + |
| 89 | +Omega_final = ( |
| 90 | + xf * c1 |
| 91 | + - xf * c2 |
| 92 | + + pxf * c3 |
| 93 | + + (xf * pxf - yf * pyf) * c4 |
| 94 | + + (xf**2 - yf**2) * c5 |
| 95 | + - xf**2 * c6 |
| 96 | + + yf**2 * c7 |
| 97 | + - xf**3 * c8 |
| 98 | + + xf * yf**2 * c9 |
| 99 | + + (xf**2 * pxf - yf**2 * pxf - 2 * xf * yf * pyf) * c10 |
| 100 | + - yf**2 * pxf * c11 |
| 101 | + + yf**4 * c12 |
| 102 | + + xf * c13 |
| 103 | + + (yf**2 - xf**2) * c14 |
| 104 | + + (xf * yf**2 / 2 - xf**3 / 6) * c15 |
| 105 | +) |
| 106 | + |
| 107 | +Delta_Omega = (Omega_final - Omega_initial).abs() |
| 108 | + |
| 109 | +dx = (xf - xi).abs().max() |
| 110 | +dpx = (pxf - pxi).abs().max() |
| 111 | +dy = (yf - yi).abs().max() |
| 112 | +dpy = (pyf - pyi).abs().max() |
| 113 | +dt = (tf - ti).abs().max() |
| 114 | +dpt = (ptf - pti).abs().max() |
| 115 | + |
| 116 | +print("Change in the coordinates and momenta:") |
| 117 | +print("dx", dx) |
| 118 | +print("dpx", dpx) |
| 119 | +print("dy", dy) |
| 120 | +print("dpy", dpy) |
| 121 | +print("dt", dt) |
| 122 | +print("dpt", dpt) |
| 123 | + |
| 124 | +print("Change in the Lie generator, for each initial condition:") |
| 125 | +print(Delta_Omega) |
| 126 | + |
| 127 | +atol = 1.5e-10 |
| 128 | +print(f" atol={atol}") |
| 129 | + |
| 130 | +assert np.allclose( |
| 131 | + [Delta_Omega.max()], |
| 132 | + [ |
| 133 | + 0.0, |
| 134 | + ], |
| 135 | + atol=atol, |
| 136 | +) |
0 commit comments