Commit 078763a6 authored by cortes_c's avatar cortes_c
Browse files

Fix Cyclotron transfer matrices

parent 52af4fa7
......@@ -90,7 +90,7 @@ public:
virtual ~ParallelCyclotronTracker();
/// Apply the algorithm to an Ring
/// Apply the algorithm to a Ring
virtual void visitRing(const Ring &ring);
/// Apply the algorithm to a Cyclotorn
......@@ -267,7 +267,7 @@ private:
double sinRefTheta_m;
double cosRefTheta_m;
/// The number of bunches specified in TURNS of RUN commond
/// The number of bunches specified in TURNS of RUN command
int numBunch_m;
// 0 for single bunch (default),
......
This diff is collapsed.
......@@ -235,18 +235,6 @@ Distribution::~Distribution() {
gsl_rng_free(randGen_m);
delete laserProfile_m;
}
/*
void Distribution::printSigma(SigmaGenerator<double,unsigned int>::matrix_type& M, Inform& out) {
for (int i=0; i<M.size1(); ++i) {
for (int j=0; j<M.size2(); ++j) {
*gmsg << M(i,j) << " ";
}
*gmsg << endl;
}
}
*/
/**
* Calculate the local number of particles evenly and adjust node 0
* such that n is matched exactly.
......@@ -1317,7 +1305,7 @@ void Distribution::createMatchedGaussDistribution(size_t numberOfParticles, doub
"'CYCLOTRON' definition.");
}
int Nint = 1440*2;
int Nint = 1440;
double scaleFactor = 1.0;
bool writeMap = true;
......@@ -1385,23 +1373,19 @@ void Distribution::createMatchedGaussDistribution(size_t numberOfParticles, doub
for (unsigned int i = 0; i < 6; ++ i)
for (unsigned int j = 0; j < 6; ++ j) sigma(i, j) *= 1e-6;
for (unsigned int i = 0; i < 3; ++ i) {
for (unsigned int i = 0; i < 3; ++ i)
if ( sigma(2 * i, 2 * i) < 0 || sigma(2 * i + 1, 2 * i + 1) < 0 )
throw OpalException("Distribution::CreateMatchedGaussDistribution()",
"Negative value on the diagonal of the sigma matrix.");
}
setDistParametersBinomial(massIneV);
sigmaR_m[0] = std::sqrt(sigma(0, 0));
sigmaP_m[0] = std::sqrt(sigma(1, 1))*beta*gamma;
sigmaR_m[2] = std::sqrt(sigma(2, 2));
sigmaP_m[2] = std::sqrt(sigma(3, 3))*beta*gamma;
sigmaR_m[1] = std::sqrt(sigma(4, 4));
// delta = |p - p_0|/|p_0| = |p - p_0|/beta*gamma --> l'^2 = (delta*beta*gamma)^2 - (x'^2 + z'^2)
//double lprime2 = sigma(5, 5)*(beta*beta*gamma*gamma) - sigmaP_m[0]*sigmaP_m[0] - sigmaP_m[2]*sigmaP_m[2];
//sigmaP_m[1] = std::sqrt(std::abs(lprime2));
double pl2 = (std::sqrt(sigma(5,5)) + 1)*(std::sqrt(sigma(5,5)) + 1)*beta*gamma*beta*gamma - sigmaP_m[0]*sigmaP_m[0] - sigmaP_m[2]*sigmaP_m[2];
double pl = std::sqrt(pl2);
sigmaP_m[1] = gamma*(pl - beta*gamma);
sigmaP_m[1] = std::sqrt(sigma(5,5))*beta*gamma;
correlationMatrix_m(1, 0) = sigma(0, 1) / (sqrt(sigma(0, 0) * sigma(1, 1)));
correlationMatrix_m(3, 2) = sigma(2, 3) / (sqrt(sigma(2, 2) * sigma(3, 3)));
......@@ -1411,8 +1395,8 @@ void Distribution::createMatchedGaussDistribution(size_t numberOfParticles, doub
correlationMatrix_m(5, 0) = sigma(0, 5) / (sqrt(sigma(0, 0) * sigma(5, 5)));
correlationMatrix_m(5, 1) = sigma(1, 5) / (sqrt(sigma(1, 1) * sigma(5, 5)));
createDistributionGauss(numberOfParticles, massIneV);
//createDistributionBinomial(numberOfParticles, massIneV);
createDistributionGauss(numberOfParticles,massIneV);
// update injection radius and radial momentum (m --> mm)
CyclotronElement->setRinit(siggen->getInjectionRadius()*1000);
CyclotronElement->setPRinit(siggen->getInjectionMomentum());
......@@ -2494,7 +2478,7 @@ void Distribution::generateGaussZ(size_t numberOfParticles) {
//Sets the GSL error handler off, exception will be handled internaly with a renormalization method
gsl_set_error_handler_off();
int errcode = gsl_linalg_cholesky_decomp(corMat);
double rn = 1e-12;
double rn = 1e-14;
while (errcode == GSL_EDOM) {
......
......@@ -140,6 +140,8 @@ MapGenerator<Value_type,
// expand
map_type M = ExpMap(-H * ds, order);
// get linear part
FMatrix<value_type,6,6> matrix = M.linearTerms();
......@@ -174,7 +176,7 @@ void MapGenerator<Value_type,
Mturn_m = boost::numeric::ublas::identity_matrix<value_type>(6);
for (size_type i = 0; i < nMaps_m; ++i)
Mturn_m = matt_boost::gemmm<matrix_type>(Mscs[i],Mcycs[i],Mturn_m);
Mturn_m = matt_boost::gemmm<matrix_type>(Mcycs[i],Mscs[i],Mturn_m);
}
template<typename Value_type,
......
......@@ -329,6 +329,23 @@ class SigmaGenerator
*/
matrix_type updateInitialSigma(const complex_matrix_type&, const complex_matrix_type&);
/// Computes the linear transfer cyclotron maps
/*!
* @param h is the bending radius
* @param n is the field index
* @param ds is the length of the integration step
*/
matrix_type generateCycMap(const value_type&, const value_type&, const value_type&);
/// Computes the linear transfer space charge maps
/*!
* @param sigx is the defocussing force in radial direction
* @param sigz is the defocussing force in vertical direction
* @param sigl is the defocussing force in longitudinal direction
* @param ds is the length of the integration step
*/
matrix_type generateSCMap(const value_type&, const value_type&, const value_type&,const value_type&);
/// Computes new sigma matrices (one for each angle)
/*!
* Mscs is a vector of all space charge maps
......@@ -408,12 +425,12 @@ SigmaGenerator<Value_type, Size_type>::SigmaGenerator(value_type I, value_type e
error_m(1),
fieldmap_m(fieldmap), truncOrder_m(truncOrder), write_m(write),
scaleFactor_m(scaleFactor), sigmas_m(0),permutations_m{{0,1,2,3},{1,2,3,0},{0,1,3,2},{1,0,2,3},{0,2,3,1},{0,3,2,1},
{1,0,3,2},{1,3,2,0},{2,1,0,3},{2,0,1,3},{2,3,0,1},{2,3,1,0},{3,1,0,2},{3,2,0,1}, {3,2,1,0},{3,0,1,2}},
{1,0,3,2},{1,3,2,0},{2,1,0,3},{2,0,1,3},{2,3,0,1},{2,3,1,0},{3,1,0,2},{3,2,0,1},{3,2,1,0},{3,0,1,2},{0,2,1,3},
{0,3,1,2},{1,2,0,3},{1,3,0,2},{2,1,3,0},{2,0,3,1},{3,1,2,0},{3,0,2,1}},
rinit_m(0.0),
prinit_m(0.0)
// The permutations up converge to a matched distribution, but the first four give the 4 unique solutions
// Following permutations threw an OPAL error, whose reason I still don't know.
//{0,2,1,3},{0,3,1,2},{1,2,0,3},{1,3,0,2},{2,1,3,0},{2,0,3,1},{3,1,2,0},{3,0,2,1}
//
{
nSteps_m = N_m;
......@@ -505,7 +522,7 @@ template<typename Value_type, typename Size_type>
nSteps_m = nStepsPerSector_m;
// object for space cyclotron map
MapGenerator<value_type,size_type,Series,Map,Hamiltonian,SpaceCharge> mapgen(nSteps_m);
// MapGenerator<value_type,size_type,Series,Map,Hamiltonian,SpaceCharge> mapgen(nSteps_m);
container_type h(nSteps_m), r(nSteps_m), ds(nSteps_m), fidx(nSteps_m);
value_type ravg = 0.0;
......@@ -574,17 +591,18 @@ template<typename Value_type, typename Size_type>
// calculate only for a single sector (a nSector_-th) of the whole cyclotron
for (size_type i = 0; i < nSteps_m; ++i)
Mcycs[i] = mapgen.generateMap(H_m(h[i],h[i]*h[i]+fidx[i],-fidx[i]),ds[i],truncOrder_m);
Mcycs[i] = generateCycMap(h[i],fidx[i],ds[i]);
// search for a match distribution for each permutation
// Set to search for the permutation which converged to a matched distribution upon tracking
// Note that 4 permutations converge to the same matched distribution
for(size_type permutation = 0; permutation < 1; permutation++){
findMatchDistribution(accuracy,h,fidx,ds,tunes,ravg,maxit,Mcycs,harmonic,2);
findMatchDistribution(accuracy,h,fidx,ds,tunes,ravg,maxit,Mcycs,harmonic,0);
}
std::cout << "OPAL> * Number of matched distributions: " <<matchedSigmas_m.size() << std::endl;
std::cout << "OPAL> * Last matched distribution information: "<<std::endl;
}
}catch(const std::exception& e) {
std::cerr << e.what() << std::endl;
}
......@@ -821,7 +839,7 @@ template<typename Value_type, typename Size_type>
// new initial sigma matrix
matrix_type newSigma(6,6);
value_type weight = 0.65;
value_type weight = 0.065;
// for exiting the loop if maxit is reached
bool stop = false;
......@@ -831,13 +849,12 @@ template<typename Value_type, typename Size_type>
// initialize sigma matrices (for each angle one) (first guess)
initialize(tunes.second,ravg);
// calculate only for a single sector (a nSector_-th) of the whole cyclotron
// compute new space charge maps
for (size_type i = 0; i < nSteps_m; ++i) {
if (!harmonic) {
Mscs[i] = mapgen.generateMap(Hsc_m(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4)),ds[i],truncOrder_m);
Mscs[i] = generateSCMap(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4),ds[i]);
} else {
Mscs[i] = mapgen.generateMap(Hsc_m(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4)),const_ds,truncOrder_m);
Mscs[i] = generateSCMap(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4),const_ds);
}
}
......@@ -873,9 +890,9 @@ template<typename Value_type, typename Size_type>
// compute new space charge maps
for (size_type i = 0; i < nSteps_m; ++i) {
if (!harmonic) {
Mscs[i] = mapgen.generateMap(Hsc_m(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4)),ds[i],truncOrder_m);
Mscs[i] = generateSCMap(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4),ds[i]);
} else {
Mscs[i] = mapgen.generateMap(Hsc_m(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4)),const_ds,truncOrder_m);
Mscs[i] = generateSCMap(sigmas_m[i](0,0),sigmas_m[i](2,2),sigmas_m[i](4,4),const_ds);
}
}
......@@ -1049,6 +1066,8 @@ typename SigmaGenerator<Value_type, Size_type>::matrix_type SigmaGenerator<Value
D(2*i,2*i) = emittance_m[i]*invbg*im;
D(2*i+1,2*i+1) = -emittance_m[i]*invbg*im;
}
D(2,2) *= -1.;
D(3,3) *= -1.;
// Computing of new Sigma
// sigma = -R*D*R^{-1}*S
......@@ -1063,9 +1082,8 @@ typename SigmaGenerator<Value_type, Size_type>::matrix_type SigmaGenerator<Value
}
}
for(value_type i = 0; i < 6; i++){
if(newSigmareal(i,i) < 0.) newSigmareal(i,i) *= -1.0;
}
for(value_type i = 0; i < 6; i++)
if (newSigmareal(i,i) < 0.) newSigmareal(i,i) *= -1;
return newSigmareal;
}
......@@ -1074,30 +1092,88 @@ template<typename Value_type, typename Size_type>
void SigmaGenerator<Value_type, Size_type>::updateSigma(const std::vector<matrix_type>& Mscs, const std::vector<matrix_type>& Mcycs) {
matrix_type M = boost::numeric::ublas::matrix<value_type>(6,6);
std::ofstream writeSigma;
if (write_m) {
std::string energy = float2string(E_m);
writeSigma.open("data/maps/SigmaPerAngleForEnergy"+energy+"MeV.dat",std::ios::app);
}
// initial sigma is already computed
for (size_type i = 1; i < nSteps_m; ++i) {
// transfer matrix for one angle
M = boost::numeric::ublas::prod(Mscs[i - 1],Mcycs[i - 1]);
// transfer the matrix sigma
sigmas_m[i] = matt_boost::gemmm<matrix_type>(M,sigmas_m[i - 1],boost::numeric::ublas::trans(M));
if (write_m)
writeSigma << sigmas_m[i] << std::endl;
}
}
template<typename Value_type, typename Size_type>
typename SigmaGenerator<Value_type, Size_type>::matrix_type
SigmaGenerator<Value_type, Size_type>::generateCycMap(const value_type& h,
const value_type& n,
const value_type& ds){
value_type kx = h*h + n;
value_type kz = -n;
matrix_type M(6,6);
for(size_type i = 0; i < 6; i++)
for(size_type j = 0; j < 6; j++) M(i,j) = 0.0;
for(size_type i = 0; i < 6; i++) M(i,i) = 1.0;
M(0,1) = ds;
M(1,0) = -kx*ds;
M(1,5) = h*ds;
M(2,3) = ds;
M(3,2) = -kz*ds;
M(4,0) = -h*ds;
M(4,5) = ds/gamma2_m;
return M;
if (write_m) {
writeSigma << std::endl;
writeSigma.close();
}
}
template<typename Value_type, typename Size_type>
typename SigmaGenerator<Value_type, Size_type>::matrix_type
SigmaGenerator<Value_type, Size_type>::generateSCMap(const value_type& sigx,
const value_type& sigz,
const value_type& sigl,
const value_type& ds){
// convert m from MeV/c^2 to eV*s^{2}/m^{2}
value_type m = m_m * 1.0e6 / (Physics::c * Physics::c);
// formula (57)
value_type lam = 2.0 * Physics::pi*Physics::c / (wo_m * nh_m); // wavelength, [lam] = m
value_type K3 = 3.0 * /* physics::q0 */ 1.0 * I_m * lam / (20.0 * std::sqrt(5.0) * Physics::pi * Physics::epsilon_0 * m
* Physics::c * Physics::c * Physics::c * beta_m * beta_m * gamma_m * gamma2_m);
// [K3] = m
value_type milli = 1.0e-3;
// formula (30), (31)
// [sigma(0,0)] = mm^{2} rad --> [sx] = [sz] = [sl] = mm
// multiply with 0.001 to get meter --> [sx] = [sz] = [sl] = m
value_type sx = std::sqrt(std::fabs(sigx)) * milli;
value_type sz = std::sqrt(std::fabs(sigz)) * milli;
value_type sl = std::sqrt(std::fabs(sigl)) * milli;
value_type tmp = sx * sz; // [tmp] = m^{2}
value_type f = std::sqrt(tmp) / (3.0 * gamma_m * sl); // [f] = 1
value_type kxy = K3 * std::fabs(1.0 - f) / ((sx + sz) * sl); // [kxy] = 1/m
value_type Kx = kxy / sx;
value_type Kz = kxy / sz;
value_type Kl = K3 * f / (tmp * sl);
matrix_type M(6,6);
for(size_type i = 0; i < 6; i++)
for(size_type j = 0; j < 6; j++) M(i,j) = 0.0;
for(size_type i = 0; i < 6; i++) M(i,i) = 1.0;
M(1,0) = Kx*ds;
M(3,2) = Kz*ds;
M(5,4) = Kl*gamma2_m*ds;
return M;
}
template<typename Value_type, typename Size_type>
typename SigmaGenerator<Value_type, Size_type>::value_type SigmaGenerator<Value_type, Size_type>::L2ErrorNorm(const matrix_type& oldS, const matrix_type& newS) {
// compute difference
......@@ -1153,7 +1229,8 @@ template<typename Value_type, typename Size_type> void SigmaGenerator<Value_type
writeSigmas<<std::endl;
writeSigmas.close();
std::ofstream writeOneTurn("data/OneTurnMatrix"+energy+"MeV.txt", std::ios::app);
std::ofstream writeOneTurn("data/OneTurnMatrix_noSpaceCharge"+energy+"MeV.txt", std::ios::app);
/*
for(size_type i = 0; i < 6; i++){
for(size_type j = 0; j < 6; j++){
writeOneTurn<<std::left<<std::setprecision(5)
......@@ -1161,6 +1238,18 @@ template<typename Value_type, typename Size_type> void SigmaGenerator<Value_type
}
writeOneTurn<<std::endl;
}
*/
matrix_type M = boost::numeric::ublas::matrix<value_type>(6,6);
for(size_type k = 1; k < nSteps_m; k++){
M = Mcycs[k];
for(size_type i = 0; i < 6; i++){
for(size_type j = 0; j < 6; j++){
writeOneTurn<<std::left<<std::setprecision(5)
<<std::setw(12)<<Mcyc(i,j);
}
writeOneTurn<<std::endl;
}
}
writeOneTurn<<std::endl;
writeOneTurn.close();
......@@ -1169,7 +1258,14 @@ template<typename Value_type, typename Size_type> void SigmaGenerator<Value_type
ss << permutation;
std::string p = ss.str();
writeSigma.open("data/SigmaPerAngleForEnergy"+p+"_"+energy+"MeV.dat",std::ios::app);
matrix_type M = boost::numeric::ublas::matrix<value_type>(6,6);
//matrix_type M = boost::numeric::ublas::matrix<value_type>(6,6);
for(size_type i = 0; i < 6; i++){
for(size_type j = 0; j < 6; j++){
writeSigma<<std::left<<std::setprecision(5)
<<std::setw(12)<<match(i,j);
}
writeSigma<<std::endl;
}
// initial sigma is already computed
for (size_type i = 1; i < nSteps_m; ++i) {
// transfer matrix for one angle
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment