OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
MultipoleTCurvedConstRadius.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, Titus Dascalu
3 * Copyright (c) 2018, Martin Duy Tat
4 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * 3. Neither the name of STFC nor the names of its contributors may be used to
13 * endorse or promote products derived from this software without specific
14 * prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
29#include "MultipoleT.h"
30#include "gsl/gsl_sf_pow_int.h"
31
36
38 planarArcGeometry_m.setElementLength(element_m->getLength());
39 planarArcGeometry_m.setCurvature(element_m->getBendAngle() / element_m->getLength());
40 setMaxOrder(element_m->getMaxFOrder(), element_m->getMaxXOrder());
41}
42
44 if(element_m->getBendAngle() != 0.0) {
45 double radius = element_m->getLength() / element_m->getBendAngle();
46 double alpha = std::atan(R[2] / (R[0] + radius));
47 if (alpha != 0.0) {
48 R[0] = R[2] / std::sin(alpha) - radius;
49 R[2] = radius * alpha;
50 }
51 }
52 R[2] += element_m->getLength() / 2.0; // Magnet origin at the center rather than entry
53}
54
56 double theta = R[2] * element_m->getBendAngle() / element_m->getLength();
57 double Bx = B[0];
58 double Bs = B[2];
59 B[0] = Bx * std::cos(theta) - Bs * std::sin(theta);
60 B[2] = Bx * std::sin(theta) + Bs * std::cos(theta);
61}
62
63void MultipoleTCurvedConstRadius::setMaxOrder(size_t orderZ, size_t orderX) {
64 std::size_t N = recursion_m.size();
65 while (orderZ >= N) {
66 polynomial::RecursionRelation r(N, 2 * (N + orderX + 1));
67 r.resizeX(element_m->getTransMaxOrder());
68 r.truncate(orderX);
69 recursion_m.push_back(r);
70 N = recursion_m.size();
71 }
72}
73
75 Vector_t result = r;
76 if(element_m->getBendAngle() != 0.0) {
77 double radius = element_m->getLength() / element_m->getBendAngle();
78 double theta = element_m->getBendAngle() /2.0;
79 double ds = radius * std::sin(theta);
80 double dx = radius * (1 - std::cos(theta));
81 result[0] = -dx;
82 result[2] = ds;
83 }
84 return result;
85}
86
87double MultipoleTCurvedConstRadius::getScaleFactor(double x, double /*s*/) {
88 return (1 + x * element_m->getBendAngle() / element_m->getLength());
89}
90
91double MultipoleTCurvedConstRadius::getFn(size_t n, double x, double s) {
92 if (n == 0) {
93 return element_m->getTransDeriv(0, x) * element_m->getFringeDeriv(0, s);
94 }
95 double rho = element_m->getLength() / element_m->getBendAngle();
96 double func = 0.0;
97 for (std::size_t j = 0;
98 j <= recursion_m.at(n).getMaxSDerivatives();
99 j++) {
100 double FringeDerivj = element_m->getFringeDeriv(2 * j, s);
101 for (std::size_t i = 0;
102 i <= recursion_m.at(n).getMaxXDerivatives();
103 i++) {
104 if (recursion_m.at(n).isPolynomialZero(i, j)) {
105 continue;
106 }
107 func += (recursion_m.at(n).evaluatePolynomial(x / rho, i, j)
108 * element_m->getTransDeriv(i, x) * FringeDerivj)
109 / gsl_sf_pow_int(rho, 2 * static_cast<int>(n) - static_cast<int>(i) -
110 2 * static_cast<int>(j));
111 }
112 }
113 func *= gsl_sf_pow_int(-1.0, static_cast<int>(n));
114 return func;
115}
116
MultipoleT * element_m
MultipoleTBase(MultipoleT *element)
std::vector< polynomial::RecursionRelation > recursion_m
void setMaxOrder(size_t orderZ, size_t orderX) override
Vector_t localCartesianToOpalCartesian(const Vector_t &r) override
double getFn(size_t n, double x, double s) override
double getScaleFactor(double x, double s) override
void transformBField(Vector_t &, const Vector_t &) override
void transformCoords(Vector_t &) override
void resizeX(const std::size_t &xDerivatives)
void truncate(std::size_t highestXorder)
Vektor< double, 3 > Vector_t