/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSBunchInterface.cc

00001 #include "BDSBunchInterface.hh"
00002 
00003 #include "BDSDebug.hh" 
00004 
00005 #include "CLHEP/Matrix/Vector.h" 
00006 #include "CLHEP/Matrix/SymMatrix.h"
00007 #include "CLHEP/RandomObjects/RandMultiGauss.h"
00008 
00010 namespace {
00012   bool isPositiveDefinite(CLHEP::HepSymMatrix& S)
00013   {
00014     CLHEP::HepSymMatrix temp (S); // Since diagonalize does not take a const s
00015                                   // we have to copy S.
00016     CLHEP::HepMatrix U = diagonalize ( &temp ); // S = U Sdiag U.T()
00017     CLHEP::HepSymMatrix D = S.similarityT(U);   // D = U.T() S U = Sdiag
00018     for (int i = 1; i <= S.num_row(); i++) {
00019       double s2 = D(i,i);
00020       if ( s2 <= 0 ) {
00021         return false;
00022       }
00023     }
00024     return true;
00025   }
00026 }
00027 
00028 BDSBunchInterface::BDSBunchInterface() : 
00029   X0(0.0), Y0(0.0), Z0(0.0), T0(0.0), 
00030   Xp0(0.0), Yp0(0.0), Zp0(0.0), sigmaT(0.0), sigmaE(0.0)
00031 {}
00032 
00033 BDSBunchInterface::BDSBunchInterface(G4double sigmaTIn, G4double sigmaEIn) :
00034   X0(0.0), Y0(0.0), Z0(0.0), T0(0.0), Xp0(0.0), Yp0(0.0), Zp0(0.0), sigmaT(sigmaTIn), sigmaE(sigmaEIn) {
00035 
00036 }
00037 
00038 BDSBunchInterface::BDSBunchInterface(G4double X0In, G4double Y0In, G4double Z0In, G4double T0In,
00039                                      G4double Xp0In, G4double Yp0In, G4double Zp0In, 
00040                                      G4double sigmaTIn, G4double sigmaEIn) : 
00041   X0(X0In), Y0(Y0In), Z0(Z0In), T0(T0In), 
00042   Xp0(Xp0In), Yp0(Yp0In), Zp0(Zp0In), sigmaT(sigmaTIn), sigmaE(sigmaEIn)
00043 {}
00044 
00045 BDSBunchInterface::~BDSBunchInterface() {
00046 }
00047 
00048 void BDSBunchInterface::SetOptions(struct Options& opt) {
00049   X0 = opt.X0;
00050   Y0 = opt.Y0;
00051   Z0 = opt.Z0;
00052   T0 = opt.T0;
00053   Xp0 = opt.Xp0;
00054   Yp0 = opt.Yp0;
00055   sigmaE = opt.sigmaE;
00056   sigmaT = opt.sigmaT;
00057 
00058   Zp0 = CalculateZp(Xp0,Yp0,opt.Zp0);
00059 }
00060 
00061 void BDSBunchInterface::GetNextParticle(G4double& x0, G4double& y0, G4double& z0, 
00062                                         G4double& xp, G4double& yp, G4double& zp,
00063                                         G4double& t , G4double&  E, G4double& weight) {
00064   x0 = (X0 + 0.0) * CLHEP::m;
00065   y0 = (Y0 + 0.0) * CLHEP::m;
00066   z0 = (Z0 + 0.0) * CLHEP::m;
00067   xp = (Xp0 + 0.0)* CLHEP::rad;
00068   yp = (Yp0 + 0.0)* CLHEP::rad;
00069   zp = CalculateZp(xp,yp,Zp0);
00070   t  = 0.0; 
00071   E = BDSGlobalConstants::Instance()->GetParticleKineticEnergy();
00072   weight = 1.0;
00073   return;
00074 }
00075 
00076 CLHEP::RandMultiGauss* BDSBunchInterface::CreateMultiGauss(CLHEP::HepRandomEngine & anEngine, const CLHEP::HepVector & mu, CLHEP::HepSymMatrix & sigma) {
00079   
00080   if (!isPositiveDefinite(sigma)) {
00081     G4cout << __METHOD_NAME__ << "WARNING bunch generator sigma matrix is not positive definite" << G4endl;
00082     G4cout << sigma << G4endl;
00083     G4cout << __METHOD_NAME__ << "adding a small error to zero diagonal elements" << G4endl;
00084 
00085     double small_error = 1e-20;
00086     
00087     for (int i=0; i<6; i++) {
00088       if (sigma[i][i]==0) {
00089         sigma[i][i] += small_error;
00090       }
00091     }
00092     
00093     if (!isPositiveDefinite(sigma)) {
00094       G4cout << __METHOD_NAME__ << "WARNING bunch generator sigma matrix is still not positive definite" << G4endl;
00095       G4cout << sigma << G4endl;
00096       G4cout << __METHOD_NAME__ << "adding a small error to all elements" << G4endl;
00097       for (int i=0; i<6; i++) {
00098         for (int j=0; j<6; j++) {
00099           if (sigma[i][j]==0) {
00100             sigma[i][j] += small_error;
00101           }
00102         }
00103       }
00104       if (!isPositiveDefinite(sigma)) {
00105         G4cout << __METHOD_NAME__ << "ERROR bunch generator sigma matrix is still not positive definite, giving up" << G4endl;
00106         G4cout << sigma << G4endl;
00107         exit(1);
00108       }
00109     }
00110   }
00111  
00112   return new CLHEP::RandMultiGauss(anEngine,mu,sigma); 
00113 }
00114 
00115 G4double BDSBunchInterface::CalculateZp(G4double xp, G4double yp, G4double Zp0)const
00116 {
00117   double zp;
00118   if (xp*xp+yp*yp > 1) {
00119     G4cout << __METHOD_NAME__ << "ERROR xp, yp too large, xp: " << xp << " yp: " << yp << G4endl;
00120     exit(1);
00121   }
00122   if (Zp0<0)
00123     zp = -sqrt(1.-xp*xp -yp*yp);
00124   else
00125     zp = sqrt(1.-xp*xp -yp*yp);
00126 
00127   return zp;
00128 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7