OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 
37 extern Inform *gmsg;
38 
39 namespace coordinatetransform {
40 
41 const double CoordinateTransform::error = 1e-10;
42 const int CoordinateTransform::workspaceSize = 1000;
43 const 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 
85 std::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 * (tanh(s_0_m / lambdaleft_m) -
98  result.push_back(-sin((lambdaleft_m * log(cosh((s + s_0_m) / lambdaleft_m))
100  / prefactor));
101  result.push_back(cos((lambdaleft_m * log(cosh((s + s_0_m) / lambdaleft_m))
102  - lambdaright_m * log(cosh((s - s_0_m) / lambdaright_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 
136 void CoordinateTransform::calcSCoordinate(const double &xlab,
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 && fabs(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 
176 void CoordinateTransform::calcXCoordinate(const double &xlab,
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 
195 double getUnitTangentVectorX(double s, void *p) {
196  struct myParams *params = (struct myParams *)p;
197  double prefactor = params->rho * (tanh(params->s_0 / params->lambdaleft) -
198  tanh(-params->s_0 / params->lambdaright));
199  return -sin((params->lambdaleft * log(cosh((s + params->s_0)
200  / params->lambdaleft)) - params->lambdaright
201  * log(cosh((s - params->s_0) / params->lambdaright))) / prefactor);
202 }
203 
204 double getUnitTangentVectorY(double s, void *p) {
205  struct myParams *params = (struct myParams *)p;
206  double prefactor = params->rho * (tanh(params->s_0 / params->lambdaleft) -
207  tanh(-params->s_0 / params->lambdaright));
208  return cos((params->lambdaleft * log(cosh((s + params->s_0)
209  / params->lambdaleft)) - params->lambdaright
210  * log(cosh((s - params->s_0) / params->lambdaright))) / prefactor);
211 }
212 
213 }
214 
double getUnitTangentVectorY(double s, void *p)
void calcSCoordinate(const double &xlab, const double &ylab)
constexpr double e
The value of .
Definition: Physics.h:40
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Inform * gmsg
Definition: Main.cpp:21
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
std::vector< double > calcReferenceTrajectory(const double &s) const
CoordinateTransform & operator=(const CoordinateTransform &transform)
void transformFromEntranceCoordinates(std::vector< double > &coordinates, const double &boundingBoxLength)
std::vector< double > getTransformation() const
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
std::vector< double > getUnitTangentVector(const double &s) const
void calcXCoordinate(const double &xlab, const double &ylab)
double getUnitTangentVectorX(double s, void *p)
Definition: Inform.h:41
Tps< T > tanh(const Tps< T > &x)
Hyperbolic tangent.
Definition: TpsMath.h:240
Inform & endl(Inform &inf)
Definition: Inform.cpp:42