OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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 #include "Physics/Units.h"
46 
48 
49 class Cyclotron;
50 
52 {
53 public:
61  typedef std::vector<double> container_t;
67  typedef std::function<Series(double,double,double)> Hamiltonian;
69  typedef std::function<Series(double,double,double)> SpaceCharge;
70 
72 
87  SigmaGenerator(double I, double ex, double ey, double ez,
88  double E, double m, double q, const Cyclotron* cycl,
89  unsigned int N, unsigned int Nsectors, unsigned int truncOrder, bool write = true);
90 
92 
104  bool match(double accuracy, unsigned int maxit, unsigned int maxitOrbit,
105  Cyclotron* cycl, double denergy, double rguess, bool full);
106 
108 
115 
117 
122  double isEigenEllipse(const matrix_t& Mturn, const matrix_t& sigma);
123 
125  matrix_t& getSigma();
126 
128  unsigned int getIterations() const;
129 
131  double getError() const;
132 
136  std::array<double,3> getEmittances() const;
137 
138  const double& getInjectionRadius() const {
139  return rinit_m;
140  }
141 
142  const double& getInjectionMomentum() const {
143  return prinit_m;
144  }
145 
146 private:
148  double I_m;
152  std::array<double,3> emittance_m;
154  double wo_m;
156  double E_m;
160  double gamma_m;
162  double gamma2_m;
164  double nh_m;
166  double beta_m;
168  double mass_m;
170  double q_m;
172  unsigned int niterations_m;
176  double Emin_m;
178  double Emax_m;
180  unsigned int N_m;
182  unsigned int nSectors_m;
184  unsigned int nStepsPerSector_m;
185 
187  unsigned int nSteps_m;
188 
190  double error_m;
191 
193  unsigned int truncOrder_m;
194 
196  bool write_m;
197 
200 
202  std::vector<matrix_t> sigmas_m;
203 
206 
209 
212 
213  double rinit_m;
214  double prinit_m;
215 
223  void initialize(double, double);
224 
226 
232  const vector_t&,
234  sparse_matrix_t&);
235 
237 
241  void updateSigma(const std::vector<matrix_t>&,
242  const std::vector<matrix_t>&);
243 
245 
249  double L2ErrorNorm(const matrix_t&, const matrix_t&);
250 
252 
255  std::string float2string(double val);
256 
258 
265  void writeOrbitOutput_m(const container_t& r_turn,
266  const container_t& peo,
267  const container_t& h_turn,
268  const container_t& fidx_turn,
269  const container_t& ds_turn);
270 
271  void writeMatrix(std::ofstream&, const matrix_t&);
272 
275 
276 
277  template<class matrix>
278  void reduce(matrix&);
279 
280  template<class matrix>
281  void expand(matrix&);
282 };
283 
284 
285 inline
286 typename SigmaGenerator::matrix_t&
288 {
289  return sigma_m;
290 }
291 
292 
293 inline
294 unsigned int SigmaGenerator::getIterations() const
295 {
296  return (converged_m) ? niterations_m : 0;
297 }
298 
299 
300 inline
302 {
303  return error_m;
304 }
305 
306 
307 inline
308 std::array<double,3> SigmaGenerator::getEmittances() const
309 {
310  double bgam = gamma_m*beta_m;
311  return std::array<double,3>{{
314  emittance_m[2] / Physics::pi / bgam * Units::m2mm * Units::rad2mrad
315  }};
316 }
317 
318 
319 template<class matrix>
320 void SigmaGenerator::reduce(matrix& M) {
321  /* The 6x6 matrix gets reduced to a 4x4 matrix in the following way:
322  *
323  * a11 a12 a13 a14 a15 a16
324  * a21 a22 a23 a24 a25 a26 a11 a12 a15 a16
325  * a31 a32 a33 a34 a35 a36 --> a21 a22 a25 a26
326  * a41 a42 a43 a44 a45 a46 a51 a52 a55 a56
327  * a51 a52 a53 a54 a55 a56 a61 a62 a65 a66
328  * a61 a62 a63 a64 a65 a66
329  */
330 
331  // copy x- and l-direction to a 4x4 matrix_t
332  matrix_t M4x4(4,4);
333  for (unsigned int i = 0; i < 2; ++i) {
334  // upper left 2x2 [a11,a12;a21,a22]
335  M4x4(i,0) = M(i,0);
336  M4x4(i,1) = M(i,1);
337  // lower left 2x2 [a51,a52;a61,a62]
338  M4x4(i + 2,0) = M(i + 4,0);
339  M4x4(i + 2,1) = M(i + 4,1);
340  // upper right 2x2 [a15,a16;a25,a26]
341  M4x4(i,2) = M(i,4);
342  M4x4(i,3) = M(i,5);
343  // lower right 2x2 [a55,a56;a65,a66]
344  M4x4(i + 2,2) = M(i + 4,4);
345  M4x4(i + 2,3) = M(i + 4,5);
346  }
347 
348  M.resize(4,4,false);
349  M.swap(M4x4);
350 }
351 
352 template<class matrix>
353 void SigmaGenerator::expand(matrix& M) {
354  /* The 4x4 matrix gets expanded to a 6x6 matrix in the following way:
355  *
356  * a11 a12 0 0 a13 a14
357  * a11 a12 a13 a14 a21 a22 0 0 a23 a24
358  * a21 a22 a23 a24 --> 0 0 1 0 0 0
359  * a31 a32 a33 a34 0 0 0 1 0 0
360  * a41 a42 a43 a44 a31 a32 0 0 a33 a34
361  * a41 a42 0 0 a43 a44
362  */
363 
364  matrix M6x6 = boost::numeric::ublas::identity_matrix<double>(6,6);
365 
366  for (unsigned int i = 0; i < 2; ++i) {
367  // upper left 2x2 [a11,a12;a21,a22]
368  M6x6(i,0) = M(i,0);
369  M6x6(i,1) = M(i,1);
370  // lower left 2x2 [a31,a32;a41,a42]
371  M6x6(i + 4,0) = M(i + 2,0);
372  M6x6(i + 4,1) = M(i + 2,1);
373  // upper right 2x2 [a13,a14;a23,a24]
374  M6x6(i,4) = M(i,2);
375  M6x6(i,5) = M(i,3);
376  // lower right 2x2 [a22,a34;a43,a44]
377  M6x6(i + 4,4) = M(i + 2,2);
378  M6x6(i + 4,5) = M(i + 2,3);
379  }
380 
381  // exchange
382  M.swap(M6x6);
383 }
384 
385 #endif
double getError() const
Returns the error (if the program didn&#39;t converged, one can call this function to check the error) ...
boost::numeric::ublas::vector< double, std::vector< double > > vector_t
Dense vector type definition.
std::vector< matrix_t > sigmas_m
Vector storing the second moment matrix for each angle.
constexpr double m2mm
Definition: Units.h:26
matrix_t sigma_m
Stores the stationary distribution (sigma matrix)
void initialize(double, double)
double I_m
Stores the value of the current, .
void reduce(matrix &)
void writeMatrix(std::ofstream &, const matrix_t &)
boost::numeric::ublas::matrix< double > matrix_t
Dense matrix type definition.
RealDiracMatrix::matrix_t matrix_t
Type for storing maps.
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.
constexpr double rad2mrad
Definition: Units.h:137
unsigned int nSectors_m
Number of (symmetric) sectors the field is averaged over.
const double & getInjectionRadius() const
constexpr double pi
The value of .
Definition: Physics.h:30
double L2ErrorNorm(const matrix_t &, const matrix_t &)
Returns the L2-error norm between the old and new sigma-matrix.
RealDiracMatrix::sparse_matrix_t sparse_matrix_t
Type for storing the sparse maps.
SpaceCharge Hsc_m
Stores the Hamiltonian for the space charge.
matrix_t updateInitialSigma(const matrix_t &, const vector_t &, sparse_matrix_t &, sparse_matrix_t &)
Computes the new initial sigma matrix.
std::function< Series(double, double, double)> Hamiltonian
Type of the Hamiltonian for the cyclotron.
double gamma2_m
Relativistic factor squared.
bool match(double accuracy, unsigned int maxit, unsigned int maxitOrbit, Cyclotron *cycl, double denergy, double rguess, bool full)
Searches for a matched distribution.
Series x_m
All variables x, px, z, pz, l, delta.
const double & getInjectionMomentum() const
double Emax_m
Maximum energy reached in cyclotron, .
RealDiracMatrix rdm_m
RealDiracMatrix-class member used for decoupling
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.
RealDiracMatrix::vector_t vector_t
Type for storing vectors.
void expand(matrix &)
boost::numeric::ublas::compressed_matrix< double, boost::numeric::ublas::row_major > sparse_matrix_t
Sparse matrix type definition.
double isEigenEllipse(const matrix_t &Mturn, const matrix_t &sigma)
Checks if the sigma-matrix is an eigenellipse and returns the L2 error.
double E_m
Stores the user-define energy, .
bool converged_m
Is true if converged, false otherwise.
double beta_m
Velocity (c/v), .
FTps< double, 2 *3 > Series
Type of the truncated power series.
unsigned int niterations_m
Is the number of iterations needed for convergence.
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().
matrix_t & getSigma()
Returns the converged stationary distribution.
double error_m
Error of computation.
std::vector< double > container_t
Container for storing the properties for each angle.
Vector truncated power series in n variables.
Definition: Component.h:34
std::array< double, 3 > getEmittances() const
Hamiltonian H_m
Stores the Hamiltonian of the cyclotron.
unsigned int getIterations() const
Returns the number of iterations needed for convergence (if not converged, it returns zero) ...
std::string float2string(double val)
Transforms a floating point value to a string.
double Emin_m
Minimum energy needed in cyclotron, .
std::array< double, 3 > emittance_m
std::function< Series(double, double, double)> SpaceCharge
Type of the Hamiltonian for the space charge.
double q_m
Is the particle charge [e].
double nh_m
Harmonic number, .
void updateSigma(const std::vector< matrix_t > &, const std::vector< matrix_t > &)
Computes new sigma matrices (one for each angle)
unsigned int nSteps_m
Number of integration steps in total.
bool write_m
Decides for writing output (default: true)
unsigned int truncOrder_m
Truncation order of the power series for the Hamiltonian (cyclotron and space charge) ...
unsigned int nStepsPerSector_m
Number of integration steps per sector (–&gt; also: number of maps per sector)
unsigned int N_m
Number of integration steps for closed orbit computation.
double wo_m
Is the orbital frequency, .
FVps< double, 2 *3 > Map
Type of a map.
double mass_m
Is the mass of the particles, .