// // 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