//
// Class Cyclotron
// Defines the abstract interface for a cyclotron.
//
// Copyright (c) 2007 - 2012, Jianjun Yang and Andreas Adelmann, Paul Scherrer Institut, Villigen PSI, Switzerland
// Copyright (c) 2013 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// Implemented as part of the PhD thesis
// "Beam dynamics in high intensity cyclotrons including neighboring bunch effects"
// and the paper
// "Beam dynamics in high intensity cyclotrons including neighboring bunch effects:
// Model, implementation, and application"
// (https://journals.aps.org/prab/pdf/10.1103/PhysRevSTAB.13.064201)
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see .
//
#ifndef CLASSIC_Cyclotron_HH
#define CLASSIC_Cyclotron_HH
#include "AbsBeamline/Component.h"
#include
#include
class Fieldmap;
class LossDataSink;
class TrimCoil;
struct BfieldData {
std::string filename;
// known from file: field and three theta derivatives
std::vector bfld; //Bz
std::vector dbt; //dBz/dtheta
std::vector dbtt; //d2Bz/dtheta2
std::vector dbttt; //d3Bz/dtheta3
// to be calculated in getdiffs: all other derivatives:
std::vector dbr; // dBz/dr
std::vector dbrr; // ...
std::vector dbrrr;
std::vector dbrt;
std::vector dbrrt;
std::vector dbrtt;
// used to get (Br,Btheta,Bz) at any off-plane point
std::vector f2; // for Bz
std::vector f3; // for Br
std::vector g3; // for Btheta
// Grid-Size
int nrad, ntet; //need to be read from inputfile.
int ntetS; // one more grid line is stored in azimuthal direction
int ntot; // total grid points number.
// Mean and Maximas
double bacc, dbtmx, dbttmx, dbtttmx;
};
struct BPositions {
// these 4 parameters are need to be read from field file.
double rmin, delr;
double tetmin, dtet;
// Radii and step width of initial Grid
std::vector rarr;
// int ThetaPeriodicity; // Periodicity of Magnetic field
double Bfact; // MULTIPLICATION FACTOR FOR MAGNETIC FIELD
};
class Cyclotron: public Component {
public:
enum class BFieldType {
PSIBF,
CARBONBF,
ANSYSBF,
AVFEQBF,
FFABF,
BANDRF,
SYNCHRO
};
/// Constructor with given name.
explicit Cyclotron(const std::string& name);
Cyclotron();
Cyclotron(const Cyclotron &);
virtual ~Cyclotron();
/// Apply visitor to Cyclotron.
virtual void accept(BeamlineVisitor &) const;
/// Get number of slices.
// Slices and stepsize used to determine integration step.
virtual double getSlices() const = 0;
/// Get stepsize.
// Slices and stepsize used to determine integration step.
virtual double getStepsize() const = 0;
void setFieldMapFN(std::string fmapfn);
virtual std::string getFieldMapFN() const;
void setRfFieldMapFN(std::vector rffmapfn);
void setRFFCoeffFN(std::vector rff_coeff_fn);
void setRFVCoeffFN(std::vector rfv_coeff_fn);
void setCyclotronType(std::string t);
const std::string &getCyclotronType() const;
virtual ElementBase::ElementType getType() const;
virtual void getDimensions(double& zBegin, double& zEnd) const;
unsigned int getNumberOfTrimcoils() const;
void setCyclHarm(double h);
virtual double getCyclHarm() const;
void setRfPhi(std::vector f);
double getRfPhi(unsigned int i) const;
void setRfFrequ(std::vector f);
double getRfFrequ(unsigned int i) const;
void setSymmetry(double symmetry);
virtual double getSymmetry() const;
void setRinit(double rinit);
virtual double getRinit() const;
void setPRinit(double prinit);
virtual double getPRinit() const;
void setPHIinit(double phiinit);
virtual double getPHIinit() const;
void setZinit(double zinit);
virtual double getZinit() const;
void setPZinit(double zinit);
virtual double getPZinit() const;
void setBScale(double bs);
virtual double getBScale() const;
void setEScale(std::vector bs);
virtual double getEScale(unsigned int i) const;
void setTrimCoils(const std::vector& trimcoils);
void setSuperpose(std::vector flag);
virtual bool getSuperpose(unsigned int i) const;
void setMinR(double r);
virtual double getMinR() const;
void setMaxR(double r);
virtual double getMaxR() const;
void setMinZ(double z);
virtual double getMinZ() const;
void setMaxZ(double z);
virtual double getMaxZ() const;
void setFMLowE(double e);
virtual double getFMLowE() const;
void setFMHighE(double e);
virtual double getFMHighE() const;
void setTrimCoilThreshold(double);
virtual double getTrimCoilThreshold() const;
void setSpiralFlag(bool spiral_flag);
virtual bool getSpiralFlag() const;
virtual bool apply(const size_t& id, const double& t, Vector_t& E, Vector_t& B);
virtual bool apply(const Vector_t& R, const Vector_t& P, const double& t, Vector_t& E, Vector_t& B);
virtual void apply(const double& rad, const double& z,
const double& tet_rad, double& br,
double& bt, double& bz);
virtual void initialise(PartBunchBase* bunch, double& startField, double& endField);
virtual void initialise(PartBunchBase* bunch, const double& scaleFactor);
virtual void finalise();
virtual bool bends() const;
virtual double getRmax() const;
virtual double getRmin() const;
bool interpolate(const double& rad,
const double& tet_rad,
double& br,
double& bt,
double& bz);
void read(const double& scaleFactor);
void setBFieldType();
BFieldType fieldType_m;
private:
/// Apply trim coils (calculate field contributions) with smooth field transition
void applyTrimCoil (const double r, const double z, const double tet_rad, double& br, double& bz);
/// Apply trim coils (calculate field contributions)
void applyTrimCoil_m(const double r, const double z, const double tet_rad, double* br, double* bz);
protected:
void getdiffs();
double gutdf5d(double* f, double dx, const int kor, const int krl, const int lpr);
void initR(double rmin, double dr, int nrad);
void getFieldFromFile_Ring(const double& scaleFactor);
void getFieldFromFile_Carbon(const double& scaleFactor);
void getFieldFromFile_CYCIAE(const double& scaleFactor);
void getFieldFromFile_AVFEQ(const double& scaleFactor);
void getFieldFromFile_FFA(const double& scaleFactor);
void getFieldFromFile_BandRF(const double& scaleFactor);
void getFieldFromFile_Synchrocyclotron(const double& scaleFactor);
inline int idx(int irad, int ktet) {return (ktet + Bfield.ntetS * irad);}
private:
std::string fmapfn_m; /* stores the filename of the fieldmap */
std::vector rffrequ_m;
std::vector< std::vector > rffc_m;
std::vector rfvrequ_m;
std::vector< std::vector > rfvc_m;
std::vector rfphi_m;
std::vector escale_m; // a scale factor for the E-field
std::vector superpose_m; // electric fields are superposed or not
double symmetry_m;
double rinit_m;
double prinit_m;
double phiinit_m;
double zinit_m;
double pzinit_m;
bool spiral_flag_m;
double trimCoilThreshold_m; ///< B-field threshold for applying trim coil
std::string typeName_m; // name of the TYPE parameter in cyclotron
double harm_m;
double bscale_m; // a scale factor for the B-field
/// Trim coils
std::vector trimcoils_m;
double minr_m;
double maxr_m;
double minz_m;
double maxz_m;
double fmLowE_m;
double fmHighE_m;
// Not implemented.
void operator=(const Cyclotron &) = delete;
// RF field map handler
// Fieldmap *RFfield;
std::vector RFfields_m;
std::vector RFfilename_m;
std::vector RFFCoeff_fn_m;
std::vector RFVCoeff_fn_m;
// handling for store the particle out of region
std::unique_ptr lossDs_m;
// Necessary for quick and dirty phase output -DW
int waiting_for_gap = 1;
protected:
// object of Matrices including magnetic field map and its derivates
BfieldData Bfield;
// object of parameters about the map grid
BPositions BP;
};
#endif // CLASSIC_Cyclotron_HH