Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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"
43
44
45using namespace std;
46using namespace CLHEP;
47
49 : G4HadronElastic(name)
50{
51 // neutron magneton squared
52
53 fM = neutron_mass_c2; // neutron mass
54 fM2 = fM*fM;
55 fme = electron_mass_c2;
56 fme2 = fme*fme;
57 fMv2 = 0.7056*GeV*GeV;
58
59 SetMinEnergy( 0.001*GeV );
60 SetMaxEnergy( 10.*TeV );
61 SetLowestEnergyLimit(1.e-6*eV);
62
63 theElectron = G4Electron::Electron();
64 // PDG2016: sin^2 theta Weinberg
65
66 fEnergyBin = 200;
67 fMinEnergy = 1.*MeV;
68 fMaxEnergy = 10000.*GeV;
69 fEnergyVector = new G4PhysicsLogVector(fMinEnergy, fMaxEnergy, fEnergyBin);
70
71 fAngleBin = 500;
72 fAngleTable = 0;
73
74 fCutEnergy = 0.; // default value
75
76 Initialise();
77}
78
79////////////////////////////////////////////////
80
82{
83 if( fEnergyVector )
84 {
85 delete fEnergyVector;
86 fEnergyVector = 0;
87 }
88 if( fAngleTable )
89 {
90 fAngleTable->clearAndDestroy();
91 delete fAngleTable;
92 fAngleTable = nullptr;
93 }
94}
95
96/////////////////////////////////////////
97
98void G4NeutronElectronElModel::ModelDescription(std::ostream& outFile) const
99{
100
101 outFile << "G4NeutronElectronElModel is a neutrino-electron (neutral current) elastic scattering\n"
102 << "model which uses the standard model \n"
103 << "transfer parameterization. The model is fully relativistic\n";
104
105}
106
107/////////////////////////////////////////////////////////
108
110 G4Nucleus & targetNucleus)
111{
112 G4bool result = false;
113 G4String pName = aTrack.GetDefinition()->GetParticleName();
114 // G4double minEnergy = 0.;
115 G4double energy = aTrack.GetTotalEnergy();
116
117 if( fCutEnergy > 0. ) // min detected recoil electron energy
118 {
119 // minEnergy = 0.5*(fCutEnergy+sqrt(fCutEnergy*(fCutEnergy+2.*electron_mass_c2)));
120 }
121 if( pName == "neutron" &&
122 energy >= fMinEnergy && energy <= fMaxEnergy )
123 {
124 result = true;
125 }
126 G4int Z = targetNucleus.GetZ_asInt();
127 Z *= 1;
128
129 return result;
130}
131
132////////////////////////////////////////////////////
133
135{
136 G4double result = 0., sum, Tkin, dt, t1, t2;
137 G4int iTkin, jTransfer;
139
140 fAngleTable = new G4PhysicsTable(fEnergyBin);
141
142 for( iTkin = 0; iTkin < fEnergyBin; iTkin++)
143 {
144 Tkin = fEnergyVector->GetLowEdgeEnergy(iTkin);
145 fAm = CalculateAm(Tkin);
146 dt = 1./fAngleBin;
147
148 G4PhysicsFreeVector* vectorT = new G4PhysicsFreeVector(fAngleBin);
149
150 sum = 0.;
151
152 for( jTransfer = 0; jTransfer < fAngleBin; jTransfer++)
153 {
154 t1 = dt*jTransfer;
155 t2 = t1 + dt;
156
157 result = integral.Legendre96( this, &G4NeutronElectronElModel::XscIntegrand, t1, t2 );
158
159 sum += result;
160 // G4cout<<sum<<", ";
161 vectorT->PutValue(jTransfer, t1, sum);
162 }
163 // G4cout<<G4endl;
164 fAngleTable->insertAt(iTkin,vectorT);
165 }
166 return;
167}
168
169//////////////////////////////////////////////////////
170//
171// sample recoil electron energy in lab frame
172
174{
175 G4double result = 0., position;
176 G4int iTkin, iTransfer;
177
178 for( iTkin = 0; iTkin < fEnergyBin; iTkin++)
179 {
180 if( Tkin < fEnergyVector->GetLowEdgeEnergy(iTkin) ) break;
181 }
182 if ( iTkin >= fEnergyBin ) iTkin = fEnergyBin-1; // Tkin is more then theMaxEnergy
183 if ( iTkin < 0 ) iTkin = 0; // against negative index, Tkin < theMinEnergy
184
185 position = (*(*fAngleTable)(iTkin))(fAngleBin-1)*G4UniformRand();
186
187 // G4cout<<"position = "<<position<<G4endl;
188
189 for( iTransfer = 0; iTransfer < fAngleBin; iTransfer++)
190 {
191 if( position <= (*(*fAngleTable)(iTkin))(iTransfer) ) break;
192 }
193 if (iTransfer >= fAngleBin-1) iTransfer = fAngleBin-1;
194
195 // G4cout<<"iTransfer = "<<iTransfer<<G4endl;
196
197 result = GetTransfer(iTkin, iTransfer, position);
198
199 // G4cout<<"t = "<<t<<G4endl;
200
201
202 return result;
203}
204
205/////////////////////////////////////////////////
206
209{
210 G4double x1, x2, y1, y2, randTransfer, delta, mean, epsilon = 1.e-6;
211
212 if( iTransfer == 0 || iTransfer == fAngleBin-1 )
213 {
214 randTransfer = (*fAngleTable)(iTkin)->GetLowEdgeEnergy(iTransfer);
215 // iTransfer++;
216 }
217 else
218 {
219 if ( iTransfer >= G4int((*fAngleTable)(iTkin)->GetVectorLength()) )
220 {
221 iTransfer = (*fAngleTable)(iTkin)->GetVectorLength() - 1;
222 }
223 y1 = (*(*fAngleTable)(iTkin))(iTransfer-1);
224 y2 = (*(*fAngleTable)(iTkin))(iTransfer);
225
226 x1 = (*fAngleTable)(iTkin)->GetLowEdgeEnergy(iTransfer-1);
227 x2 = (*fAngleTable)(iTkin)->GetLowEdgeEnergy(iTransfer);
228
229 delta = y2 - y1;
230 mean = y2 + y1;
231
232 if ( x1 == x2 ) randTransfer = x2;
233 else
234 {
235 // if ( y1 == y2 )
236
237 if ( delta < epsilon*mean )
238 {
239 randTransfer = x1 + ( x2 - x1 )*G4UniformRand();
240 }
241 else
242 {
243 randTransfer = x1 + ( position - y1 )*( x2 - x1 )/delta; // ( y2 - y1 );
244 }
245 }
246 }
247 return randTransfer;
248}
249
250//////////////////////////////////////////////////////////////
251//
252// Rosenbluth relation (ultra-relativistic!) in the neutron rest frame,
253// x = sin^2(theta/2), theta is the electron scattering angle
254// Magnetic form factor in the dipole approximation.
255
257{
258 G4double result = 1., q2, znq2, znf, znf2, znf4;
259
260 znq2 = 1. + 2.*fee*x/fM;
261
262 q2 = 4.*fee2*x/znq2;
263
264 znf = 1 + q2/fMv2;
265 znf2 = znf*znf;
266 znf4 = znf2*znf2;
267
268 result /= ( x + fAm )*znq2*znq2*znf4;
269
270 result *= ( 1 - x )/( 1 + q2/4./fM2 ) + 2.*x;
271
272 return result;
273}
274
275////////////////////////////////////////////////
276//
277//
278
280 const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
281{
283
284 const G4HadProjectile* aParticle = &aTrack;
285 G4double Tkin = aParticle->GetKineticEnergy();
286 fAm = CalculateAm( Tkin);
287 // G4double En = aParticle->GetTotalEnergy();
288
289 if( Tkin <= LowestEnergyLimit() )
290 {
293 return &theParticleChange;
294 }
295 // sample e-scattering angle and make final state in lab frame
296
297 G4double sin2ht = SampleSin2HalfTheta( Tkin); // in n-rrest frame
298
299 // G4cout<<"sin2ht = "<<sin2ht<<G4endl;
300
301 G4double eTkin = fee; // fM;
302
303 eTkin /= 1.+2.*fee*sin2ht/fM; // fme/En + 2*sin2ht;
304
305 eTkin -= fme;
306
307 // G4cout<<"eTkin = "<<eTkin<<G4endl;
308
309 if( eTkin > fCutEnergy )
310 {
311 G4double ePlab = sqrt( eTkin*(eTkin + 2.*fme) );
312
313 // G4cout<<"ePlab = "<<ePlab<<G4endl;
314
315 G4double cost = 1. - 2*sin2ht;
316
317 if( cost > 1. ) cost = 1.;
318 if( cost < -1. ) cost = -1.;
319
320 G4double sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
321 G4double phi = G4UniformRand()*CLHEP::twopi;
322
323 G4ThreeVector eP( sint*std::cos(phi), sint*std::sin(phi), cost );
324 eP *= ePlab;
325 G4LorentzVector lvt2( eP, eTkin + electron_mass_c2 ); // recoil e- in n-rest frame
326
327 G4LorentzVector lvp1 = aParticle->Get4Momentum();
328 G4LorentzVector lvt1(0.,0.,0.,electron_mass_c2);
329 G4LorentzVector lvsum = lvp1+lvt1;
330
331 G4ThreeVector bst = lvp1.boostVector();
332 lvt2.boost(bst);
333
334 // G4cout<<"lvt2 = "<<lvt2<<G4endl;
335
336 G4DynamicParticle * aSec = new G4DynamicParticle( theElectron, lvt2 );
338
339 G4LorentzVector lvp2 = lvsum-lvt2;
340
341 // G4cout<<"lvp2 = "<<lvp2<<G4endl;
342
343 G4double Tkin2 = lvp2.e()-aParticle->GetDefinition()->GetPDGMass();
346 }
347 else if( eTkin > 0.0 )
348 {
350 Tkin -= eTkin;
351
352 if( Tkin > 0. )
353 {
356 }
357 }
358 else
359 {
362 }
363 G4int Z = targetNucleus.GetZ_asInt();
364 Z *= 1;
365
366 return &theParticleChange;
367}
368
369//
370//
371///////////////////////////
double epsilon(double density, double temperature)
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)
G4NeutronElectronElModel(const G4String &name="nu-e-elastic")
G4double CalculateAm(G4double momentum)
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
virtual G4bool IsApplicable(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
G4double GetTransfer(G4int iTkin, G4int iTransfer, G4double position)
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
const G4String & GetParticleName() const
void PutValue(std::size_t index, G4double energy, G4double dValue)
void clearAndDestroy()
G4double GetLowEdgeEnergy(std::size_t binNumber) const
Definition: DoubConv.h:17