@@ -64,8 +64,7 @@ Status::type calc_twiss(const Accelerator& accelerator,
6464 const Pos<double >& fixed_point,
6565 Matrix& m66,
6666 std::vector<Twiss>& twiss,
67- Twiss twiss0,
68- bool closed_flag) {
67+ Twiss twiss0) {
6968
7069#ifdef TIMEIT
7170 auto start = std::chrono::steady_clock::now ();
@@ -84,14 +83,7 @@ Status::type calc_twiss(const Accelerator& accelerator,
8483 unsigned int element_offset = 0 ;
8584 Status::type status = track_linepass (accelerator, fp, closed_orbit, element_offset, lost_plane, true );
8685 if (status != Status::success) return status;
87- if (not closed_flag) closed_orbit.pop_back ();
8886
89- // std::vector<Pos<double>> closed_orbit0;
90- // if (not accelerator.cavity_on) {
91- // Pos<double> fp = fixed_point; fp.de = 0;
92- // Status::type status = track_linepass(accelerator, fp, closed_orbit0, element_offset, lost_plane, true);
93- // if (status != Status::success) return status;
94- // }
9587
9688#ifdef TIMEIT
9789 end = std::chrono::steady_clock::now (); diff = end - start;
@@ -102,22 +94,10 @@ Status::type calc_twiss(const Accelerator& accelerator,
10294 start = std::chrono::steady_clock::now ();
10395#endif
10496
105- // finds accumulated transfer matrices
106-
107- // std::vector<Matrix> atm0;
108- // if (not accelerator.cavity_on) {
109- // status = track_findm66 (accelerator, closed_orbit0, atm0, m66);
110- // if (status != Status::success) return status;
111- // if (closed_flag) atm.push_back(atm.back());
112- // }
113-
11497 std::vector<Matrix> atm;
11598 Pos<double > v0;
116- status = track_findm66 (accelerator, closed_orbit, atm, m66, v0);
99+ status = track_findm66 (accelerator, closed_orbit[ 0 ] , atm, m66, v0);
117100 if (status != Status::success) return status;
118- if (closed_flag) atm.push_back (atm.back ());
119-
120-
121101
122102#ifdef TIMEIT
123103 end = std::chrono::steady_clock::now (); diff = end - start;
@@ -128,6 +108,11 @@ Status::type calc_twiss(const Accelerator& accelerator,
128108 start = std::chrono::steady_clock::now ();
129109#endif
130110
111+ const double dpp = 1e-8 ;
112+ Pos<double > fpp = fixed_point;
113+ fpp.de += dpp;
114+ std::vector<Pos<double >> codp;
115+
131116 // initial twiss parameters
132117 twiss.clear (); twiss.reserve (atm.size ());
133118 if (twiss0.isundef ()) { // case of periodic solution
@@ -141,15 +126,32 @@ Status::type calc_twiss(const Accelerator& accelerator,
141126 twiss0.betay = m66[2 ][3 ]/sin_muy;
142127 // --- closed orbit
143128 twiss0.co = closed_orbit[0 ];
144- // --- dispersion function based on eta = (1 - M)^(-1) D
145- Vector Dx ({m66[0 ][4 ], m66[1 ][4 ]});
146- Vector Dy ({m66[2 ][4 ], m66[3 ][4 ]});
147- Matrix eye2 ({{1 ,0 },{0 ,1 }});
148- Matrix mx; m66.getM (mx, 2 , 2 , 0 , 0 ); mx.linear_combination (1.0 ,eye2,-1.0 ,mx); mx.inverse ();
149- Matrix my; m66.getM (my, 2 , 2 , 2 , 2 ); my.linear_combination (1.0 ,eye2,-1.0 ,my); my.inverse ();
150- twiss0.etax .multiplication (mx, Dx);
151- twiss0.etay .multiplication (my, Dy);
129+
130+ // // --- dispersion function based on eta = (1 - M)^(-1) D
131+ // Vector Dx({m66[0][4], m66[1][4]});
132+ // Vector Dy({m66[2][4], m66[3][4]});
133+ // Matrix eye2({{1,0},{0,1}});
134+ // Matrix mx; m66.getM(mx, 2, 2, 0, 0); mx.linear_combination(1.0,eye2,-1.0,mx); mx.inverse();
135+ // Matrix my; m66.getM(my, 2, 2, 2, 2); my.linear_combination(1.0,eye2,-1.0,my); my.inverse();
136+ // twiss0.etax.multiplication(mx, Dx);
137+ // twiss0.etay.multiplication(my, Dy);
138+
139+ // Dispersion Function based on tracking:
140+ Status::type status = track_findorbit4 (accelerator, codp, fpp);
141+ if (status != Status::success) return status;
142+ twiss0.etax [0 ] = (codp[0 ].rx - closed_orbit[0 ].rx ) / dpp;
143+ twiss0.etax [1 ] = (codp[0 ].px - closed_orbit[0 ].px ) / dpp;
144+ twiss0.etay [0 ] = (codp[0 ].ry - closed_orbit[0 ].ry ) / dpp;
145+ twiss0.etay [1 ] = (codp[0 ].py - closed_orbit[0 ].py ) / dpp;
146+ } else {
147+ fpp.rx += twiss0.etax [0 ] * dpp;
148+ fpp.px += twiss0.etax [1 ] * dpp;
149+ fpp.ry += twiss0.etay [0 ] * dpp;
150+ fpp.py += twiss0.etay [1 ] * dpp;
151+ Status::type status = track_linepass (accelerator, fpp, codp, element_offset, lost_plane, true );
152+ if (status != Status::success) return status;
152153 }
154+
153155 twiss.push_back (twiss0);
154156
155157#ifdef TIMEIT
@@ -178,20 +180,25 @@ Status::type calc_twiss(const Accelerator& accelerator,
178180 // --- closed orbit
179181 tw.co = closed_orbit[i];
180182
181- // --- dispersion function
182- Matrix t1 (atm[i-1 ]); t1.inverse ();
183- Matrix T; T.multiplication (atm[i],t1);
184- Vector Dx ({T[0 ][4 ], T[1 ][4 ]});
185- Vector Dy ({T[2 ][4 ], T[3 ][4 ]});
186- Matrix mx; T.getMx (mx);
187- Matrix my; T.getMy (my);
188- tw.etax .multiplication (mx, twiss[i-1 ].etax );
189- tw.etay .multiplication (my, twiss[i-1 ].etay );
190- tw.etax = Dx + tw.etax .multiplication (mx, twiss[i-1 ].etax );
191- tw.etay = Dy + tw.etay .multiplication (my, twiss[i-1 ].etay );
183+ // // --- dispersion function based on propagation
184+ // Matrix t1(atm[i-1]); t1.inverse();
185+ // Matrix T; T.multiplication(atm[i],t1);
186+ // Vector Dx({T[0][4], T[1][4]});
187+ // Vector Dy({T[2][4], T[3][4]});
188+ // Matrix mx; T.getMx(mx);
189+ // Matrix my; T.getMy(my);
190+ // tw.etax.multiplication(mx, twiss[i-1].etax);
191+ // tw.etay.multiplication(my, twiss[i-1].etay);
192+ // tw.etax = Dx + tw.etax.multiplication(mx, twiss[i-1].etax);
193+ // tw.etay = Dy + tw.etay.multiplication(my, twiss[i-1].etay);
194+
195+ // Dispersion Function based on tracking
196+ tw.etax [0 ] = (codp[i].rx - closed_orbit[i].rx ) / dpp;
197+ tw.etax [1 ] = (codp[i].px - closed_orbit[i].px ) / dpp;
198+ tw.etay [0 ] = (codp[i].ry - closed_orbit[i].ry ) / dpp;
199+ tw.etay [1 ] = (codp[i].py - closed_orbit[i].py ) / dpp;
192200
193201 twiss.push_back (tw);
194-
195202 }
196203
197204 // unwraps betatron phases
0 commit comments