// // ******************************************************************** // * DISCLAIMER * // * * // * The following disclaimer summarizes all the specific disclaimers * // * of contributors to this software. The specific disclaimers,which * // * govern, are listed with their locations in: * // * http://cern.ch/geant4/license * // * * // * 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. * // * * // * This code implementation is the intellectual property of the * // * GEANT4 collaboration. * // * By copying, distributing or modifying the Program (or any work * // * based on the Program) you indicate your acceptance of this * // * statement, and all its terms. * // ******************************************************************** // // // $Id: G4VXrayTRmodel.cc,v 1.5 2001/09/18 09:02:04 gcosmo Exp $ // GEANT4 tag $Name: geant4-04-00 $ // #include "G4Timer.hh" #include "G4VXrayTRmodel.hh" #include "Randomize.hh" #include "G4Material.hh" #include "G4MaterialTable.hh" #include "globals.hh" #include "g4std/complex" #include "G4PhysicsTable.hh" #include "G4PhysicsVector.hh" #include "G4PhysicsLinearVector.hh" #include "G4PhysicsLogVector.hh" #include "G4Integrator.hh" #include "G4Gamma.hh" // Initialization of local constants G4double G4VXrayTRmodel::fTheMinEnergyTR = 1.0*keV ; G4double G4VXrayTRmodel::fTheMaxEnergyTR = 100.0*keV ; G4double G4VXrayTRmodel::fTheMaxAngle = 1.0e-3 ; G4double G4VXrayTRmodel::fTheMinAngle = 5.0e-6 ; G4int G4VXrayTRmodel::fBinTR = 50 ; G4double G4VXrayTRmodel::fMinProtonTkin = 100.0*GeV ; G4double G4VXrayTRmodel::fMaxProtonTkin = 100.0*TeV ; G4int G4VXrayTRmodel::fTotBin = 50 ; // Proton energy vector initialization G4PhysicsLogVector* G4VXrayTRmodel:: fProtonEnergyVector = new G4PhysicsLogVector(fMinProtonTkin, fMaxProtonTkin, fTotBin ) ; G4double G4VXrayTRmodel::fPlasmaCof = 4.0*pi*fine_structure_const* hbarc*hbarc*hbarc/electron_mass_c2 ; G4double G4VXrayTRmodel::fCofTR = fine_structure_const/pi ; //////////////////////////////////////////////////////////////////////////// // // Constructor, destructor G4VXrayTRmodel::G4VXrayTRmodel(G4Envelope *anEnvelope, G4double a, G4double b) : G4VFastSimulationModel("G4VXrayTRmodel",anEnvelope) // , G4ForwardXrayTR("G4VXrayTRmodel") { fPlateNumber = anEnvelope->GetNoDaughters() ; G4cout<<"the number of TR radiator plates = "<GetDaughter(0)->GetLogicalVolume()-> GetMaterial()->GetIndex() ; G4cout<<"plate material = "<GetDaughter(0)->GetLogicalVolume()-> GetMaterial()->GetName()<GetMaterial()->GetIndex() ; G4cout<<"gas material = "< GetMaterial()->GetName()<GetDaughter(0)->GetLogicalVolume()-> GetMaterial()->GetElectronDensity() ; // fSigma1 = (20.9*eV)*(20.9*eV) ; G4cout<<"plate plasma energy = "<GetMaterial()->GetElectronDensity() ; G4cout<<"gas plasma energy = "<GetDefinition()->GetPDGMass() ; // G4double kinEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ; // G4double gamma = 1.0 + kinEnergy/mass ; // Lorentz factor // G4cout << "gamma = " << gamma << G4endl ; // if (gamma >= 100.0) return true ; // else return false ; return true ; } ////////////////////////////////////////////////////////////////////////// // // User method to code the parameterisation properly // said. This is simple example of creation of one X-ray photon with the // energy in the range of around 5 keV produced by relativistic charged // particle // void G4VXrayTRmodel::ExampleDoIt( const G4FastTrack& fastTrack , G4FastStep& fastStep ) { // The primary track continues along its direction. // One secondary (a photon) is added: // G4cout << " TR `model' applied \n " << endl; // Primary: idem as in "DefaultModel": // G4double distance = fastTrack.GetEnvelopeSolid()-> DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(), fastTrack.GetPrimaryTrackLocalDirection()) ; G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() + distance*fastTrack.GetPrimaryTrackLocalDirection() ; // Set final position: fastStep.SetPrimaryTrackFinalPosition(position); //--------------------------- // Secondary: Adds one "secondary": // // First, user has to say how many secondaries will be created: fastStep.SetNumberOfSecondaryTracks(1); // Build the secondary direction: G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection()); // direction.setZ(direction.z()*0.5); // direction.setY(direction.y()+direction.z()*0.1); direction = direction.unit(); // necessary !? // Dynamics (Note that many constructors exists for G4DynamicParticle G4double gammaEnergy = 3.0*keV + G4UniformRand()*2*keV ; G4DynamicParticle dynamique(G4Gamma::GammaDefinition(), direction, // fastTrack.GetPrimaryTrack()->GetKineticEnergy()/2. gammaEnergy ); // -- position: G4double Dist = fastTrack.GetEnvelopeSolid()-> DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),direction) ; G4ThreeVector posi = fastTrack.GetPrimaryTrackLocalPosition() + Dist*direction ; // Creation of the secondary Track: fastStep.CreateSecondaryTrack( dynamique, posi, fastTrack.GetPrimaryTrack()->GetGlobalTime()); } ////////////////////////////////////////////////////////////////////// // // Calculates formation zone for plates. Omega is energy !!! G4double G4VXrayTRmodel::GetPlateFormationZone( G4double omega , G4double gamma , G4double varAngle ) { G4double cof, lambda ; lambda = 1.0/gamma/gamma + varAngle + fSigma1/omega/omega ; cof = 2.0*hbarc/omega/lambda ; return cof ; } ////////////////////////////////////////////////////////////////////// // // Calculates complex formation zone for plates. Omega is energy !!! G4complex G4VXrayTRmodel::GetPlateComplexFZ( G4double omega , G4double gamma , G4double varAngle ) { G4double cof, length,delta, real, image ; length = 0.5*GetPlateFormationZone(omega,gamma,varAngle) ; delta = length*GetPlateLinearPhotoAbs(omega) ; cof = 1.0/(1.0 + delta*delta) ; real = length*cof ; image = real*delta ; G4complex zone(real,image); return zone ; } //////////////////////////////////////////////////////////////////////// // // Computes matrix of Sandia photo absorption cross section coefficients for // plate material void G4VXrayTRmodel::ComputePlatePhotoAbsCof() { G4int i, j, numberOfElements ; static const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable(); G4SandiaTable thisMaterialSandiaTable(fMatIndex1) ; numberOfElements = (*theMaterialTable)[fMatIndex1]->GetNumberOfElements() ; G4int* thisMaterialZ = new G4int[numberOfElements] ; for(i=0;i GetElement(i)->GetZ() ; } fPlateIntervalNumber = thisMaterialSandiaTable.SandiaIntervals (thisMaterialZ,numberOfElements) ; fPlateIntervalNumber = thisMaterialSandiaTable.SandiaMixing ( thisMaterialZ , (*theMaterialTable)[fMatIndex1]->GetFractionVector() , numberOfElements,fPlateIntervalNumber) ; fPlatePhotoAbsCof = new G4double*[fPlateIntervalNumber] ; for(i=0;iGetDensity() ; } } delete[] thisMaterialZ ; return ; } ////////////////////////////////////////////////////////////////////// // // Returns the value of linear photo absorption coefficient (in reciprocal // length) for plate for given energy of X-ray photon omega G4double G4VXrayTRmodel::GetPlateLinearPhotoAbs(G4double omega) { G4int i ; G4double omega2, omega3, omega4 ; omega2 = omega*omega ; omega3 = omega2*omega ; omega4 = omega2*omega2 ; for(i=0;iGetNumberOfElements() ; G4int* thisMaterialZ = new G4int[numberOfElements] ; for(i=0;i GetElement(i)->GetZ() ; } fGasIntervalNumber = thisMaterialSandiaTable.SandiaIntervals (thisMaterialZ,numberOfElements) ; fGasIntervalNumber = thisMaterialSandiaTable.SandiaMixing ( thisMaterialZ , (*theMaterialTable)[fMatIndex2]->GetFractionVector() , numberOfElements,fGasIntervalNumber) ; fGasPhotoAbsCof = new G4double*[fGasIntervalNumber] ; for(i=0;iGetDensity() ; } } delete[] thisMaterialZ ; return ; } ////////////////////////////////////////////////////////////////////// // // Returns the value of linear photo absorption coefficient (in reciprocal // length) for gas G4double G4VXrayTRmodel::GetGasLinearPhotoAbs(G4double omega) { G4int i ; G4double omega2, omega3, omega4 ; omega2 = omega*omega ; omega3 = omega2*omega ; omega4 = omega2*omega2 ; for(i=0;i matter2, or 2->1) // varAngle =2* (1 - cos(theta)) or approximately = theta*theta // G4double G4VXrayTRmodel::OneBoundaryXTRNdensity( G4double energy,G4double gamma, G4double varAngle ) const { G4double formationLength1, formationLength2 ; formationLength1 = 1.0/ (1.0/(gamma*gamma) + fSigma1/(energy*energy) + varAngle) ; formationLength2 = 1.0/ (1.0/(gamma*gamma) + fSigma2/(energy*energy) + varAngle) ; return (varAngle/energy)*(formationLength1 - formationLength2) *(formationLength1 - formationLength2) ; } ////////////////////////////////////////////////////////////////////////////// // // For photon energy distribution tables. Integrate first over angle // G4double G4VXrayTRmodel::XTRNSpectralAngleDensity(G4double varAngle) { return OneBoundaryXTRNdensity(fEnergy,fGamma,varAngle)* GetStackFactor(fEnergy,fGamma,varAngle) ; } ///////////////////////////////////////////////////////////////////////// // // For second integration over energy G4double G4VXrayTRmodel::XTRNSpectralDensity(G4double energy) { fEnergy = energy ; G4Integrator integral ; return integral.Legendre96(this,&G4VXrayTRmodel::XTRNSpectralAngleDensity, 0.0,0.2*fMaxThetaTR) + integral.Legendre10(this,&G4VXrayTRmodel::XTRNSpectralAngleDensity, 0.2*fMaxThetaTR,fMaxThetaTR) ; } ////////////////////////////////////////////////////////////////////////// // // for photon angle distribution tables // G4double G4VXrayTRmodel::XTRNAngleSpectralDensity(G4double energy) { return OneBoundaryXTRNdensity(energy,fGamma,fVarAngle)* GetStackFactor(energy,fGamma,fVarAngle) ; } /////////////////////////////////////////////////////////////////////////// // // G4double G4VXrayTRmodel::XTRNAngleDensity(G4double varAngle) { fVarAngle = varAngle ; G4Integrator integral ; return integral.Legendre96(this,&G4VXrayTRmodel::XTRNAngleSpectralDensity, fMinEnergyTR,fMaxEnergyTR) ; } ////////////////////////////////////////////////////////////////////////////// // // Check number of photons for a range of Lorentz factors from both energy // and angular tables void G4VXrayTRmodel::GetNumberOfPhotons() { G4int iTkin ; G4double gamma, numberE ; G4std::ofstream outEn("numberE.dat", G4std::ios::out ) ; outEn.setf( G4std::ios::scientific, G4std::ios::floatfield ); G4std::ofstream outAng("numberAng.dat", G4std::ios::out ) ; outAng.setf( G4std::ios::scientific, G4std::ios::floatfield ); for(iTkin=0;iTkin GetLowEdgeEnergy(iTkin)/proton_mass_c2) ; numberE = (*(*fEnergyDistrTable)(iTkin))(0) ; // numberA = (*(*fAngleDistrTable)(iTkin))(0) ; G4cout<= ( (*(*fEnergyDistrTable)(iPlace))(iTransfer)*W1 + (*(*fEnergyDistrTable)(iPlace+1))(iTransfer)*W2) ) break ; } transfer = GetXTRenergy(iPlace,position,iTransfer); } // G4cout<<"XTR transfer = "<GetLowEdgeEnergy(iTransfer) ; } else { y1 = (*(*fEnergyDistrTable)(iPlace))(iTransfer-1) ; y2 = (*(*fEnergyDistrTable)(iPlace))(iTransfer) ; x1 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ; x2 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ; if ( x1 == x2 ) result = x2 ; else { if ( y1 == y2 ) result = x1 + (x2 - x1)*G4UniformRand() ; else { result = x1 + (position - y1)*(x2 - x1)/(y2 - y1) ; } } } return result ; } // // ///////////////////////////////////////////////////////////////////////