OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
SigmaGenerator.h
Go to the documentation of this file.
1 //
2 // Class: SigmaGenerator
3 // The SigmaGenerator class uses the class <b>ClosedOrbitFinder</b> to get the parameters(inverse bending radius, path length
4 // field index and tunes) to initialize the sigma matrix.
5 // The main function of this class is <b>match(double, unsigned int)</b>, where it iteratively tries to find a matched
6 // distribution for given
7 // emittances, energy and current. The computation stops when the L2-norm is smaller than a user-defined tolerance. \n
8 // In default mode it prints all space charge maps, cyclotron maps and second moment matrices. The orbit properties, i.e.
9 // tunes, average radius, orbit radius, inverse bending radius, path length, field index and frequency error, are printed
10 // as well.
11 //
12 // Copyright (c) 2014, 2018, Matthias Frey, Cristopher Cortes, ETH Zürich
13 // All rights reserved
14 //
15 // Implemented as part of the Semester thesis by Matthias Frey
16 // "Matched Distributions in Cyclotrons"
17 //
18 // Some adaptations done as part of the Bachelor thesis by Cristopher Cortes
19 // "Limitations of a linear transfer map method for finding matched distributions in high intensity cyclotrons"
20 //
21 // This file is part of OPAL.
22 //
23 // OPAL is free software: you can redistribute it and/or modify
24 // it under the terms of the GNU General Public License as published by
25 // the Free Software Foundation, either version 3 of the License, or
26 // (at your option) any later version.
27 //
28 // You should have received a copy of the GNU General Public License
29 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
30 //
31 
32 #ifndef SIGMAGENERATOR_H
33 #define SIGMAGENERATOR_H
34 
35 #include <array>
36 #include <fstream>
37 #include <functional>
38 #include <string>
39 #include <vector>
40 
41 #include <boost/numeric/ublas/matrix.hpp>
42 
43 #include "FixedAlgebra/FTps.h"
44 #include "Physics/Physics.h"
45 
47 
48 class Cyclotron;
49 
51 {
52 public:
60  typedef std::vector<double> container_t;
66  typedef std::function<Series(double,double,double)> Hamiltonian;
68  typedef std::function<Series(double,double,double)> SpaceCharge;
69 
71 
86  SigmaGenerator(double I, double ex, double ey, double ez,
87  double E, double m, double q, const Cyclotron* cycl,
88  unsigned int N, unsigned int Nsectors, unsigned int truncOrder, bool write = true);
89 
91 
103  bool match(double accuracy, unsigned int maxit, unsigned int maxitOrbit,
104  Cyclotron* cycl, double denergy, double rguess, bool full);
105 
107 
114 
116 
121  double isEigenEllipse(const matrix_t& Mturn, const matrix_t& sigma);
122 
124  matrix_t& getSigma();
125 
127  unsigned int getIterations() const;
128 
130  double getError() const;
131 
135  std::array<double,3> getEmittances() const;
136 
137  const double& getInjectionRadius() const {
138  return rinit_m;
139  }
140 
141  const double& getInjectionMomentum() const {
142  return prinit_m;
143  }
144 
145 private:
147  double I_m;
151  std::array<double,3> emittance_m;
153  double wo_m;
155  double E_m;
159  double gamma_m;
161  double gamma2_m;
163  double nh_m;
165  double beta_m;
167  double m_m;
169  double q_m;
171  unsigned int niterations_m;
175  double Emin_m;
177  double Emax_m;
179  unsigned int N_m;
181  unsigned int nSectors_m;
183  unsigned int nStepsPerSector_m;
184 
186  unsigned int nSteps_m;
187 
189  double error_m;
190 
192  unsigned int truncOrder_m;
193 
195  bool write_m;
196 
199 
201  std::vector<matrix_t> sigmas_m;
202 
205 
208 
211 
212  double rinit_m;
213  double prinit_m;
214 
222  void initialize(double, double);
223 
225 
231  const vector_t&,
233  sparse_matrix_t&);
234 
236 
240  void updateSigma(const std::vector<matrix_t>&,
241  const std::vector<matrix_t>&);
242 
244 
248  double L2ErrorNorm(const matrix_t&, const matrix_t&);
249 
251 
254  std::string float2string(double val);
255 
257 
264  void writeOrbitOutput_m(const container_t& r_turn,
265  const container_t& peo,
266  const container_t& h_turn,
267  const container_t& fidx_turn,
268  const container_t& ds_turn);
269 
270  void writeMatrix(std::ofstream&, const matrix_t&);
271 
274 
275 
276  template<class matrix>
277  void reduce(matrix&);
278 
279  template<class matrix>
280  void expand(matrix&);
281 };
282 
283 
284 inline
285 typename SigmaGenerator::matrix_t&
287 {
288  return sigma_m;
289 }
290 
291 
292 inline
293 unsigned int SigmaGenerator::getIterations() const
294 {
295  return (converged_m) ? niterations_m : 0;
296 }
297 
298 
299 inline
301 {
302  return error_m;
303 }
304 
305 
306 inline
307 std::array<double,3> SigmaGenerator::getEmittances() const
308 {
309  double bgam = gamma_m*beta_m;
310  return std::array<double,3>{{
311  emittance_m[0] / Physics::pi / bgam * 1.0e6,
312  emittance_m[1] / Physics::pi / bgam * 1.0e6,
313  emittance_m[2] / Physics::pi / bgam * 1.0e6
314  }};
315 }
316 
317 
318 template<class matrix>
319 void SigmaGenerator::reduce(matrix& M) {
320  /* The 6x6 matrix gets reduced to a 4x4 matrix in the following way:
321  *
322  * a11 a12 a13 a14 a15 a16
323  * a21 a22 a23 a24 a25 a26 a11 a12 a15 a16
324  * a31 a32 a33 a34 a35 a36 --> a21 a22 a25 a26
325  * a41 a42 a43 a44 a45 a46 a51 a52 a55 a56
326  * a51 a52 a53 a54 a55 a56 a61 a62 a65 a66
327  * a61 a62 a63 a64 a65 a66
328  */
329 
330  // copy x- and l-direction to a 4x4 matrix_t
331  matrix_t M4x4(4,4);
332  for (unsigned int i = 0; i < 2; ++i) {
333  // upper left 2x2 [a11,a12;a21,a22]
334  M4x4(i,0) = M(i,0);
335  M4x4(i,1) = M(i,1);
336  // lower left 2x2 [a51,a52;a61,a62]
337  M4x4(i + 2,0) = M(i + 4,0);
338  M4x4(i + 2,1) = M(i + 4,1);
339  // upper right 2x2 [a15,a16;a25,a26]
340  M4x4(i,2) = M(i,4);
341  M4x4(i,3) = M(i,5);
342  // lower right 2x2 [a55,a56;a65,a66]
343  M4x4(i + 2,2) = M(i + 4,4);
344  M4x4(i + 2,3) = M(i + 4,5);
345  }
346 
347  M.resize(4,4,false);
348  M.swap(M4x4);
349 }
350 
351 template<class matrix>
352 void SigmaGenerator::expand(matrix& M) {
353  /* The 4x4 matrix gets expanded to a 6x6 matrix in the following way:
354  *
355  * a11 a12 0 0 a13 a14
356  * a11 a12 a13 a14 a21 a22 0 0 a23 a24
357  * a21 a22 a23 a24 --> 0 0 1 0 0 0
358  * a31 a32 a33 a34 0 0 0 1 0 0
359  * a41 a42 a43 a44 a31 a32 0 0 a33 a34
360  * a41 a42 0 0 a43 a44
361  */
362 
363  matrix M6x6 = boost::numeric::ublas::identity_matrix<double>(6,6);
364 
365  for (unsigned int i = 0; i < 2; ++i) {
366  // upper left 2x2 [a11,a12;a21,a22]
367  M6x6(i,0) = M(i,0);
368  M6x6(i,1) = M(i,1);
369  // lower left 2x2 [a31,a32;a41,a42]
370  M6x6(i + 4,0) = M(i + 2,0);
371  M6x6(i + 4,1) = M(i + 2,1);
372  // upper right 2x2 [a13,a14;a23,a24]
373  M6x6(i,4) = M(i,2);
374  M6x6(i,5) = M(i,3);
375  // lower right 2x2 [a22,a34;a43,a44]
376  M6x6(i + 4,4) = M(i + 2,2);
377  M6x6(i + 4,5) = M(i + 2,3);
378  }
379 
380  // exchange
381  M.swap(M6x6);
382 }
383 
384 #endif
constexpr double pi
The value of.
Definition: Physics.h:30
Vector truncated power series in n variables.
Definition: FVps.h:39
boost::numeric::ublas::compressed_matrix< double, boost::numeric::ublas::row_major > sparse_matrix_t
Sparse matrix type definition.
boost::numeric::ublas::matrix< double > matrix_t
Dense matrix type definition.
boost::numeric::ublas::vector< double, std::vector< double > > vector_t
Dense vector type definition.
unsigned int niterations_m
Is the number of iterations needed for convergence.
double E_m
Stores the user-define energy, .
bool write_m
Decides for writing output (default: true)
void writeMatrix(std::ofstream &, const matrix_t &)
double isEigenEllipse(const matrix_t &Mturn, const matrix_t &sigma)
Checks if the sigma-matrix is an eigenellipse and returns the L2 error.
std::vector< double > container_t
Container for storing the properties for each angle.
std::array< double, 3 > getEmittances() const
double gamma2_m
Relativistic factor squared.
FTps< double, 2 *3 > Series
Type of the truncated power series.
void expand(matrix &)
Hamiltonian H_m
Stores the Hamiltonian of the cyclotron.
double m_m
Is the mass of the particles, .
matrix_t & getSigma()
Returns the converged stationary distribution.
double error_m
Error of computation.
matrix_t updateInitialSigma(const matrix_t &, const vector_t &, sparse_matrix_t &, sparse_matrix_t &)
Computes the new initial sigma matrix.
unsigned int nSteps_m
Number of integration steps in total.
RealDiracMatrix::sparse_matrix_t sparse_matrix_t
Type for storing the sparse maps.
unsigned int nSectors_m
Number of (symmetric) sectors the field is averaged over.
unsigned int nStepsPerSector_m
Number of integration steps per sector (--> also: number of maps per sector)
const double & getInjectionRadius() const
double I_m
Stores the value of the current, .
std::function< Series(double, double, double)> SpaceCharge
Type of the Hamiltonian for the space charge.
double Emin_m
Minimum energy needed in cyclotron, .
unsigned int truncOrder_m
Truncation order of the power series for the Hamiltonian (cyclotron and space charge)
SigmaGenerator(double I, double ex, double ey, double ez, double E, double m, double q, const Cyclotron *cycl, unsigned int N, unsigned int Nsectors, unsigned int truncOrder, bool write=true)
Constructs an object of type SigmaGenerator.
double L2ErrorNorm(const matrix_t &, const matrix_t &)
Returns the L2-error norm between the old and new sigma-matrix.
RealDiracMatrix rdm_m
RealDiracMatrix-class member used for decoupling
FVps< double, 2 *3 > Map
Type of a map.
Series x_m
All variables x, px, z, pz, l, delta.
void reduce(matrix &)
SpaceCharge Hsc_m
Stores the Hamiltonian for the space charge.
double q_m
Is the particle charge [e].
RealDiracMatrix::matrix_t matrix_t
Type for storing maps.
std::vector< matrix_t > sigmas_m
Vector storing the second moment matrix for each angle.
double Emax_m
Maximum energy reached in cyclotron, .
matrix_t sigma_m
Stores the stationary distribution (sigma matrix)
double nh_m
Harmonic number, .
vector_t decouple(const matrix_t &Mturn, sparse_matrix_t &R, sparse_matrix_t &invR)
Block diagonalizes the symplex part of the one turn transfer matrix.
double getError() const
Returns the error (if the program didn't converged, one can call this function to check the error)
const double & getInjectionMomentum() const
double wo_m
Is the orbital frequency, .
std::function< Series(double, double, double)> Hamiltonian
Type of the Hamiltonian for the cyclotron.
unsigned int N_m
Number of integration steps for closed orbit computation.
void initialize(double, double)
bool converged_m
Is true if converged, false otherwise.
void writeOrbitOutput_m(const container_t &r_turn, const container_t &peo, const container_t &h_turn, const container_t &fidx_turn, const container_t &ds_turn)
Called within SigmaGenerator::match().
void updateSigma(const std::vector< matrix_t > &, const std::vector< matrix_t > &)
Computes new sigma matrices (one for each angle)
std::string float2string(double val)
Transforms a floating point value to a string.
RealDiracMatrix::vector_t vector_t
Type for storing vectors.
unsigned int getIterations() const
Returns the number of iterations needed for convergence (if not converged, it returns zero)
double beta_m
Velocity (c/v), .
std::array< double, 3 > emittance_m
bool match(double accuracy, unsigned int maxit, unsigned int maxitOrbit, Cyclotron *cycl, double denergy, double rguess, bool full)
Searches for a matched distribution.