Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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:81
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:101
G4int GetZ_asInt() const
Definition G4Nucleus.hh:105
static G4int GetModelID(const G4int modelIndex)
static G4PionZero * PionZero()
static G4Proton * Proton()
Definition G4Proton.cc:90
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)