Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ElectroVDNuclearModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// Author: D.H. Wright
28// Date: 1 May 2012
29//
30// Description: model for electron and positron interaction with nuclei
31// using the equivalent photon spectrum. A real gamma is
32// produced from the virtual photon spectrum and is then
33// interacted hadronically by the Bertini cascade at low
34// energies. At high energies the gamma is treated as a
35// pi0 and interacted with the nucleus using the FTFP model.
36// The electro- and photo-nuclear cross sections of
37// M. Kossov are used to generate the virtual photon
38// spectrum.
39//
40
42
44#include "G4SystemOfUnits.hh"
45
49
50#include "G4CascadeInterface.hh"
51#include "G4TheoFSGenerator.hh"
54#include "G4PreCompoundModel.hh"
57#include "G4FTFModel.hh"
58
59#include "G4HadFinalState.hh"
62
65#include "G4GammaNuclearXS.hh"
66
67
69 : G4HadronicInteraction("G4ElectroVDNuclearModel"),
70 leptonKE(0.0), photonEnergy(0.0), photonQ2(0.0), secID(-1)
71{
72 SetMinEnergy(0.0);
73 SetMaxEnergy(1*PeV);
74
75 electroXS =
77 GetCrossSectionDataSet(G4ElectroNuclearCrossSection::Default_Name());
78 if ( electroXS == nullptr ) {
79 electroXS = new G4ElectroNuclearCrossSection;
80 }
81
82 gammaXS =
84 GetCrossSectionDataSet(G4PhotoNuclearCrossSection::Default_Name());
85 if ( gammaXS == nullptr ) {
86 gammaXS =
88 GetCrossSectionDataSet(G4GammaNuclearXS::Default_Name());
89 if ( gammaXS == nullptr ) {
90 gammaXS = new G4PhotoNuclearCrossSection;
91 }
92 }
93
94 // reuse existing pre-compound model
95 G4GeneratorPrecompoundInterface* precoInterface
99 G4VPreCompoundModel* pre = static_cast<G4VPreCompoundModel*>(p);
100 if(!pre) { pre = new G4PreCompoundModel(); }
101 precoInterface->SetDeExcitation(pre);
102
103 // string model
104 ftfp = new G4TheoFSGenerator();
105 ftfp->SetTransport(precoInterface);
106 theFragmentation = new G4LundStringFragmentation();
107 theStringDecay = new G4ExcitedStringDecay(theFragmentation);
108 G4FTFModel* theStringModel = new G4FTFModel();
109 theStringModel->SetFragmentationModel(theStringDecay);
110 ftfp->SetHighEnergyGenerator(theStringModel);
111
112 // Build Bertini model
113 bert = new G4CascadeInterface();
114
115 // Creator model ID
116 secID = G4PhysicsModelCatalog::GetModelID( "model_" + GetModelName() );
117}
118
120{
121 delete theFragmentation;
122 delete theStringDecay;
123}
124
125void G4ElectroVDNuclearModel::ModelDescription(std::ostream& outFile) const
126{
127 outFile << "G4ElectroVDNuclearModel handles the inelastic scattering\n"
128 << "of e- and e+ from nuclei using the equivalent photon\n"
129 << "approximation in which the incoming lepton generates a\n"
130 << "virtual photon at the electromagnetic vertex, and the\n"
131 << "virtual photon is converted to a real photon. At low\n"
132 << "energies, the photon interacts directly with the nucleus\n"
133 << "using the Bertini cascade. At high energies the photon\n"
134 << "is converted to a pi0 which interacts using the FTFP\n"
135 << "model. The electro- and gamma-nuclear cross sections of\n"
136 << "M. Kossov are used to generate the virtual photon spectrum\n";
137}
138
139
142 G4Nucleus& targetNucleus)
143{
144 // Set up default particle change (just returns initial state)
147 leptonKE = aTrack.GetKineticEnergy();
150
151 // Set up sanity checks for real photon production
152 G4DynamicParticle lepton(aTrack.GetDefinition(), aTrack.Get4Momentum() );
153
154 // Need to call GetElementCrossSection before calling GetEquivalentPhotonEnergy.
155 const G4Material* mat = aTrack.GetMaterial();
156 G4int targZ = targetNucleus.GetZ_asInt();
157 electroXS->GetElementCrossSection(&lepton, targZ, mat);
158
159 photonEnergy = electroXS->GetEquivalentPhotonEnergy();
160 // Photon energy cannot exceed lepton energy
161 if (photonEnergy < leptonKE) {
162 photonQ2 = electroXS->GetEquivalentPhotonQ2(photonEnergy);
164 // Photon
165 if (photonEnergy > photonQ2/dM) {
166 // Produce recoil lepton and transferred photon
167 G4DynamicParticle* transferredPhoton = CalculateEMVertex(aTrack, targetNucleus);
168 // Interact gamma with nucleus
169 if (transferredPhoton) CalculateHadronicVertex(transferredPhoton, targetNucleus);
170 }
171 }
172 return &theParticleChange;
173}
174
175
177G4ElectroVDNuclearModel::CalculateEMVertex(const G4HadProjectile& aTrack,
178 G4Nucleus& targetNucleus)
179{
180 G4DynamicParticle photon(G4Gamma::Gamma(), photonEnergy,
181 G4ThreeVector(0.,0.,1.) );
182
183 // Get gamma cross section at Q**2 = 0 (real gamma)
184 G4int targZ = targetNucleus.GetZ_asInt();
185 const G4Material* mat = aTrack.GetMaterial();
186 G4double sigNu =
187 gammaXS->GetElementCrossSection(&photon, targZ, mat);
188
189 // Change real gamma energy to equivalent energy and get cross section at that energy
191 photon.SetKineticEnergy(photonEnergy - photonQ2/dM);
192 G4double sigK =
193 gammaXS->GetElementCrossSection(&photon, targZ, mat);
194 G4double rndFraction = electroXS->GetVirtualFactor(photonEnergy, photonQ2);
195
196 // No gamma produced, return null ptr
197 if (sigNu*G4UniformRand() > sigK*rndFraction) return 0;
198
199 // Scatter the lepton
200 G4double mProj = aTrack.GetDefinition()->GetPDGMass();
201 G4double mProj2 = mProj*mProj;
202 G4double iniE = leptonKE + mProj; // Total energy of incident lepton
203 G4double finE = iniE - photonEnergy; // Total energy of scattered lepton
205 G4double iniP = std::sqrt(iniE*iniE-mProj2); // Incident lepton momentum
206 G4double finP = std::sqrt(finE*finE-mProj2); // Scattered lepton momentum
207 G4double cost = (iniE*finE - mProj2 - photonQ2/2.)/iniP/finP; // cos(theta) from Q**2
208 if (cost > 1.) cost= 1.;
209 if (cost < -1.) cost=-1.;
210 G4double sint = std::sqrt(1.-cost*cost);
211
212 G4ThreeVector dir = aTrack.Get4Momentum().vect().unit();
213 G4ThreeVector ortx = dir.orthogonal().unit(); // Ortho-normal to scattering plane
214 G4ThreeVector orty = dir.cross(ortx); // Third unit vector
215 G4double phi = twopi*G4UniformRand();
216 G4double sinx = sint*std::sin(phi);
217 G4double siny = sint*std::cos(phi);
218 G4ThreeVector findir = cost*dir+sinx*ortx+siny*orty;
219 theParticleChange.SetMomentumChange(findir); // change lepton direction
220
221 // Create a gamma with momentum equal to momentum transfer
222 G4ThreeVector photonMomentum = iniP*dir - finP*findir;
224 photonEnergy, photonMomentum);
225 return gamma;
226}
227
228
229void
230G4ElectroVDNuclearModel::CalculateHadronicVertex(G4DynamicParticle* incident,
231 G4Nucleus& target)
232{
233 G4HadFinalState* hfs = 0;
234 G4double gammaE = incident->GetTotalEnergy();
235
236 if (gammaE < 10*GeV) {
237 G4HadProjectile projectile(*incident);
238 hfs = bert->ApplyYourself(projectile, target);
239 } else {
240 // At high energies convert incident gamma to a pion
242 G4double piMom = std::sqrt(gammaE*gammaE - piMass*piMass);
243 G4ThreeVector piMomentum(incident->GetMomentumDirection() );
244 piMomentum *= piMom;
245 G4DynamicParticle theHadron(G4PionZero::PionZero(), piMomentum);
246 G4HadProjectile projectile(theHadron);
247 hfs = ftfp->ApplyYourself(projectile, target);
248 }
249
250 delete incident;
251
252 // Assign the creator model ID to the secondaries
253 for ( size_t i = 0; i < hfs->GetNumberOfSecondaries(); ++i ) {
254 hfs->GetSecondary( i )->SetCreatorModelID( secID );
255 }
256
257 // Copy secondaries from sub-model to model
259}
260
@ isAlive
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector orthogonal() const
Hep3Vector cross(const Hep3Vector &) const
Hep3Vector vect() const
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &theNucleus)
static G4CrossSectionDataSetRegistry * Instance()
const G4ThreeVector & GetMomentumDirection() const
G4double GetTotalEnergy() const
virtual G4double GetElementCrossSection(const G4DynamicParticle *, G4int Z, const G4Material *mat)
G4double GetVirtualFactor(G4double nu, G4double Q2)
virtual void ModelDescription(std::ostream &outFile) const
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &aTargetNucleus)
static const char * Default_Name()
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
void SetStatusChange(G4HadFinalStateStatus aS)
void AddSecondaries(const std::vector< G4HadSecondary > &addSecs)
std::size_t GetNumberOfSecondaries() const
void SetEnergyChange(G4double anEnergy)
G4HadSecondary * GetSecondary(size_t i)
void SetMomentumChange(const G4ThreeVector &aV)
const G4Material * GetMaterial() const
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
void SetCreatorModelID(G4int id)
G4HadronicInteraction * FindModel(const G4String &name)
static G4HadronicInteractionRegistry * Instance()
void SetMinEnergy(G4double anEnergy)
const G4String & GetModelName() const
void SetMaxEnergy(const G4double anEnergy)
static G4Neutron * Neutron()
Definition: G4Neutron.cc:103
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:105
static G4int GetModelID(const G4int modelIndex)
static G4PionZero * PionZero()
Definition: G4PionZero.cc:107
static G4Proton * Proton()
Definition: G4Proton.cc:92
void SetTransport(G4VIntraNuclearTransportModel *const value)
void SetHighEnergyGenerator(G4VHighEnergyGenerator *const value)
G4HadFinalState * ApplyYourself(const G4HadProjectile &thePrimary, G4Nucleus &theNucleus) override
virtual G4double GetElementCrossSection(const G4DynamicParticle *, G4int Z, const G4Material *mat=nullptr)
void SetDeExcitation(G4VPreCompoundModel *ptr)
void SetFragmentationModel(G4VStringFragmentation *aModel)