46 "The \"MICADO\" command makes a correction "
47 "using the \"MICADO\" algorithm.") {
49 (
"METHOD",
"The method used for orbit tracking",
"LINEAR");
51 (
"TOL",
"The tolerance for the r.m.s closed orbit.");
53 (
"ITERATIONS",
"The number of iterations");
55 (
"CORRECTORS",
"The number of correctors to be used");
57 (
"PLANE",
"The plane(s) for which a Correction is desired",
"BOTH");
59 (
"LISTC1",
"List the correctors before correction");
61 (
"LISTC",
"List the correctors during correction");
63 (
"LISTC2",
"List the correctors after correction");
65 (
"LISTM1",
"List the monitors before correction");
67 (
"LISTM2",
"List the monitors after correction");
83 return new Micado(name,
this);
113 std::cerr <<
"\n### Warning ### \"MICADO\" table \""
114 << lineName <<
"\" contains no elements.\n" <<
std::endl;
119 bool planes[2] = {
false,
false };
120 if(planeName ==
"BOTH") {
121 planes[0] = planes[1] =
true;
122 }
else if(planeName ==
"X") {
124 }
else if(planeName ==
"Y") {
128 "Plane name \"" + planeName +
"\" is unknown.");
135 if(methodName ==
"THICK") {
137 }
else if(methodName ==
"THIN") {
139 }
else if(methodName ==
"LINEAR") {
143 "Method name \"" + methodName +
"\" is unknown.");
150 for(
int iteration = 1; iteration <= iterations; ++iteration) {
151 std::cout <<
"\n\"MICADO\" iteration " << iteration <<
":\n";
153 for(
int plane = 0; plane < 2; ++plane) {
178 if(listc2 || listm2) {
179 std::cout <<
"\"MICADO\" finished:\n";
180 for(
int plane = 0; plane < 2; ++plane) {
189 static const int iteration_limit = 20;
190 static const double itsTolerance = 1.0e-8;
192 for(
int count = 0; count < iteration_limit; ++count) {
200 iter !=
itsLine.end(); ++iter) {
213 for(
int i = 0; i < 4; i++) {
218 for(
int i = 4; i < 6; i++) {
219 for(
int j = 0; j < 6; j++) A(i, j) = A(j, i) = 0.0;
225 for(
int i = 0; i < 6; i++) {
235 if(error < itsTolerance)
break;
246 for(
int i = 0; i < 4; ++i) {
247 for(
int j = 0; j < 4; ++j) {
248 R(i, j) = tmat(i, j);
254 for(
int i = 0; i < 4; ++i) {
255 for(
int j = 0; j < 4; ++j) {
256 tmat1(i, j) = R1(i, j);
259 tmat1(4, 4) = tmat1(5, 5) = 1.0;
261 const int q = 2 * plane;
270 for(
LocalIter cIter = cBegin; cIter != cEnd; ++cIter) {
275 for(
int j = 0; j < 6; j += 2) {
276 initialOrbit[j] = - cmat(q, j + 1);
277 initialOrbit[j+1] = cmat(q, j);
282 for(
LocalIter mIter = mBegin; mIter != mEnd; ++mIter) {
285 if((*mIter)->arc >= (*cIter)->arc) {
286 orbit = (*mIter)->matrix * (tmat1 * initialOrbit);
288 orbit = (*mIter)->matrix * (tmat1 * (tmat * initialOrbit));
291 A(moni, corr) = orbit[q];
301 const int q = 2 * plane;
327 for(
int k = 0; k <
n; ++k) {
330 for(
int i = 0; i < m; ++i) {
331 hh += A(i, k) * A(i, k);
332 gg += A(i, k) * B[i];
338 double sqrmin = 1.e-8 * sum / double(n);
343 if(correctors > n || correctors == 0) correctors =
n;
349 double maxChange = 0.0;
350 int changeIndex = -1;
351 for(
int j = k; j <
n; ++j) {
352 if(sqr[j] > sqrmin) {
353 double change = dot[j] * dot[j] / sqr[j];
354 if(change > maxChange) {
362 if(changeIndex < 0)
break;
365 if(changeIndex > k) {
366 std::swap(sqr[k], sqr[changeIndex]);
367 std::swap(dot[k], dot[changeIndex]);
368 std::swap(index[k], index[changeIndex]);
374 for(
int i = k; i < m; ++i) hh += A(i, k) * A(i, k);
375 double sigma = (A(k, k) > 0.0) ?
sqrt(hh) : (-
sqrt(hh));
377 A(k, k) = A(k, k) + sigma;
378 double beta = 1.0 / (A(k, k) * sigma);
381 for(
int j = k + 1; j <
n; ++j) {
383 for(
int i = k; i < m; ++i) hh += A(i, k) * A(i, j);
385 for(
int i = k; i < m; ++i) A(i, j) -= A(i, k) * hh;
390 for(
int i = k; i < m; ++i) hh += A(i, k) * B[i];
392 for(
int i = k; i < m; ++i) B[i] -= A(i, k) * hh;
395 for(
int j = k + 1; j <
n; ++j) {
396 sqr[j] -= A(k, j) * A(k, j);
397 dot[j] -= A(k, j) * B[k];
401 x[k] = B[k] / sqr[k];
402 for(
int i = k - 1; i >= 0; --i) {
404 for(
int j = i + 1; j < k; ++j) x[i] -= A(i, j) * x[j];
409 for(
int i = 0; i < m; ++i) r[i] = B[i];
410 for(
int j = k; j >= 0; --j) {
413 for(
int i = j; i < m; ++i) hh += A(i, j) * r[i];
414 hh /= sqr[j] * A(j, j);
415 for(
int i = j; i < m; ++i) {
416 r[i] += A(i, j) * hh;
422 for(
int i = 1; i < m; ++i) hh += r[i] * r[i];
428 std::cout <<
"\nCorrector increment r.m.s.";
429 for(
int k = 0; k < corr; ++k) {
430 const std::string &
name = index[k]->getElement()->getName();
431 std::cout <<
'\n' << name << std::string(20 - name.length(),
' ')
432 << std::setw(12) << (- x[k]);
434 std::cout << std::setw(20) << hh <<
std::endl;
439 if(corr > correctors)
break;
443 for(
int k = 0; k < corr; ++k) {
444 addKick(plane, *index[k], - x[k]);
void swapColumns(int c1, int c2)
Exchange columns.
double Round(double value)
Round the double argument.
Abstract base class for all orbit correction commands.
void solve(int plane, Matrix< double > &A, Vector< double > &B)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
OwnPtr< AbstractMapper > itsMapper
RangeRep getRange(const Attribute &attr)
Get range value.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
The base class for all OPAL exceptions.
void setupInfluence(int mode, Matrix< double > &)
int ncols() const
Get number of columns.
void update()
Update all objects.
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Build a map using a linear map for each element.
LocalList monitorTable[2]
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
bool getBool(const Attribute &attr)
Return logical value.
void listCorrectors(bool list, int plane)
List correctors before or after correction.
static OpalData * getInstance()
static BeamSequence * find(const std::string &name)
Find a BeamSequence by name.
FVector< T, N > constantTerm(const FVector< T, N > &P) const
Evaluate map at point [b]P[/b].
A templated representation of a LU-decomposition.
void listMonitors(bool list, int plane)
List monitors before or after correction.
TLine itsLine
The flat beam line on which the correction is done.
virtual Micado * clone(const std::string &name)
Make clone.
static Beam * find(const std::string &name)
Find named BEAM.
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
virtual Beamline * fetchLine() const =0
Return the embedded CLASSIC beam line.
LocalList::iterator LocalIter
Micado()
Exemplar constructor.
LocalList correctorTable[2]
void backSubstitute(FVector< T, N > &B) const
Back substitution.
virtual void setMap(const LinearMap< double, 6 > &)=0
Reset the linear part of the accumulated map for restart.
virtual void execute()
Apply the algorithm to the top-level beamline.
PartData reference
The particle reference data.
Representation of a range within a beam line or sequence.
FVector< double, 6 > orbitGuess
The closed orbit guess.
Tps< T > sqrt(const Tps< T > &x)
Square root.
The base class for all OPAL beam lines and sequences.
const PartData & getReference() const
Return the embedded CLASSIC PartData.
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
static void setGlobalTruncOrder(int order)
Set the global truncation order.
FMatrix< T, N, N > linearTerms() const
Extract linear terms at origin.
std::string::iterator iterator
Linear function in N variables of type T.
double getReal(const Attribute &attr)
Return real value.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
void setupReadings(int mode, Vector< double > &B)
int nrows() const
Get number of rows.
void setupTables()
Set up the corrector and monitor tables.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Build a map using a finite-length lens for each element.
void addKick(int plane, Row &, double kick)
Add to kicker strength.
virtual void execute()
Check validity of the table definition.
virtual void getMap(LinearMap< double, 6 > &) const =0
Return the linear part of the accumulated map.
Inform & endl(Inform &inf)
std::string getString(const Attribute &attr)
Get string value.