Skip to content

Commit

Permalink
Merge pull request #1125 from jsberg-bnl/exact-xyrot
Browse files Browse the repository at this point in the history
Make TWISS compute [XY]ROTATION exactly, including linear and second order maps
  • Loading branch information
rdemaria authored Aug 15, 2022
2 parents 78328fc + 3eeaec0 commit e19ca7b
Show file tree
Hide file tree
Showing 33 changed files with 1,433 additions and 174 deletions.
2 changes: 2 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
MAD-X master

* [PR 1125](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1125) Make TWISS treat [XY]ROTATION exactly, including the linear and second order map (J. S. Berg)
* [PR 1123](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1123) Fix errors in the time variable with EXACT flag to TWISS (J. S. Berg)
* [PR 1081](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1108) Fix potential buffer overrun when node_name calls stoupper (J. S. Berg)
* [PR 1107](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1107) Stabizes few tests due to compiler dependent numerical noise (R. De Maria)
Expand Down
5 changes: 3 additions & 2 deletions Makefile_test
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
# added test-twiss-12 for sigma matrix calculation
# 2021-Sep-02 20:59:00 ghislain:
# added test-taper
# 2022-Jul-06 jsberg-bnl:
# added test comparing PTC to TWISS/TRACK for [XY]ROTATION
# 2022-Jun-21 jsberg-bnl:
# added test-twiss-16 for exact TWISS drift compared to PTC
#################################################
# testsuite

# variables:
Expand All @@ -58,7 +59,7 @@ test-track-acd test-track-rotations test-beambeam-npart \
test-twiss test-twiss-2 test-twiss-3 test-twiss-4 test-twiss-5 \
test-twiss-6 test-twiss-8 test-twiss-9 test-twiss-10 test-twiss-11 \
test-twiss-12 test-twiss-13 test-twiss-14 test-twiss-15 test-twiss-16 test-twiss-exact test-translation test-crabcavity \
test-xrotation test-yrotation test-rotations test-interpolate test-rf-fringe \
test-xrotation test-yrotation test-rotations test-rotations-2 test-interpolate test-rf-fringe \
test-cororbit test-cororbit-2 test-cororbit-3 test-cororbit-4 \
test-emit test-emit-2 \
test-ibs test-ibs-2 test-ibs-3 test-ibs-4 \
Expand Down
231 changes: 144 additions & 87 deletions src/twiss.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3727,10 +3727,10 @@ SUBROUTINE tmmap(code,fsec,ftrk,orbit,fmap,ek,re,te,fcentre,dl)
call tmsrot(ftrk,orbit,fmap,ek,re,te)

case (code_yrotation)
call tmyrot(ftrk,orbit,fmap,ek,re,te)
call tmxyrot(fsec,ftrk,orbit,fmap,ek,re,te,node_value('angle ')*node_value('other_bv '),1)

case (code_xrotation)
call tmxrot(ftrk,orbit,fmap,ek,re,te)
call tmxyrot(fsec,ftrk,orbit,fmap,ek,re,te,-node_value('angle ')*node_value('other_bv '),2)

case (code_hkicker, code_vkicker, code_kicker, code_tkicker)
call tmcorr(fsec,ftrk,fcentre,orbit,fmap,el,dl,ek,re,te)
Expand Down Expand Up @@ -7031,109 +7031,166 @@ SUBROUTINE tmsrot(ftrk,orbit,fmap,ek,re,te)

end SUBROUTINE tmsrot

SUBROUTINE tmxrot(ftrk,orbit,fmap,ek,re,te)
SUBROUTINE tmxyrot(fsec,ftrk,orbit,fmap,ek,re,te,angle,iplane)
! Common code for tmxrot and tmyrot
! iplane=1 for YROTATION, iplane=2 for XROTATION
use twisslfi
use twissbeamfi, only : beta, gamma
use twiss0fi, only : align_max
implicit none
!----------------------------------------------------------------------*
! Purpose: *
! TRANSPORT map for rotation about X-axis. *
! Treated in a purely linear way. *
! Input: *
! ftrk (logical) if true, track orbit. *
! Input/output: *
! orbit(6) (double) closed orbit. *
! Output: *
! fmap (logical) if true, element has a map. *
! ek(6) (double) kick due to element. *
! re(6,6) (double) transfer matrix. *
! te(6,6,6) (double) second-order terms. *
!----------------------------------------------------------------------*
logical :: ftrk, fmap
double precision :: orbit(6), ek(6), re(6,6), te(6,6,6)
double precision :: al_errors(align_max)
double precision :: angle, ca, sa, ta
double precision :: node_value
logical :: fsec, ftrk, fmap
integer :: iplane
double precision :: angle, orbit(6), ek(6), re(6,6), te(6,6,6)

!---- Initialize.
al_errors = 0d0
integer ix,ip,iy,iq
double precision :: ca, sa
real(kind(0d0)) :: beti,bg2i,ca2,pl2,pm2,ps0,ps1,pt,ptb,px0,px02,px1,px12,py,py2,sa2,sps0ps12,x0,xsps1

angle = node_value('angle ')
!---- Initialize.
ix = 2*iplane-1
ip = 2*iplane
iy = 5-2*iplane
iq = 6-2*iplane
fmap = angle.ne.0
if (angle .eq. 0) return

angle = angle * node_value('other_bv ')
!al_errors(4) = -angle
x0 = orbit(ix)
px0 = orbit(ip)
py = orbit(iq)
pt = orbit(6)

beti = 1/beta
bg2i = 1/(beta*beta*gamma*gamma)
ptb = beti+pt
pl2 = 1+(2*beti+pt)*pt
py2 = py*py
pm2 = pl2-py2
px02 = px0*px0
ps0 = sqrt(pm2-px02)

!---- Kick.
ca = cos(angle)
sa = sin(angle)
ta = tan(angle)

ek(4) = sa

!call tmali1(orbit,al_errors,beta,gamma,orbit,re)
!---- Transfer matrix.
re(3,3) = 1/ca
re(4,4) = ca
re(4,6) = sa/beta
re(5,3) = -ta/beta
px1 = px0*ca - ps0*sa
ps1 = px0*sa + ps0*ca
px12 = px1*px1
xsps1 = x0*sa/ps1
sps0ps12 = 0.5d0*sa/(ps0*ps1*ps1)

!---- Track orbit.
if (ftrk) call tmtrak(ek,re,te,orbit,orbit)
ca2 = cos(0.5d0*angle)
sa2 = sin(0.5d0*angle)

end SUBROUTINE tmxrot
ek(ix) = 2*sa2*x0*(ps0*sa2-px0*ca2)/ps1
ek(ip) = -2*sa2*(ps0*ca2+px0*sa2)
ek(iy) = -xsps1*py
ek(iq) = 0
ek(5) = xsps1*ptb
ek(6) = 0

SUBROUTINE tmyrot(ftrk,orbit,fmap,ek,re,te)
use twisslfi
use twissbeamfi, only : beta, gamma
use twiss0fi, only : align_max
implicit none
!----------------------------------------------------------------------*
! Purpose: *
! TRANSPORT map for rotation about Y-axis. *
! Treated in a purely linear way. *
! Input: *
! ftrk (logical) if true, track orbit. *
! Input/output: *
! orbit(6) (double) closed orbit. *
! Output: *
! fmap (logical) if true, element has a map. *
! ek(6) (double) kick due to element. *
! re(6,6) (double) transfer matrix. *
! te(6,6,6) (double) second-order terms. *
!----------------------------------------------------------------------*
logical :: ftrk, fmap
double precision :: orbit(6), ek(6), re(6,6), te(6,6,6)

double precision :: angle, ca, sa, ta
double precision :: node_value
double precision :: al_errors(align_max)

!---- Initialize.
angle = -node_value('angle ') !Note that we should have the negative angle here
if (angle .eq. 0) return
!al_errors = 0d0
angle = angle * node_value('other_bv ')
!al_errors(5) = - angle
!call tmali1(orbit,al_errors,beta,gamma,orbit,re)

!---- Kick.
ca = cos(angle)
sa = sin(angle)
ta = tan(angle)

ek(2) = sa
if (ftrk) then
orbit(ix) = x0*ps0/ps1
orbit(ip) = px1
orbit(iy) = orbit(iy) + ek(iy)
orbit(5) = orbit(5) + ek(5)
end if

!---- Transfer matrix.
re(1,1) = 1/ca
re(2,2) = ca
re(2,6) = sa/beta
re(5,1) = -ta/beta
re = 0
re(ip,ip) = ps1/ps0
re(ip,iq) = sa*py/ps0
re(ip,6) = -sa*ptb/ps0

if (fsec) te = 0

! Using te as scratch space to avoid excess copying when fsec is true
te(ix,ix,ip) = -sps0ps12*pm2
te(ix,ix,iq) = -sps0ps12*px0*py
te(ix,ix,6) = sps0ps12*px0*ptb
te(iy,ix,ip) = -sps0ps12*px1*py
te(iy,ix,iq) = sps0ps12*(px0*px1-pl2*ca)
te(iy,ix,6) = sps0ps12*ca*py*ptb
te(5,ix,ip) = sps0ps12*px1*ptb
te(5,ix,iq) = sps0ps12*ca*py*ptb
te(5,ix,6) = -sps0ps12*(px0*px1+(bg2i+py2)*ca)

!---- Track orbit.
if (ftrk) call tmtrak(ek,re,te,orbit,orbit)
if (fsec) then
te(1:5:2,2:6:2,ix) = te(1:5:2,ix,2:6:2)
block
real(kind(0d0)) :: sps30,sps31,sps5
real(kind(0d0)) :: d0xx,d0xy,d0xt,d0yy,d0yt,d0tt
real(kind(0d0)) :: d0xxx,d0xxy,d0xxt,d0xyy,d0xyt,d0xtt,d0yyy,d0yyt,d0ytt,d0ttt

sps31 = sa/ps1**3
d0xx = -(pl2-py2)*sps31
d0xy = -px1*py*sps31
d0xt = px1*ptb*sps31
d0yy = -(pl2-px12)*sps31
d0yt = py*ptb*sps31
d0tt = -(bg2i+px12+py2)*sps31

sps5 = 0.5d0*sa/ps1**5
d0xxx = -3*px1*(pl2-py2)*sps5
d0xxy = -py*(pl2-py2+2*px12)*sps5
d0xxt = ptb*(pl2-py2+2*px12)*sps5
d0xyy = -px1*(pl2-px12+2*py2)*sps5
d0xyt = 3*px1*py*ptb*sps5
d0xtt = -px1*(2*ptb*ptb+bg2i+px12+py2)*sps5
d0yyy = -3*py*(pl2-px12)*sps5
d0yyt = ptb*(pl2-px12+2*py2)*sps5
d0ytt = -py*(2*ptb*ptb+bg2i+px12+py2)*sps5
d0ttt = 3*ptb*(bg2i+px12+py2)*sps5

sps30 = 0.5d0*sa/ps0**3
te(ip,ip,ip) = (pl2-py2)*sps30
te(ip,ip,iq) = px0*py*sps30
te(ip,ip,6) = -px0*ptb*sps30
te(ip,iq,ip) = te(ip,ip,iq)
te(ip,iq,iq) = (pl2-px02)*sps30
te(ip,iq,6) = -py*ptb*sps30
te(ip,6,ip) = te(ip,ip,6)
te(ip,6,iq) = te(ip,iq,6)
te(ip,6,6) = (bg2i+px02+py2)*sps30

te(ix,ip,ip) = x0*(d0xxx*re(ip,ip)*re(ip,ip)+d0xx*te(ip,ip,ip))
te(ix,ip,iq) = x0*(d0xxy*re(ip,ip)+d0xxx*re(ip,ip)*re(ip,iq)+d0xx*te(ip,ip,iq))
te(ix,ip,6) = x0*(d0xxt*re(ip,ip)+d0xxx*re(ip,ip)*re(ip,6)+d0xx*te(ip,ip,6))
te(ix,iq,ip) = te(ix,ip,iq)
te(ix,iq,iq) = x0*(d0xyy+2*d0xxy*re(ip,iq)+d0xxx*re(ip,iq)*re(ip,iq)+d0xx*te(ip,iq,iq))
te(ix,iq,6) = x0*(d0xyt+d0xxy*re(ip,6)+d0xxt*re(ip,iq)+d0xxx*re(ip,iq)*re(ip,6)+d0xx*te(ip,iq,6))
te(ix,6,ip) = te(ix,ip,6)
te(ix,6,iq) = te(ix,iq,6)
te(ix,6,6) = x0*(d0xtt+2*d0xxt*re(ip,6)+d0xxx*re(ip,6)*re(ip,6)+d0xx*te(ip,6,6))
te(iy,ip,ip) = x0*(d0xxy*re(ip,ip)*re(ip,ip)+d0xy*te(ip,ip,ip))
te(iy,ip,iq) = x0*(d0xyy*re(ip,ip)+d0xxy*re(ip,ip)*re(ip,iq)+d0xy*te(ip,ip,iq))
te(iy,ip,6) = x0*(d0xyt*re(ip,ip)+d0xxy*re(ip,ip)*re(ip,6)+d0xy*te(ip,ip,6))
te(iy,iq,ip) = te(iy,ip,iq)
te(iy,iq,iq) = x0*(d0yyy+2*d0xyy*re(ip,iq)+d0xxy*re(ip,iq)*re(ip,iq)+d0xy*te(ip,iq,iq))
te(iy,iq,6) = x0*(d0yyt+d0xyy*re(ip,6)+d0xyt*re(ip,iq)+d0xxy*re(ip,iq)*re(ip,6)+d0xy*te(ip,iq,6))
te(iy,6,ip) = te(iy,ip,6)
te(iy,6,iq) = te(iy,iq,6)
te(iy,6,6) = x0*(d0ytt+2*d0xyt*re(ip,6)+d0xxy*re(ip,6)*re(ip,6)+d0xy*te(ip,6,6))
te(5,ip,ip) = x0*(d0xxt*re(ip,ip)*re(ip,ip)+d0xt*te(ip,ip,ip))
te(5,ip,iq) = x0*(d0xyt*re(ip,ip)+d0xxt*re(ip,ip)*re(ip,iq)+d0xt*te(ip,ip,iq))
te(5,ip,6) = x0*(d0xtt*re(ip,ip)+d0xxt*re(ip,ip)*re(ip,6)+d0xt*te(ip,ip,6))
te(5,iq,ip) = te(5,ip,iq)
te(5,iq,iq) = x0*(d0yyt+2*d0xyt*re(ip,iq)+d0xxt*re(ip,iq)*re(ip,iq)+d0xt*te(ip,iq,iq))
te(5,iq,6) = x0*(d0ytt+d0xyt*re(ip,6)+d0xtt*re(ip,iq)+d0xxt*re(ip,iq)*re(ip,6)+d0xt*te(ip,iq,6))
te(5,6,ip) = te(5,ip,6)
te(5,6,iq) = te(5,iq,6)
te(5,6,6) = x0*(d0ttt+2*d0xtt*re(ip,6)+d0xxt*re(ip,6)*re(ip,6)+d0xt*te(ip,6,6))
end block
end if

re(ix,ix) = ps0/ps1
re(iy,ix) = -sa*py/ps1
re(iy,iy) = 1
re(iq,iq) = 1
re(5,5) = 1
re(5,ix) = sa*ptb/ps1
re(6,6) = 1
re(1:5:2,2:6:2) = (2*x0)*te(1:5:2,ix,2:6:2)

end SUBROUTINE tmyrot
end SUBROUTINE tmxyrot

SUBROUTINE tmdrf(fsec,ftrk,orbit,fmap,dl,ek,re,te)
use twissbeamfi, only : beta, gamma, dtbyds
Expand Down
18 changes: 9 additions & 9 deletions tests/test-ptc-twiss-rotations/test-ptc-twiss-rotations.ref
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

++++++++++++++++++++++++++++++++++++++++++++
+ MAD-X 5.07.00 (64 bit, Linux) +
+ MAD-X 5.08.01 (64 bit, Linux) +
+ Support: mad@cern.ch, http://cern.ch/mad +
+ Release date: 2021.05.03 +
+ Execution date: 2021.12.10 13:07:41 +
+ Release date: 2022.02.25 +
+ Execution date: 2022.07.05 16:32:18 +
++++++++++++++++++++++++++++++++++++++++++++
circum=3;

Expand Down Expand Up @@ -364,13 +364,13 @@ final orbit vector: 0.000000E+00 0.000000E+00 3.999997E-03 1.999999E-03 -
3 -0 0 0

q1 dq1 betxmax dxmax
0.1987981743 0 10.00240016 0
0.1987918088 0 9.999999995 0

dxrms xcomax xcorms q2
0 0 0 0.1987981743
0 0 0 0.1987916815

dq2 betymax dymax dyrms
0 10.00240016 0.003999997856 0.002108183977
0 9.999991986 7.999990378e-07 6.531964791e-07

ycomax ycorms deltap synch_1
0.003999997332 0.0021081837 0 0
Expand Down Expand Up @@ -638,13 +638,13 @@ final orbit vector: -3.999997E-03 -1.999999E-03 0.000000E+00 0.000000E+00 -
3 -0 0 0

q1 dq1 betxmax dxmax
0.1987886255 0 9.998800041 0.003999997856
0.1987916815 0 9.999992007 3.999995189e-07

dxrms xcomax xcorms q2
0.002108183977 0.003999997334 0.002108183702 0.1987886255
3.265982395e-07 0.003999997334 0.002108183702 0.1987918088

dq2 betymax dymax dyrms
0 9.998800041 0 0
0 10 0 0

ycomax ycorms deltap synch_1
0 0 0 0
Expand Down
5 changes: 5 additions & 0 deletions tests/test-rotations-2/test-rotations-2.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1-155 * skip
156-223 * abs=1e-14
224-367 * skip
368-435 * abs=1e-14
436-$ * skip
Loading

0 comments on commit e19ca7b

Please sign in to comment.