OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
CoordinateTransform.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, Martin Duy Tat
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright notice,
9 * this list of conditions and the following disclaimer in the documentation
10 * and/or other materials provided with the distribution.
11 * 3. Neither the name of STFC nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific
13 * prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <cmath>
29#include <vector>
30#include "gsl/gsl_errno.h"
31#include "gsl/gsl_integration.h"
32#include "gsl/gsl_sf_pow_int.h"
33#include "Utility/Inform.h" // ippl/src/
34
35#include "CoordinateTransform.h"
36
37extern Inform *gmsg;
38
40
41const double CoordinateTransform::error = 1e-10;
43const int CoordinateTransform::algorithm = GSL_INTEG_GAUSS61;
44
46 const double &ylab,
47 const double &zlab,
48 const double &s_0,
49 const double &lambdaleft,
50 const double &lambdaright,
51 const double &rho):
52 s_0_m(s_0), lambdaleft_m(lambdaleft),
53 lambdaright_m(lambdaright), rho_m(rho) {
54 std::vector<double> coordinates;
55 coordinates.push_back(xlab);
56 coordinates.push_back(zlab);
57 //transformFromEntranceCoordinates(coordinates, boundingBoxLength);
58 calcSCoordinate(coordinates[0], coordinates[1]);
59 calcXCoordinate(coordinates[0], coordinates[1]);
60 z_m = ylab;
61}
62
64 s_0_m(transform.s_0_m), lambdaleft_m(transform.lambdaleft_m),
65 lambdaright_m(transform.lambdaright_m),
66 rho_m(transform.rho_m), x_m(transform.x_m),
67 z_m(transform.z_m), s_m(transform.s_m) {
68}
69
71}
72
74 const CoordinateTransform& transform) {
75 s_0_m = transform.s_0_m;
76 lambdaleft_m = transform.lambdaleft_m;
77 lambdaright_m = transform.lambdaright_m;
78 x_m = transform.x_m;
79 z_m = transform.z_m;
80 s_m = transform.s_m;
81 rho_m = transform.rho_m;
82 return *this;
83}
84
85std::vector<double> CoordinateTransform::getTransformation() const {
86 std::vector<double> result;
87 result.push_back(x_m);
88 result.push_back(z_m);
89 result.push_back(s_m);
90 return result;
91}
92
94 const double &s) const {
95 std::vector<double> result;
96 double prefactor = rho_m * (std::tanh(s_0_m / lambdaleft_m) -
98 result.push_back(-std::sin((lambdaleft_m * std::log(std::cosh((s + s_0_m) / lambdaleft_m))
100 / prefactor));
101 result.push_back(std::cos((lambdaleft_m * std::log(std::cosh((s + s_0_m) / lambdaleft_m))
103 / prefactor));
104 return result;
105}
106
108 const double &s) const {
109 struct myParams params = {s_0_m, lambdaleft_m, lambdaright_m, rho_m};
110 gsl_function FX, FY;
111 FX.function = &getUnitTangentVectorX;
112 FY.function = &getUnitTangentVectorY;
113 FX.params = &params;
114 FY.params = &params;
115 gsl_integration_workspace *w = gsl_integration_workspace_alloc(workspaceSize);
116 double resultX, resultY, absErrX, absErrY;
117 gsl_error_handler_t* err_default = gsl_set_error_handler_off();
118 int errX = gsl_integration_qag(&FX, 0, s, error, error, workspaceSize,
119 algorithm, w, &resultX, &absErrX);
120 int errY = gsl_integration_qag(&FY, 0, s, error, error, workspaceSize,
121 algorithm, w, &resultY, &absErrY);
122 if (errX || errY) {
123 *gmsg << "Warning - failed to reach specified error " << error
124 << " in multipoleT coordinateTransform" << endl;
125 *gmsg << " X " << errX << " absErr: " << absErrX << " s: " << s << endl;
126 *gmsg << " Y " << errY << " absErr: " << absErrY << " s: " << s << endl;
127 }
128 gsl_integration_workspace_free(w);
129 gsl_set_error_handler(err_default);
130 std::vector<double> result;
131 result.push_back(resultX);
132 result.push_back(resultY);
133 return result;
134}
135
137 const double &zlab) {
138 double s1 = -(5 * lambdaleft_m + s_0_m), s2 = (5 * lambdaright_m + s_0_m);
139 std::vector<double> shat1 = getUnitTangentVector(s1);
140 std::vector<double> shat2 = getUnitTangentVector(s2);
141 std::vector<double> r_1 = calcReferenceTrajectory(s1);
142 std::vector<double> r_2 = calcReferenceTrajectory(s2);
143 double eqn1 = (r_1[0] - xlab) * shat1[0] + (r_1[1] - zlab) * shat1[1];
144 double eqn2 = (r_2[0] - xlab) * shat2[0] + (r_2[1] - zlab) * shat2[1];
145 if (eqn1 * eqn2 > 0) {
146 s_m = 10 * s_0_m;
147 return;
148 }
149 // if (eqn1 > 0 && eqn2 < 0) {
150 // std::swap(eqn1, eqn2)
151 // }
152 int n = 0;
153 while (n < 10000 && std::abs(s1 - s2) > 1e-12) {
154 double stemp = (s2 + s1) / 2;
155 std::vector<double> r_temp = calcReferenceTrajectory(stemp);
156 std::vector<double> shattemp = getUnitTangentVector(stemp);
157 double eqntemp = (r_temp[0] - xlab) * shattemp[0] +
158 (r_temp[1] - zlab) * shattemp[1];
159 if (eqntemp > 0) {
160 s2 = stemp;
161 } else if (eqntemp < 0) {
162 s1 = stemp;
163 } else {
164 s_m = stemp;
165 return;
166 }
167 n++;
168 }
169 if (n == 10000) {
170 s_m = 0.0;
171 return;
172 }
173 s_m = (s2 + s1) / 2;
174}
175
177 const double &zlab) {
178 std::vector<double> shat = getUnitTangentVector(s_m);
179 std::vector<double> r_0 = calcReferenceTrajectory(s_m);
180 x_m = (xlab * shat[1] - zlab * shat[0] -
181 r_0[0] * shat[1] + r_0[1] * shat[0]);
182}
183
185 std::vector<double> &coordinates,
186 const double &boundingBoxLength) {
187 std::vector<double> r_entrance =
188 calcReferenceTrajectory(-boundingBoxLength);
189 std::vector<double> shat = getUnitTangentVector(-boundingBoxLength);
190 double x = coordinates[0], z = coordinates[1];
191 coordinates[0] = x * shat[1] + z * shat[0] + r_entrance[0];
192 coordinates[1] = -x * shat[0] + z * shat[1] + r_entrance[1];
193}
194
195double getUnitTangentVectorX(double s, void *p) {
196 struct myParams *params = (struct myParams *)p;
197 double prefactor = params->rho * (std::tanh(params->s_0 / params->lambdaleft) -
198 std::tanh(-params->s_0 / params->lambdaright));
199 return -std::sin((params->lambdaleft * std::log(std::cosh((s + params->s_0)
200 / params->lambdaleft)) - params->lambdaright
201 * std::log(std::cosh((s - params->s_0) / params->lambdaright))) / prefactor);
202}
203
204double getUnitTangentVectorY(double s, void *p) {
205 struct myParams *params = (struct myParams *)p;
206 double prefactor = params->rho * (std::tanh(params->s_0 / params->lambdaleft) -
207 std::tanh(-params->s_0 / params->lambdaright));
208 return std::cos((params->lambdaleft * std::log(std::cosh((s + params->s_0)
209 / params->lambdaleft)) - params->lambdaright
210 * std::log(std::cosh((s - params->s_0) / params->lambdaright))) / prefactor);
211}
212
213}
Inform * gmsg
Definition: Main.cpp:61
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
double getUnitTangentVectorX(double s, void *p)
double getUnitTangentVectorY(double s, void *p)
constexpr double e
The value of.
Definition: Physics.h:39
std::vector< double > getUnitTangentVector(const double &s) const
void transformFromEntranceCoordinates(std::vector< double > &coordinates, const double &boundingBoxLength)
void calcXCoordinate(const double &xlab, const double &ylab)
std::vector< double > getTransformation() const
std::vector< double > calcReferenceTrajectory(const double &s) const
CoordinateTransform & operator=(const CoordinateTransform &transform)
void calcSCoordinate(const double &xlab, const double &ylab)
Definition: Inform.h:42