// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // $Id: G4GoudsmitSaundersonMscModel.cc,v 1.20 2009/12/16 17:50:11 gunter Exp $ // GEANT4 tag $Name: geant4-09-03 $ // // ------------------------------------------------------------------- // // GEANT4 Class file // // File name: G4GoudsmitSaundersonMscModel // // Author: Omrane Kadri // // Creation date: 20.02.2009 // // Modifications: // 04.03.2009 V.Ivanchenko cleanup and format according to Geant4 EM style // // 15.04.2009 O.Kadri: cleanup: discard no scattering and single scattering theta // sampling from SampleCosineTheta() which means the splitting // step into two sub-steps occur only for msc regime // // 12.06.2009 O.Kadri: linear log-log extrapolation of lambda0 & lambda1 between 1 GeV - 100 TeV // adding a theta min limit due to screening effect of the atomic nucleus // 26.08.2009 O.Kadri: Cubic Spline interpolation was replaced with polynomial method // within CalculateIntegrals method // 05.10.2009 O.Kadri: tuning small angle theta distributions // assuming the case of lambdan<1 as single scattering regime // tuning theta sampling for theta below the screening angle // // //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //REFERENCES: //Ref.1:E. Benedito et al.,"Mixed simulation ... cross-sections", NIMB 174 (2001) pp 91-110; //Ref.2:I. Kawrakow et al.,"On the condensed ... transport",NIMB 142 (1998) pp 253-280; //Ref.3:I. Kawrakow et al.,"On the representation ... calculations",NIMB 134 (1998) pp 325-336; //Ref.4:Bielajew et al.,".....", NIMB 173 (2001) 332-343; //Ref.5:F. Salvat et al.,"ELSEPA--Dirac partial ...molecules", Comp.Phys.Comm.165 (2005) pp 157-190; //Ref.6:G4UrbanMscModel G4_v9.1Ref09; //Ref.7:G4eCoulombScatteringModel G4_v9.1Ref09. //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #include "G4GoudsmitSaundersonMscModel.hh" #include "G4GoudsmitSaundersonTable.hh" #include "G4ParticleChangeForMSC.hh" #include "G4MaterialCutsCouple.hh" #include "G4DynamicParticle.hh" #include "G4Electron.hh" #include "G4Positron.hh" #include "G4LossTableManager.hh" #include "G4Track.hh" #include "G4PhysicsTable.hh" #include "Randomize.hh" #include "G4Poisson.hh" using namespace std; G4double G4GoudsmitSaundersonMscModel::ener[] = {-1.}; G4double G4GoudsmitSaundersonMscModel::TCSE[103][106] ; G4double G4GoudsmitSaundersonMscModel::FTCSE[103][106] ; G4double G4GoudsmitSaundersonMscModel::TCSP[103][106] ; G4double G4GoudsmitSaundersonMscModel::FTCSP[103][106] ; //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam) : G4VMscModel(nam),lowKEnergy(0.1*keV),highKEnergy(100.*TeV),isInitialized(false) { fr=0.02,rangeinit=0.,masslimite=0.6*MeV, particle=0;tausmall=1.e-16;taulim=1.e-6;tlimit=1.e10*mm; tlimitmin=10.e-6*mm;geombig=1.e50*mm;geommin=1.e-3*mm,tgeom=geombig; tlimitminfix=1.e-6*mm;stepmin=tlimitminfix;lambdalimit=1.*mm;smallstep=1.e10; theManager=G4LossTableManager::Instance(); inside=false;insideskin=false; samplez=false; GSTable = new G4GoudsmitSaundersonTable(); if(ener[0] < 0.0){ G4cout << "### G4GoudsmitSaundersonMscModel loading ELSEPA data" << G4endl; LoadELSEPAXSections(); } } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4GoudsmitSaundersonMscModel::~G4GoudsmitSaundersonMscModel() { delete GSTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void G4GoudsmitSaundersonMscModel::Initialise(const G4ParticleDefinition* p, const G4DataVector&) { skindepth=skin*stepmin; SetParticle(p); if(isInitialized) return; fParticleChange = GetParticleChangeForMSC(); InitialiseSafetyHelper(); isInitialized=true; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4double G4GoudsmitSaundersonMscModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition* p, G4double kineticEnergy,G4double Z, G4double, G4double, G4double) { //Build cross section table : Taken from Ref.7 G4double cs=0.0; G4double kinEnergy = kineticEnergy; if(kinEnergyhighKEnergy)kinEnergy=highKEnergy; G4double value0,value1; CalculateIntegrals(p,Z,kinEnergy,value0,value1); if(value1 > 0.0) cs = 1./value1; return cs; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void G4GoudsmitSaundersonMscModel::SampleScattering(const G4DynamicParticle* dynParticle, G4double safety) { G4double kineticEnergy = dynParticle->GetKineticEnergy(); if((kineticEnergy <= 0.0) || (tPathLength <= tlimitminfix)) return ; G4double cosTheta1,sinTheta1,cosTheta2,sinTheta2; G4double phi1,phi2,cosPhi1=1.0,sinPhi1=0.0,cosPhi2=1.0,sinPhi2=0.0; G4double q1,Gamma,Eta,delta,nu,nu0,nu1,nu2; /////////////////////////////////////////// // Effective energy and path-length from Eq. 4.7.15+16 of Ref.4 G4double eloss = theManager->GetEnergy(particle,tPathLength,currentCouple); if(eloss>0.5*kineticEnergy)eloss=kineticEnergy-eloss;//exchange possibility between target atomic e- and incident particle G4double ee = kineticEnergy - 0.5*eloss; G4double ttau = ee/electron_mass_c2; G4double ttau2 = ttau*ttau; G4double epsilonpp= eloss/ee; G4double cst1=epsilonpp*epsilonpp*(6+10*ttau+5*ttau2)/(24*ttau2+48*ttau+72); kineticEnergy *= (1 - cst1); /////////////////////////////////////////// // additivity rule for mixture and compound xsection calculation const G4Material* mat = currentCouple->GetMaterial(); G4int nelm = mat->GetNumberOfElements(); const G4ElementVector* theElementVector = mat->GetElementVector(); const G4double* theFraction = mat->GetFractionVector(); G4double atomPerVolume = mat->GetTotNbOfAtomsPerVolume(); G4double llambda0=0.,llambda1=0.; for(G4int i=0;iGetZ(),kineticEnergy,l0,l1); llambda0 += (theFraction[i]/l0); llambda1 += (theFraction[i]/l1); } if(llambda0>DBL_MIN) llambda0 =1./llambda0; if(llambda1>DBL_MIN) llambda1 =1./llambda1; G4double g1=0.0; if(llambda1>DBL_MIN) g1 = llambda0/llambda1; G4double x1,x0; x0=g1/2.; do { x1 = x0-(x0*((1.+x0)*log(1.+1./x0)-1.0)-g1/2.)/( (1.+2.*x0)*log(1.+1./x0)-2.0);// x1=x0-f(x0)/f'(x0) delta = std::abs( x1 - x0 ); x0 = x1; // new approximation becomes the old approximation for the next iteration } while (delta > 1e-10); G4double scrA = x1; G4double us=0.0,vs=0.0,ws=1.0,x_coord=0.0,y_coord=0.0,z_coord=1.0; G4double lambdan=0.; G4bool mscatt=false,noscatt=false; if(llambda0>0.)lambdan=atomPerVolume*tPathLength/llambda0; if((lambdan<=1.0e-12))return; G4double epsilon1=G4UniformRand(); G4double expn = exp(-lambdan); if((epsilon11.)&&(i<20));//i<20 to avoid time consuming during the run if(i==19)ws=cos(sqrt(scrA)); } G4double phi0=twopi*G4UniformRand(); us=sqrt(1.-ws*ws)*cos(phi0); vs=sqrt(1.-ws*ws)*sin(phi0); G4double rr=G4UniformRand(); x_coord=(rr*us); y_coord=(rr*vs); z_coord=((1.-rr)+rr*ws); } else { mscatt=true; // Ref.2 subsection 4.4 "The best solution found" // Sample first substep scattering angle SampleCosineTheta(0.5*lambdan,scrA,cosTheta1,sinTheta1); phi1 = twopi*G4UniformRand(); cosPhi1 = cos(phi1); sinPhi1 = sin(phi1); // Sample second substep scattering angle SampleCosineTheta(0.5*lambdan,scrA,cosTheta2,sinTheta2); phi2 = twopi*G4UniformRand(); cosPhi2 = cos(phi2); sinPhi2 = sin(phi2); // Scattering direction us = sinTheta2*(cosTheta1*cosPhi1*cosPhi2 - sinPhi1*sinPhi2) + cosTheta2*sinTheta1*cosPhi1; vs = sinTheta2*(cosTheta1*sinPhi1*cosPhi2 + cosPhi1*sinPhi2) + cosTheta2*sinTheta1*sinPhi1; ws = cosTheta1*cosTheta2 - sinTheta1*sinTheta2*cosPhi2; } G4ThreeVector oldDirection = dynParticle->GetMomentumDirection(); G4ThreeVector newDirection(us,vs,ws); newDirection.rotateUz(oldDirection); fParticleChange->ProposeMomentumDirection(newDirection); if((safety > tlimitminfix)&&(latDisplasment)) { if(mscatt) { if(scrA 0.0) aRead = log(aRead); else aRead = 0.0; ener[i]=aRead; } for(G4int j=0;j<103;j++){ for(G4int i=0;i<106;i++){ fscanf(infile,"%f\t",&aRead); if(aRead > 0.0) aRead = log(aRead); else aRead = 0.0; TCSE[j][i]=aRead; } } for(G4int j=0;j<103;j++){ for(G4int i=0;i<106;i++){ fscanf(infile,"%f\t",&aRead); if(aRead > 0.0) aRead = log(aRead); else aRead = 0.0; FTCSE[j][i]=aRead; } } for(G4int j=0;j<103;j++){ for(G4int i=0;i<106;i++){ fscanf(infile,"%f\t",&aRead); if(aRead > 0.0) aRead = log(aRead); else aRead = 0.0; TCSP[j][i]=aRead; } } for(G4int j=0;j<103;j++){ for(G4int i=0;i<106;i++){ fscanf(infile,"%f\t",&aRead); if(aRead > 0.0) aRead = log(aRead); else aRead = 0.0; FTCSP[j][i]=aRead; } } fclose(infile); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......