Geant4-11
G4NeutronElectronElModel.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// Geant4 Header : G4NeutronElectronElModel
28//
29// 16.5.17: V.Grichine
30//
31
33#include "G4SystemOfUnits.hh"
34#include "G4ParticleTable.hh"
36#include "G4IonTable.hh"
37#include "Randomize.hh"
38#include "G4Integrator.hh"
39#include "G4Electron.hh"
40#include "G4PhysicsTable.hh"
41#include "G4PhysicsLogVector.hh"
44
45
46using namespace std;
47using namespace CLHEP;
48
51{
53
54 // neutron magneton squared
55
56 fM = neutron_mass_c2; // neutron mass
57 fM2 = fM*fM;
59 fme2 = fme*fme;
60 fMv2 = 0.7056*GeV*GeV;
61
62 SetMinEnergy( 0.001*GeV );
63 SetMaxEnergy( 10.*TeV );
65
67 // PDG2016: sin^2 theta Weinberg
68
69 fEnergyBin = 200;
70 fMinEnergy = 1.*MeV;
71 fMaxEnergy = 10000.*GeV;
73
74 fAngleBin = 500;
75 fAngleTable = 0;
76
77 fCutEnergy = 0.; // default value
78
79 Initialise();
80}
81
83
85{
86 if( fEnergyVector )
87 {
88 delete fEnergyVector;
89 fEnergyVector = nullptr;
90 }
91 if( fAngleTable )
92 {
94 delete fAngleTable;
95 fAngleTable = nullptr;
96 }
97}
98
100
101void G4NeutronElectronElModel::ModelDescription(std::ostream& outFile) const
102{
103 outFile << "G4NeutronElectronElModel is a neutrino-electron (neutral current) elastic scattering\n"
104 << "model which uses the standard model \n"
105 << "transfer parameterization. The model is fully relativistic\n";
106}
107
109
111{
112 G4String pName = aTrack.GetDefinition()->GetParticleName();
113 G4double energy = aTrack.GetTotalEnergy();
114
115 return (pName == "neutron" && energy >= fMinEnergy && energy <= fMaxEnergy);
116}
117
119
121{
122 G4double result = 0., sum, Tkin, dt, t1, t2;
123 G4int iTkin, jTransfer;
125
127
128 for( iTkin = 0; iTkin < fEnergyBin; iTkin++)
129 {
130 Tkin = fEnergyVector->GetLowEdgeEnergy(iTkin);
131 fAm = CalculateAm(Tkin);
132 dt = 1./fAngleBin;
133
135
136 sum = 0.;
137
138 for( jTransfer = 0; jTransfer < fAngleBin; jTransfer++)
139 {
140 t1 = dt*jTransfer;
141 t2 = t1 + dt;
142
143 result = integral.Legendre96( this, &G4NeutronElectronElModel::XscIntegrand, t1, t2 );
144
145 sum += result;
146 // G4cout<<sum<<", ";
147 vectorT->PutValue(jTransfer, t1, sum);
148 }
149 // G4cout<<G4endl;
150 fAngleTable->insertAt(iTkin,vectorT);
151 }
152 return;
153}
154
156//
157// sample recoil electron energy in lab frame
158
160{
161 G4double result = 0., position;
162 G4int iTkin, iTransfer;
163
164 for( iTkin = 0; iTkin < fEnergyBin; iTkin++)
165 {
166 if( Tkin < fEnergyVector->Energy(iTkin) ) break;
167 }
168 if ( iTkin >= fEnergyBin ) iTkin = fEnergyBin-1; // Tkin is more then theMaxEnergy
169 if ( iTkin < 0 ) iTkin = 0; // against negative index, Tkin < theMinEnergy
170
171 position = (*(*fAngleTable)(iTkin))(fAngleBin-1)*G4UniformRand();
172
173 // G4cout<<"position = "<<position<<G4endl;
174
175 for( iTransfer = 0; iTransfer < fAngleBin; iTransfer++)
176 {
177 if( position <= (*(*fAngleTable)(iTkin))(iTransfer) ) break;
178 }
179 if (iTransfer >= fAngleBin-1) iTransfer = fAngleBin-1;
180
181 // G4cout<<"iTransfer = "<<iTransfer<<G4endl;
182
183 result = GetTransfer(iTkin, iTransfer, position);
184
185 // G4cout<<"t = "<<t<<G4endl;
186
187
188 return result;
189}
190
192
195{
196 G4double x1, x2, y1, y2, randTransfer, delta, mean, epsilon = 1.e-6;
197
198 if( iTransfer == 0 || iTransfer == fAngleBin-1 )
199 {
200 randTransfer = (*fAngleTable)(iTkin)->Energy(iTransfer);
201 }
202 else
203 {
204 if ( iTransfer >= G4int((*fAngleTable)(iTkin)->GetVectorLength()) )
205 {
206 iTransfer = (*fAngleTable)(iTkin)->GetVectorLength() - 1;
207 }
208 y1 = (*(*fAngleTable)(iTkin))(iTransfer-1);
209 y2 = (*(*fAngleTable)(iTkin))(iTransfer);
210
211 x1 = (*fAngleTable)(iTkin)->Energy(iTransfer-1);
212 x2 = (*fAngleTable)(iTkin)->Energy(iTransfer);
213
214 delta = y2 - y1;
215 mean = y2 + y1;
216
217 if ( x1 == x2 ) randTransfer = x2;
218 else
219 {
220 if ( delta < epsilon*mean )
221 {
222 randTransfer = x1 + ( x2 - x1 )*G4UniformRand();
223 }
224 else
225 {
226 randTransfer = x1 + ( position - y1 )*( x2 - x1 )/delta; // ( y2 - y1 );
227 }
228 }
229 }
230 return randTransfer;
231}
232
234//
235// Rosenbluth relation (ultra-relativistic!) in the neutron rest frame,
236// x = sin^2(theta/2), theta is the electron scattering angle
237// Magnetic form factor in the dipole approximation.
238
240{
241 G4double result = 1., q2, znq2, znf, znf2, znf4;
242
243 znq2 = 1. + 2.*fee*x/fM;
244
245 q2 = 4.*fee2*x/znq2;
246
247 znf = 1 + q2/fMv2;
248 znf2 = znf*znf;
249 znf4 = znf2*znf2;
250
251 result /= ( x + fAm )*znq2*znq2*znf4;
252
253 result *= ( 1 - x )/( 1 + q2/4./fM2 ) + 2.*x;
254
255 return result;
256}
257
259//
260//
261
263 const G4HadProjectile& aTrack, G4Nucleus&)
264{
266
267 const G4HadProjectile* aParticle = &aTrack;
268 G4double Tkin = aParticle->GetKineticEnergy();
269 fAm = CalculateAm( Tkin);
270 // G4double En = aParticle->GetTotalEnergy();
271
272 if( Tkin <= LowestEnergyLimit() )
273 {
276 return &theParticleChange;
277 }
278 // sample e-scattering angle and make final state in lab frame
279
280 G4double sin2ht = SampleSin2HalfTheta( Tkin); // in n-rrest frame
281
282 // G4cout<<"sin2ht = "<<sin2ht<<G4endl;
283
284 G4double eTkin = fee; // fM;
285
286 eTkin /= 1.+2.*fee*sin2ht/fM; // fme/En + 2*sin2ht;
287
288 eTkin -= fme;
289
290 // G4cout<<"eTkin = "<<eTkin<<G4endl;
291
292 if( eTkin > fCutEnergy )
293 {
294 G4double ePlab = sqrt( eTkin*(eTkin + 2.*fme) );
295
296 // G4cout<<"ePlab = "<<ePlab<<G4endl;
297
298 G4double cost = 1. - 2*sin2ht;
299
300 if( cost > 1. ) cost = 1.;
301 if( cost < -1. ) cost = -1.;
302
303 G4double sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
305
306 G4ThreeVector eP( sint*std::cos(phi), sint*std::sin(phi), cost );
307 eP *= ePlab;
308 G4LorentzVector lvt2( eP, eTkin + electron_mass_c2 ); // recoil e- in n-rest frame
309
310 G4LorentzVector lvp1 = aParticle->Get4Momentum();
311 G4LorentzVector lvt1(0.,0.,0.,electron_mass_c2);
312 G4LorentzVector lvsum = lvp1+lvt1;
313
314 G4ThreeVector bst = lvp1.boostVector();
315 lvt2.boost(bst);
316
317 // G4cout<<"lvt2 = "<<lvt2<<G4endl;
318
319 G4DynamicParticle * aSec = new G4DynamicParticle( theElectron, lvt2 );
321
322 G4LorentzVector lvp2 = lvsum-lvt2;
323
324 // G4cout<<"lvp2 = "<<lvp2<<G4endl;
325
326 G4double Tkin2 = lvp2.e()-aParticle->GetDefinition()->GetPDGMass();
329 }
330 else if( eTkin > 0.0 )
331 {
333 Tkin -= eTkin;
334
335 if( Tkin > 0. )
336 {
339 }
340 }
341 else
342 {
345 }
346 return &theParticleChange;
347}
348
349//
350//
G4double epsilon(G4double density, G4double temperature)
static constexpr double eV
Definition: G4SIunits.hh:201
static constexpr double GeV
Definition: G4SIunits.hh:203
static constexpr double MeV
Definition: G4SIunits.hh:200
static constexpr double TeV
Definition: G4SIunits.hh:204
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
Hep3Vector vect() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
void SetLocalEnergyDeposit(G4double aE)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4double GetTotalEnergy() const
G4double LowestEnergyLimit() const
void SetLowestEnergyLimit(G4double value)
void SetMinEnergy(G4double anEnergy)
void SetMaxEnergy(const G4double anEnergy)
virtual void ModelDescription(std::ostream &) const
G4double SampleSin2HalfTheta(G4double Tkin)
G4double CalculateAm(G4double momentum)
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
G4PhysicsLogVector * fEnergyVector
G4NeutronElectronElModel(const G4String &name="n-e-elastic")
G4ParticleDefinition * theElectron
virtual G4bool IsApplicable(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
G4double GetTransfer(G4int iTkin, G4int iTransfer, G4double position)
const G4String & GetParticleName() const
void PutValue(const std::size_t index, const G4double e, const G4double value)
static G4int GetModelID(const G4int modelIndex)
void clearAndDestroy()
void insertAt(std::size_t, G4PhysicsVector *)
G4double GetLowEdgeEnergy(const std::size_t index) const
Definition: DoubConv.h:17
static constexpr double twopi
Definition: SystemOfUnits.h:56
G4double energy(const ThreeVector &p, const G4double m)
const char * name(G4int ptype)
float electron_mass_c2
Definition: hepunit.py:273
float neutron_mass_c2
Definition: hepunit.py:275
#define position
Definition: xmlparse.cc:622