class Resonator : public Element
{
  protected: 
    double RperQ, Q, FreqRes ;
    double R, OmegaRes, OmegaResP ; 
    complex Lambda ; 
    double W0, Damp ; 
    double Beta, Alpha, Gamma ;
    double NuBeta0 ;
    complex U ;
    double U11, U12, U21, U22 ;
    double V11, V12, V21, V22 ;

    complex V ;
    complex Vb ; // Voltage felt by Bunch 
    double V0, Vr ;
    double TimeResonator ;
    double Tres ; 
  public:
    virtual void PassBunch( Bunch* bunch ) = 0;
    void InputData( ResoInput ResoIn ) ;
    void SetData() ;
    inline void set_V( complex VT ){ V = VT  ; } ; 
    inline void set_RperQ( double RperQT ){ RperQ = RperQT ; };
    inline void set_Q( double QT ){ Q = QT ; };
    inline void set_FreqRes( double FreqResT ){ FreqRes = FreqResT ; };

    inline double get_RperQ(){ return RperQ ; } ; 
    inline double get_R(){ return R ; } ; 
    inline double get_Q(){ return Q ; } ; 
    inline double get_FreqRes(){ return FreqRes ; } ;

    inline complex get_V(){ return V ; } ; 
    inline complex get_Vb(){ return Vb ; } ; 
    inline double get_Vr(){ return Vr ; } ; 
    inline double get_V0(){ return V0 ; } ;

    inline double get_OmegaRes(){ return OmegaRes ; } ; 
    inline double get_OmegaResP(){ return OmegaResP ; } ; 
    inline void MakeU( double Beta, double Alpha ) ; 
    inline void MakeV( double Beta, double Alpha ) ; 
    void atox( double *x, double *xp, double a, double ap ){ 
       *x  = U11 * a + U12 * ap ;
       *xp = U21 * a + U22 * ap ;
    } 
    void xtoa( double *a, double *ap, double x, double xp )
    { 
       *a  = V11 * x + V12 * xp ;
       *ap = V21 * x + V22 * xp ;
    }    
    void MakeU( double Beta, double Alpha, double NuBeta0 )
    { 
       U11 = sqrt(Beta) ;
       U12 = 0.0 ;
       U21 = -Alpha/sqrt(Beta) ;
       U22 = 1.0/NuBeta0/sqrt(Beta) ; 
    } 
    void MakeV( double Beta, double Alpha, double NuBeta0 )
    { 
       V11 = 1.0/sqrt(Beta) ;
       V12 = 0.0 ;
       V21 = NuBeta0*Alpha/sqrt(Beta) ;
       V22 = NuBeta0*sqrt(Beta) ;
    } 
} ;

class TResonator : public Resonator
{
  public:
    void InputData( ResoInput ResoIn ) ;
    void PassBunch( Bunch* bunch ) ; 
    void SetData() ; 
} ;

class LResonator : public Resonator
{
  public:
    void InputData( ResoInput ResoIn ) ;
    void PassBunch( Bunch* bunch ) ;
    void SetData() ; 
} ;

class Acceleration : public LResonator
{
  private:
    double Vg0 ;
    double FreqAcc ;
    double Phase ;

    complex Va ;
    complex Vg ;
    double OmegaAcc, TAcc ;
    int Harmonics ;
    double  Je ; 
    int    TDamping ;
  public:
    void InputData( ResoInput ResoIn, AccInput AccIn ) ;
    void SetData() ; 
    inline void set_FreqAcc( double FreqAccT ){ FreqAcc = FreqAccT ; };
    inline void set_Vg0( double Vg0T ){ Vg0 = Vg0T  ; } ; 
    inline void set_Phase( double PhaseT ){ Phase = PhaseT  ; } ; 

    inline double get_FreqAcc(){ return FreqAcc ; } ;
    inline double get_Phase(){ return Phase ; } ;

    inline complex get_Vg(){ return Vg ; } ; 
    inline double get_Vg0(){ return Vg0 ; } ;

    inline complex cal_Vg( double Angle, double Tau ) ;

    void PassBunch( Bunch* bunch ) ;
} ;

