49#include <boost/filesystem.hpp> 
   51#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> 
   64                               unsigned int Nsectors,
 
   65                               unsigned int truncOrder,
 
   71    , gamma2_m(gamma_m*gamma_m)
 
   72    , nh_m(cycl->getCyclHarm())
 
   73    , beta_m(
std::
sqrt(1.0-1.0/gamma2_m))
 
   78    , Emin_m(cycl->getFMLowE())
 
   79    , Emax_m(cycl->getFMHighE())
 
   81    , nSectors_m(Nsectors)
 
   82    , nStepsPerSector_m(N/cycl->getSymmetry())
 
   84    , error_m(
std::numeric_limits<double>::
max())
 
   85    , truncOrder_m(truncOrder)
 
   87    , sigmas_m(nStepsPerSector_m)
 
  112    H_m = [&](
double h, 
double kx, 
double ky) {
 
  118    Hsc_m = [&](
double sigx, 
double sigy, 
double sigz) {
 
  139        double tmp = sx * sy;                                           
 
  142        double kxy = K3 * 
std::abs(1.0 - f) / ((sx + sy) * sz); 
 
  144        double Kx = kxy / sx;
 
  145        double Ky = kxy / sy;
 
  146        double Kz = K3 * f / (tmp * sz);
 
  148        return -0.5 * Kx * 
x_m * 
x_m 
  157                           unsigned int maxitOrbit,
 
  188        if ( !cof.findOrbit(accuracy, maxitOrbit, 
E_m, denergy, rguess) ) {
 
  190                                "Closed orbit finder didn't converge.");
 
  193        cof.computeOrbitProperties(
E_m);
 
  196        container_t h    = cof.getInverseBendingRadius(angle);
 
  212        if (!boost::filesystem::exists(fpath)) {
 
  213            boost::filesystem::create_directory(fpath);
 
  216        std::pair<double,double> tunes = cof.getTunes();
 
  217        double ravg = cof.getAverageRadius();
 
  220        *
gmsg << 
"* ----------------------------" << 
endl 
  221                << 
"* Closed orbit info:" << 
endl 
  223                << 
"* average radius: " << ravg << 
" [m]" << 
endl 
  224                << 
"* initial radius: " << r[0] << 
" [m]" << 
endl 
  225                << 
"* initial momentum: " << peo[0] << 
" [Beta Gamma]" << 
endl 
  226                << 
"* frequency error: " << cof.getFrequencyError()*100 <<
" [ % ] "<< 
endl 
  227                << 
"* horizontal tune: " << tunes.first << 
endl 
  228                << 
"* vertical tune: " << tunes.second << 
endl 
  229                << 
"* ----------------------------" << 
endl << 
endl;
 
  235        std::ofstream writeMturn, writeMcyc, writeMsc;
 
  244                "OneTurnMapsForEnergy" + energy + 
"MeV.dat" 
  247            writeMturn.open(fname, std::ios::out);
 
  252                "SpaceChargeMapPerAngleForEnergy" + energy + 
"MeV_iteration_0.dat" 
  255            writeMsc.open(fname, std::ios::out);
 
  260                "CyclotronMapPerAngleForEnergy" + energy + 
"MeV.dat" 
  263            writeMcyc.open(fname, std::ios::out);
 
  267        for (
unsigned int i = 0; i < 
nSteps_m; ++i) {
 
  268            Mcycs[i] = mapgen.generateMap(
H_m(h[i],
 
  287        mapgen.combine(Mscs,Mcycs);
 
  303        while (
error_m > accuracy && !stop) {
 
  326                        "SpaceChargeMapPerAngleForEnergy" + energy + 
"MeV_iteration_" 
  331                writeMsc.open(fname, std::ios::out);
 
  335            for (
unsigned int i = 0; i < 
nSteps_m; ++i) {
 
  349            mapgen.combine(Mscs,Mcycs);
 
  350            Mturn = mapgen.getMap();
 
  371    } 
catch(
const std::exception& 
e) {
 
  379            "MatchedDistributions.dat" 
  382        std::ofstream writeSigmaMatched(fname, std::ios::out);
 
  386        writeSigmaMatched << 
"* Converged (Ex, Ey, Ez) = (" << emit[0]
 
  387                          << 
", " << emit[1] << 
", " << emit[2]
 
  388                          << 
") pi mm mrad for E= " << 
E_m << 
" (MeV)" 
  391        for(
unsigned int i = 0; i < 
sigma_m.size1(); ++ i) {
 
  392            writeSigmaMatched << std::setprecision(4)  << std::setw(11)
 
  394            for(
unsigned int j = 1; j < 
sigma_m.size2(); ++ j) {
 
  395                writeSigmaMatched << 
" & " <<  std::setprecision(4)
 
  396                                  << std::setw(11) << 
sigma_m(i,j);
 
  398            writeSigmaMatched << 
" \\\\" << 
std::endl;
 
  402        writeSigmaMatched.close();
 
  439    eigen(1) = - Ms(1,0);       
 
  441    eigen(3) = - Ms(3,2);       
 
  450    matrix_t newSigma = matt_boost::gemmm<matrix_t>(Mturn,
 
  452                                                    boost::numeric::ublas::trans(Mturn));
 
  499    double guessedEmittance = std::cbrt(ex * ey * ez);             
 
  502    double rcyc = ravg / 
beta_m;
 
  505    double avgInverseBendingRadius = 1.0 / ravg;
 
  526        sig = sig0 * std::cbrt(1.0 + 
alpha);            
 
  527    } 
else if (
alpha >= 0) {
 
  528        sig = sig0 * (1 + 
alpha * (0.25 - 0.03125 * 
alpha));
 
  531                            "Negative alpha value: " + std::to_string(
alpha) + 
" < 0");
 
  535    double K = K3 * 
gamma_m / (3.0 * sig * sig * sig);   
 
  538    double a = 0.5 * kx - K;    
 
  545                            "Negative value --> No real-valued frequency.");
 
  547    double tmp = 
a * 
a - b;           
 
  550                            "Square root of negative number.");
 
  556                            "Square root of negative number.");
 
  558    if (
std::pow(avgInverseBendingRadius, 2) * nuz * nuz <= K)
 
  560                            "h^{2} * nu_{z}^{2} <= K (i.e. square root of negative number)");
 
  565    double A = avgInverseBendingRadius / (Omega * Omega + K); 
 
  566    double B = avgInverseBendingRadius / (omega * omega + K); 
 
  567    double invAB = 1.0 / (B - A);                 
 
  570    matrix_t sigma = boost::numeric::ublas::zero_matrix<double>(6);
 
  573    sigma(0,0) = invAB * (B * ex / Omega + A * ez / omega);
 
  576    sigma(0,5) = sigma(5,0) = invAB * (ex / Omega + ez / omega);
 
  579    sigma(1,1) = invAB * (B * ex * Omega + A * ez * omega);
 
  582    sigma(1,4) = sigma(4,1) = invAB * (ex * Omega+ez * omega) / (K * 
gamma2_m);
 
  585    sigma(2,2) = ey / (
std::sqrt(
std::pow(avgInverseBendingRadius,2) * nuz * nuz - K));
 
  587    sigma(3,3) = (ey * ey) / sigma(2,2);
 
  590    sigma(4,4) = invAB * (A * ex * Omega + B * ez * omega) / (K * 
gamma2_m);
 
  593    sigma(5,5) = invAB * (ex / (B * Omega) + ez / (A * omega));
 
  607            "InitialSigmaPerAngleForEnergy" + energy + 
"MeV.dat" 
  610        std::ofstream writeInit(fname, std::ios::out);
 
  677    double gammax = 1.0 / betax;
 
  682    double gammal = 1.0 / betal;
 
  704    double cosz = 0.5 * (M(2,2) + M(3,3));
 
  706    double sign = (std::signbit(M(2,3))) ? 
double(-1) : double(1);
 
  710    double alphaz = 0.5 * (M(2,2) - M(3,3)) * invsinz;
 
  711    double betaz  =   M(2,3) * invsinz;
 
  712    double gammaz = - M(3,2) * invsinz;
 
  715    if (std::signbit(betaz))    
 
  719    matrix_t D = boost::numeric::ublas::zero_matrix<double>(6,6);
 
  722    D(1,0) = - gammax * ex;
 
  724    D(2,2) =   alphaz * ey;
 
  725    D(3,3) = - alphaz * ey;
 
  727    D(3,2) = - gammaz * ey;
 
  730    D(5,4) = - gammal * ez;
 
  733    expand<sparse_matrix_t>(
R);
 
  734    expand<sparse_matrix_t>(invR);
 
  738    S(0,1) = S(2,3) = S(4,5) = 1;
 
  739    S(1,0) = S(3,2) = S(5,4) = -1;
 
  741    matrix_t sigma = matt_boost::gemmm<matrix_t>(-invR,D,
R);
 
  750            "InitialSigmaPerAngleForEnergy" + energy + 
"MeV.dat" 
  753        std::ofstream writeInit(fname, std::ios::app);
 
  763                                 const std::vector<matrix_t>& Mcycs)
 
  765    std::ofstream writeSigma;
 
  773            "SigmaPerAngleForEnergy" + energy + 
"MeV_iteration_" 
  778        writeSigma.open(fname,std::ios::out);
 
  784    for (
unsigned int i = 1; i < 
nSteps_m; ++i) {
 
  789                                                     boost::numeric::ublas::trans(M));
 
  807    return std::sqrt(std::inner_product(diff.data().begin(),
 
  815    std::ostringstream out;
 
  816    out << std::setprecision(6) << val;
 
  834            "PropertiesForEnergy" + energy + 
"MeV.dat" 
  837    std::ofstream writeProperties(fname, std::ios::out);
 
  839    writeProperties << std::left
 
  840                    << std::setw(25) << 
"orbit radius" 
  841                    << std::setw(25) << 
"orbit momentum" 
  842                    << std::setw(25) << 
"inverse bending radius" 
  843                    << std::setw(25) << 
"field index" 
  844                    << std::setw(25) << 
"path length" << 
std::endl;
 
  846    for (
unsigned int i = 0; i < r.size(); ++i) {
 
  847        writeProperties << std::setprecision(10) << std::left
 
  848                        << std::setw(25) << r[i]
 
  849                        << std::setw(25) << peo[i]
 
  850                        << std::setw(25) << h[i]
 
  851                        << std::setw(25) << fidx[i]
 
  854    writeProperties.close();
 
  862    for (
unsigned int i = 0; i < 6; ++i) {
 
  863        for (
unsigned int j = 0; j < 6; ++j)
 
  864            os << m(i, j) << 
" ";
 
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
 
Tps< T > sqrt(const Tps< T > &x)
Square root.
 
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
 
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
 
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
 
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
 
Inform & endl(Inform &inf)
 
constexpr double two_pi
The value of.
 
constexpr double epsilon_0
The permittivity of vacuum in As/Vm.
 
constexpr double alpha
The fine structure constant, no dimension.
 
constexpr double e
The value of.
 
constexpr double mu_0
The permeability of vacuum in Vs/Am.
 
constexpr double c
The velocity of light in m/s.
 
constexpr double pi
The value of.
 
constexpr double mrad2rad
 
std::string::iterator iterator
 
std::string combineFilePath(std::initializer_list< std::string > ilist)
 
double getBetaGamma(double Ekin, double mass)
 
static OpalData * getInstance()
 
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
 
virtual double getPHIinit() const
 
static FTps makeVariable(int var)
Make variable.
 
static void setGlobalTruncOrder(int order)
Set the global truncation order.
 
This class generates the matrices for the one turn matrix of a cyclotron.
 
matrix_t symplex(const matrix_t &)
 
void diagonalize(matrix_t &, sparse_matrix_t &, sparse_matrix_t &)
 
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.
 
Hamiltonian H_m
Stores the Hamiltonian of the cyclotron.
 
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)
 
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.
 
double mass_m
Is the mass of the particles, .
 
Series x_m
All variables x, px, z, pz, l, delta.
 
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.
 
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 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.
 
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.
 
The base class for all OPAL exceptions.