{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "4d8ff990-9a7c-49d1-8fe7-a1d56543240a", "metadata": {}, "source": [ "# Example-09: Multipole (element)" ] }, { "cell_type": "code", "execution_count": 1, "id": "74c4a0c7-598d-4c1f-8925-213b1ea492c5", "metadata": {}, "outputs": [], "source": [ "# Comparison of sextupole element with MADX-PTC and other features" ] }, { "cell_type": "code", "execution_count": 2, "id": "535639b7-4c2c-4f7b-add8-003a5c23673f", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "from os import system\n", "\n", "import torch\n", "from model.library.multipole import Multipole" ] }, { "cell_type": "code", "execution_count": 3, "id": "434e29d7-258f-4dc3-8cd4-d71e386aaf02", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.00892946929535585, 0.0009165531774213284, -0.0017930189940976037, 0.01128986832436645]\n", "[0.008929469295355376, 0.0009165531774212371, -0.001793018994097562, 0.011289868324366148]\n", "[4.735795089416683e-16, 9.128982292327947e-17, -4.163336342344337e-17, 3.0184188481996443e-16]\n" ] } ], "source": [ "# Tracking (paraxial)\n", "\n", "ptc = Path('ptc')\n", "obs = Path('track.obs0001.p0001')\n", "\n", "exact = False\n", "align = False\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "dp = 0.005\n", "length = 0.5\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "qx, px, qy, py = state.tolist()\n", "\n", "dx = align*torch.tensor(0.05, dtype=torch.float64)\n", "dy = align*torch.tensor(-0.02, dtype=torch.float64)\n", "dz = align*torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = align*torch.tensor(0.005, dtype=torch.float64)\n", "wy = align*torch.tensor(-0.005, dtype=torch.float64)\n", "wz = align*torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "code = f\"\"\"\n", "mag:quadrupole,l={length},knl={{0.0,{kn*length},{ms*length},{mo*length}}},ksl={{0.0,{ks*length}}};\n", "map:line=(mag) ;\n", "beam,energy=1.0E+6,particle=electron ;\n", "set,format=\"20.20f\",\"-20s\" ;\n", "use,period=map ;\n", "select,flag=error,pattern=\"mag\" ;\n", "ealign,dx={dx.item()},dy={dy.item()},ds={dz.item()},dphi={wx.item()},dtheta={wy.item()},dpsi={wz.item()} ;\n", "ptc_create_universe,sector_nmul_max=10,sector_nmul=10 ;\n", "ptc_create_layout,model=1,method=6,nst=1000,exact={str(exact).lower()} ;\n", "ptc_setswitch,fringe=false,time=true,totalpath=true,exact_mis=true ;\n", "ptc_align ;\n", "ptc_start,x={qx},px={px},y={qy},py={py},pt={dp},t=0.0 ;\n", "ptc_track,icase=5,deltap=0.,turns=1,file=track,maxaper={{1.,1.,1.,1.,1.,1.}} ;\n", "ptc_track_end ;\n", "ptc_end ;\n", "\"\"\" \n", "\n", "with ptc.open('w') as stream:\n", " stream.write(code)\n", " \n", "system(f'madx < {str(ptc)} > /dev/null')\n", "\n", "with obs.open('r') as stream:\n", " for line in stream:\n", " continue\n", " _, _, qx, px, qy, py, *_ = line.split()\n", " \n", "ref = torch.tensor([float(x) for x in (qx, px, qy, py)], dtype=torch.float64)\n", "\n", "M = Multipole('M', length=length, kn=kn, ks=ks, ms=ms, mo=mo, dp=dp, exact=exact, order=5, ns=10)\n", "res = M(state, alignment=align, data={**M.data(), **error})\n", "\n", "print(ref.tolist())\n", "print(res.tolist())\n", "print((ref - res).tolist())\n", "\n", "ptc.unlink()\n", "obs.unlink()" ] }, { "cell_type": "code", "execution_count": 4, "id": "809b8da7-afa1-4bb9-911c-b44be96489c9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.00892945162589142, 0.0009165626425029898, -0.0017929090323601758, 0.011289834389170184]\n", "[0.008929451625891005, 0.0009165626425029993, -0.001792909032360122, 0.01128983438916985]\n", "[4.145989107584569e-16, -9.432558900623889e-18, -5.377642775528102e-17, 3.3480163086352377e-16]\n" ] } ], "source": [ "# Tracking (exact)\n", "\n", "ptc = Path('ptc')\n", "obs = Path('track.obs0001.p0001')\n", "\n", "exact = True\n", "align = False\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "dp = 0.005\n", "length = 0.5\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "qx, px, qy, py = state.tolist()\n", "\n", "dx = align*torch.tensor(0.05, dtype=torch.float64)\n", "dy = align*torch.tensor(-0.02, dtype=torch.float64)\n", "dz = align*torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = align*torch.tensor(0.005, dtype=torch.float64)\n", "wy = align*torch.tensor(-0.005, dtype=torch.float64)\n", "wz = align*torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "code = f\"\"\"\n", "mag:quadrupole,l={length},knl={{0.0,{kn*length},{ms*length},{mo*length}}},ksl={{0.0,{ks*length}}};\n", "map:line=(mag) ;\n", "beam,energy=1.0E+6,particle=electron ;\n", "set,format=\"20.20f\",\"-20s\" ;\n", "use,period=map ;\n", "select,flag=error,pattern=\"mag\" ;\n", "ealign,dx={dx.item()},dy={dy.item()},ds={dz.item()},dphi={wx.item()},dtheta={wy.item()},dpsi={wz.item()} ;\n", "ptc_create_universe,sector_nmul_max=10,sector_nmul=10 ;\n", "ptc_create_layout,model=1,method=6,nst=1000,exact={str(exact).lower()} ;\n", "ptc_setswitch,fringe=false,time=true,totalpath=true,exact_mis=true ;\n", "ptc_align ;\n", "ptc_start,x={qx},px={px},y={qy},py={py},pt={dp},t=0.0 ;\n", "ptc_track,icase=5,deltap=0.,turns=1,file=track,maxaper={{1.,1.,1.,1.,1.,1.}} ;\n", "ptc_track_end ;\n", "ptc_end ;\n", "\"\"\" \n", "\n", "with ptc.open('w') as stream:\n", " stream.write(code)\n", " \n", "system(f'madx < {str(ptc)} > /dev/null')\n", "\n", "with obs.open('r') as stream:\n", " for line in stream:\n", " continue\n", " _, _, qx, px, qy, py, *_ = line.split()\n", " \n", "ref = torch.tensor([float(x) for x in (qx, px, qy, py)], dtype=torch.float64)\n", "\n", "M = Multipole('M', length=length, kn=kn, ks=ks, ms=ms, mo=mo, dp=dp, exact=exact, order=5, ns=10)\n", "res = M(state, alignment=align, data={**M.data(), **error})\n", "\n", "print(ref.tolist())\n", "print(res.tolist())\n", "print((ref - res).tolist())\n", "\n", "ptc.unlink()\n", "obs.unlink()" ] }, { "cell_type": "code", "execution_count": 5, "id": "6d83f9c6-115f-450e-9d02-c2077a8862ae", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.001664975746516068, -0.04016261215593401, -0.015906155451718536, -0.05363979979736713]\n", "[0.0016649757465192622, -0.04016261215593149, -0.015906155451718116, -0.053639799797364655]\n", "[-3.194059600142296e-15, -2.518818487118324e-15, -4.198030811863873e-16, -2.4771851236948805e-15]\n" ] } ], "source": [ "# Tracking (exact, alignment)\n", "\n", "ptc = Path('ptc')\n", "obs = Path('track.obs0001.p0001')\n", "\n", "exact = True\n", "align = True\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "dp = 0.005\n", "length = 0.5\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "qx, px, qy, py = state.tolist()\n", "\n", "dx = align*torch.tensor(0.05, dtype=torch.float64)\n", "dy = align*torch.tensor(-0.02, dtype=torch.float64)\n", "dz = align*torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = align*torch.tensor(0.005, dtype=torch.float64)\n", "wy = align*torch.tensor(-0.005, dtype=torch.float64)\n", "wz = align*torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "code = f\"\"\"\n", "mag:quadrupole,l={length},knl={{0.0,{kn*length},{ms*length},{mo*length}}},ksl={{0.0,{ks*length}}};\n", "map:line=(mag) ;\n", "beam,energy=1.0E+6,particle=electron ;\n", "set,format=\"20.20f\",\"-20s\" ;\n", "use,period=map ;\n", "select,flag=error,pattern=\"mag\" ;\n", "ealign,dx={dx.item()},dy={dy.item()},ds={dz.item()},dphi={wx.item()},dtheta={wy.item()},dpsi={wz.item()} ;\n", "ptc_create_universe,sector_nmul_max=10,sector_nmul=10 ;\n", "ptc_create_layout,model=1,method=6,nst=1000,exact={str(exact).lower()} ;\n", "ptc_setswitch,fringe=false,time=true,totalpath=true,exact_mis=true ;\n", "ptc_align ;\n", "ptc_start,x={qx},px={px},y={qy},py={py},pt={dp},t=0.0 ;\n", "ptc_track,icase=5,deltap=0.,turns=1,file=track,maxaper={{1.,1.,1.,1.,1.,1.}} ;\n", "ptc_track_end ;\n", "ptc_end ;\n", "\"\"\" \n", "\n", "with ptc.open('w') as stream:\n", " stream.write(code)\n", " \n", "system(f'madx < {str(ptc)} > /dev/null')\n", "\n", "with obs.open('r') as stream:\n", " for line in stream:\n", " continue\n", " _, _, qx, px, qy, py, *_ = line.split()\n", " \n", "ref = torch.tensor([float(x) for x in (qx, px, qy, py)], dtype=torch.float64)\n", "\n", "M = Multipole('M', length=length, kn=kn, ks=ks, ms=ms, mo=mo, dp=dp, exact=exact, order=5, ns=10)\n", "res = M(state, alignment=align, data={**M.data(), **error})\n", "\n", "print(ref.tolist())\n", "print(res.tolist())\n", "print((ref - res).tolist())\n", "\n", "ptc.unlink()\n", "obs.unlink()" ] }, { "cell_type": "code", "execution_count": 6, "id": "13c33b3f-626b-420e-8ab0-6d344954377d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([ 0.0092, -0.0028, -0.0043, 0.0055], dtype=torch.float64)\n", "\n", "tensor([ 0.0100, -0.0050, -0.0050, 0.0010], dtype=torch.float64)\n", "\n", "tensor([ 0.0085, -0.0159, -0.0060, -0.0224], dtype=torch.float64)\n", "\n", "tensor([0., 0., 0., 0.], dtype=torch.float64)\n" ] } ], "source": [ "# Deviation/error variables\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp)\n", "\n", "# Each element has two variant of a call method\n", "# In the first case only state is passed, it is transformed using parameters specified on initializaton\n", "\n", "print(M(state))\n", "print()\n", "\n", "# Deviation errors can be also passed to call method\n", "# These variables are added to corresponding parameters specified on initializaton\n", "# For example, element lenght can changed\n", "\n", "print(M(state, data={**M.data(), **{'dl': -M.length}}))\n", "print()\n", "\n", "# In the above M.data() creates default deviation dictionary (with zero values for each deviaton)\n", "# {**M.data(), **{'dl': -M.length}} replaces the 'dl' key value \n", "\n", "# Additionaly, alignment errors are passed as deivation variables\n", "# They are used if alignment flag is raised\n", "\n", "print(M(state, data={**M.data(), **error}, alignment=True))\n", "print()\n", "\n", "# The following elements can be made equivalent using deviation variables\n", "\n", "MA = Multipole('MA', length, kn, ks, ms, mo, dp)\n", "MB = Multipole('MB', length - 0.1, kn, ks, ms, mo, dp)\n", "\n", "print(MA(state) - MB(state, data={**MB.data(), **{'dl': torch.tensor(+0.1, dtype=MB.dtype)}}))\n", "\n", "# Note, while in some cases float values can be passed as values to deviation variables\n", "# The correct behaviour in guaranteed only for tensors" ] }, { "cell_type": "code", "execution_count": 7, "id": "11581ee4-60ec-4537-8bd1-13115a1797ee", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([ 6.9389e-18, -1.8792e-04, 8.6736e-19, -2.5229e-04],\n", " dtype=torch.float64)\n", "tensor([ 6.9389e-18, -4.3368e-18, 8.6736e-19, -8.6736e-19],\n", " dtype=torch.float64)\n", "tensor([-0.0004, 0.0009, 0.0002, 0.0021], dtype=torch.float64)\n", "tensor([-7.9785e-07, -1.9093e-04, -5.6642e-07, -2.5071e-04],\n", " dtype=torch.float64)\n" ] } ], "source": [ "# Insertion element\n", "\n", "# In this mode elements are treated as thin insertions (at the center)\n", "# Using parameters specified on initialization, transport two matrices are computed\n", "# These matrices are used to insert the element\n", "# Input state is transformed from the element center to its entrance\n", "# Next, transformation from the entrance frame to the exit frame is performed\n", "# This transformation can contain errors\n", "# The final step is to transform state from the exit frame back to the element center\n", "# Without errors, this results in identity transformation for linear elements\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, exact=False, insertion=True)\n", "\n", "# Since multipole is a nonlinear element (non-zero sextupole or octupole)\n", "# Insertion is an identity transformation only for zero strenght\n", "\n", "print(M(state) - state)\n", "print(M(state, data={**M.data(), **{'ms': -ms, 'mo': -mo}}) - state)\n", "\n", "# Represents effect of an error (any nonzero value of strengh or a change in other parameter)\n", "\n", "print(M(state, data={**M.data(), **{'dl': 0.1}}) - state)\n", "\n", "# Exact tracking corresponds to inclusion of kinematic term as errors\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, exact=True, insertion=True, ns=20, order=1)\n", "\n", "print(M(state) - state)" ] }, { "cell_type": "code", "execution_count": 8, "id": "7eb566c4-098a-4009-b532-25b7d35580b3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([512, 4])\n", "torch.Size([512, 4])\n" ] } ], "source": [ "# Mapping over a set of initial conditions\n", "\n", "# Call method can be used to map over a set of initial conditions\n", "# Note, device can be set to cpu or gpu via base element classvariables\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, exact=True)\n", "\n", "state = 1.0E-3*torch.randn((512, 4), dtype=M.dtype, device=M.device)\n", "\n", "print(torch.vmap(M)(state).shape)\n", "\n", "# To map over deviations parameters a wrapper function (or a lambda expression) can be used\n", "\n", "def wrapper(state, dp):\n", " return M(state, data={**M.data(), **{'dp': dp}})\n", "\n", "dp = 1.0E-3*torch.randn(512, dtype=M.dtype, device=M.device)\n", "\n", "print(torch.vmap(wrapper)(state, dp).shape)" ] }, { "cell_type": "code", "execution_count": 9, "id": "03d8cd2c-3bda-4a0d-b50c-5c3367bb295a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[ 1.0353, 0.2012, 0.0274, 0.0017],\n", " [ 0.3588, 1.0353, 0.2757, 0.0274],\n", " [ 0.0274, 0.0017, 0.9653, 0.1969],\n", " [ 0.2757, 0.0274, -0.3449, 0.9653]], dtype=torch.float64)\n", "\n", "tensor([-1.9468e-04, -1.9487e-03, -9.6920e-05, -9.5528e-04],\n", " dtype=torch.float64)\n", "\n" ] } ], "source": [ "# Differentiability\n", "\n", "# Both call methods are differentiable\n", "# Derivative with respect to state can be computed directly\n", "# For deviation variables, wrapping is required\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, exact=False)\n", "\n", "# Compute derivative with respect to state\n", "\n", "print(torch.func.jacrev(M)(state))\n", "print()\n", "\n", "# Compute derivative with respect to a deviation variable\n", "\n", "kn = torch.tensor(0.0, dtype=torch.float64)\n", "\n", "def wrapper(state, kn):\n", " return M(state, data={**M.data(), **{'kn': kn}})\n", "\n", "print(torch.func.jacrev(wrapper, 1)(state, kn))\n", "print()" ] }, { "cell_type": "code", "execution_count": 10, "id": "29d6f709-6ac4-4ae0-9a6c-b3212c73ae47", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([ 0.0092, -0.0028, -0.0043, 0.0055], dtype=torch.float64)\n", "torch.Size([10, 4])\n", "torch.Size([10, 4, 4])\n", "torch.Size([100, 4])\n", "torch.Size([100, 4, 4])\n" ] } ], "source": [ "# Output at each step\n", "\n", "# It is possible to collect output of state or tangent matrix at each integration step\n", "# Number of integratin steps is controlled by ns parameter on initialization\n", "# Alternatively, desired integration step length can be passed\n", "# Number of integration steps is computed as ceil(length/ds)\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, exact=False, ns=10, output=True, matrix=True)\n", "\n", "# Final state is still returned\n", "\n", "print(M(state))\n", "\n", "# Data is added to special attributes (state and tangent matrix)\n", "\n", "print(M.container_output.shape)\n", "print(M.container_matrix.shape)\n", "\n", "# Number of integration steps can be changed\n", "\n", "M.ns = 100\n", "\n", "M(state)\n", "print(M.container_output.shape)\n", "print(M.container_matrix.shape)" ] }, { "cell_type": "code", "execution_count": 11, "id": "d55de70e-1c88-4df3-b05e-4f11d42a3c96", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.009228705737231328, -0.002766282719416843, -0.004341639948599635, 0.005542200849934217]\n", "[0.009228699312521686, -0.0027663108074714475, -0.004341646792491436, 0.00554221421387834]\n", "[6.424709642766091e-09, 2.808805460441377e-08, 6.843891801368296e-09, -1.3363944122331273e-08]\n", "\n", "[0, 1, 2, 1, 0]\n", "[0.5, 0.5, 1.0, 0.5, 0.5]\n" ] } ], "source": [ "# Integration order is set on initialization (default value is zero)\n", "# This order is related to difference order as 2n + 2\n", "# Thus, zero corresponds to second order difference method\n", "\n", "kn = - 2.0\n", "ks = + 1.5\n", "ms = 25.0\n", "mo = 110.0\n", "mo = 50.0\n", "dp = 0.005\n", "length = 0.2\n", "state = torch.tensor([0.01, -0.005, -0.005, 0.001], dtype=torch.float64)\n", "\n", "dx = torch.tensor(0.05, dtype=torch.float64)\n", "dy = torch.tensor(-0.02, dtype=torch.float64)\n", "dz = torch.tensor(0.05, dtype=torch.float64)\n", "\n", "wx = torch.tensor(0.005, dtype=torch.float64)\n", "wy = torch.tensor(-0.005, dtype=torch.float64)\n", "wz = torch.tensor(0.1, dtype=torch.float64)\n", "\n", "error = {'dx': dx, 'dy': dy, 'dz': dz, 'wx': wx, 'wy': wy, 'wz': wz}\n", "\n", "M = Multipole('M', length, kn, ks, ms, mo, dp, order=0, exact=True)\n", "\n", "# For multipole with non-zero sextupole and/or octupole integration is always performed\n", "# In exact case, kinematic term error is added\n", "\n", "M.ns = 10\n", "ref = M(state)\n", "\n", "M.ns = 100\n", "res = M(state)\n", "\n", "print(ref.tolist())\n", "print(res.tolist())\n", "print((ref - res).tolist())\n", "print()\n", "\n", "# Integrator parameters are stored in data attribute (if integration is actually performed)\n", "\n", "maps, weights = M._data\n", "print(maps)\n", "print(weights)" ] } ], "metadata": { "colab": { "collapsed_sections": [ "myt0_gMIOq7b", "5d97819c" ], "name": "03_frequency.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.1" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false } }, "nbformat": 4, "nbformat_minor": 5 }