Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PolarizedMollerBhabhaModel.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//
28// GEANT4 Class file
29//
30// File name: G4PolarizedMollerBhabhaModel
31//
32// Author: A.Schaelicke on base of Vladimir Ivanchenko code
33//
34// Creation date: 10.11.2005
35//
36// Modifications:
37//
38// 20-08-05, modified interface (A.Schaelicke)
39//
40// Class Description:
41//
42// Implementation of energy loss and delta-electron production by e+/e-
43// (including polarization effects)
44//
45// -------------------------------------------------------------------
46//
47//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
49
52#include "G4Electron.hh"
53#include "G4Positron.hh"
55#include "Randomize.hh"
56
61
62//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
63
65 const G4String& nam)
66 : G4MollerBhabhaModel(p,nam)
67{
68
69 // G4cout<<" particle==electron "<<(p==theElectron)<<G4endl;
70 isElectron=(p==theElectron); // necessary due to wrong order in G4MollerBhabhaModel constructor!
71
72 if (p==nullptr) {
73
74 }
75 if (!isElectron) {
76 G4cout<<" buildBhabha cross section "<<isElectron<<G4endl;
77 crossSectionCalculator = new G4PolarizedBhabhaCrossSection();
78 } else {
79 G4cout<<" buildMoller cross section "<<isElectron<<G4endl;
80 crossSectionCalculator = new G4PolarizedMollerCrossSection();
81 }
82}
83
84//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
85
87{
88 if (crossSectionCalculator) {
89 delete crossSectionCalculator;
90 }
91}
92
93
94//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
95
97 const G4ParticleDefinition* pd,
98 G4double kinEnergy,
99 G4double cut,
100 G4double emax)
101{
102 G4double xs =
104 cut,emax);
105// G4cout<<"calc eIoni xsec "<<xs<<G4endl;
106// G4cout<<" "<<kinEnergy<<" "<<cut<<" "<<emax<<G4endl;
107 G4double factor=1.;
108 if (xs!=0.) {
109 // G4cout<<"calc asym"<<G4endl;
110 G4double tmax = MaxSecondaryEnergy(pd, kinEnergy);
111 tmax = std::min(emax, tmax);
112
113 if (std::fabs(cut/emax-1.)<1.e-10) return xs;
114
115 if(cut < tmax) {
116
117 G4double xmin = cut/kinEnergy;
118 G4double xmax = tmax/kinEnergy;
119// G4cout<<"calc asym "<<xmin<<","<<xmax<<G4endl;
120 G4double gam = kinEnergy/electron_mass_c2 + 1.0;
121
122 G4double crossPol=crossSectionCalculator->
123 TotalXSection(xmin,xmax,gam,
124 theBeamPolarization,
125 theTargetPolarization);
126 G4double crossUnpol=crossSectionCalculator->
127 TotalXSection(xmin,xmax,gam,
130 if (crossUnpol>0.) factor=crossPol/crossUnpol;
131 // G4cout<<" factor="<<factor<<G4endl;
132 }
133 }
134 return xs*factor;
135}
136
137//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
138
139void G4PolarizedMollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
140 const G4MaterialCutsCouple* ,
141 const G4DynamicParticle* dp,
142 G4double tmin,
143 G4double maxEnergy)
144{
145 // *** obtain and save target and beam polarization ***
147
148 const G4Track * aTrack = fParticleChange->GetCurrentTrack();
149
150 // obtain polarization of the beam
151 theBeamPolarization = dp->GetPolarization();
152
153 // obtain polarization of the media
154 G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
155 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
156 const G4bool targetIsPolarized = polarizationManger->IsPolarized(aLVolume);
157 theTargetPolarization = polarizationManger->GetVolumePolarization(aLVolume);
158
159 // transfer target polarization in interaction frame
160 if (targetIsPolarized)
161 theTargetPolarization.rotateUz(dp->GetMomentumDirection());
162
163
164
165
166 G4double tmax = std::min(maxEnergy, MaxSecondaryKinEnergy(dp));
167 if(tmin >= tmax) return;
168 // if(tmin > tmax) tmin = tmax;
169
170 G4double polL = theBeamPolarization.z()*theTargetPolarization.z();
171 polL=std::fabs(polL);
172 G4double polT = theBeamPolarization.x()*theTargetPolarization.x() +
173 theBeamPolarization.y()*theTargetPolarization.y();
174 polT=std::fabs(polT);
175
176 G4double kineticEnergy = dp->GetKineticEnergy();
177 G4double energy = kineticEnergy + electron_mass_c2;
178 G4double totalMomentum = std::sqrt(kineticEnergy*(energy + electron_mass_c2));
179 G4double xmin = tmin/kineticEnergy;
180 G4double xmax = tmax/kineticEnergy;
181 G4double gam = energy/electron_mass_c2;
182 G4double gamma2 = gam*gam;
183 G4double gmo = gam - 1.;
184 G4double gmo2 = gmo*gmo;
185 G4double gmo3 = gmo2*gmo;
186 G4double gpo = gam + 1.;
187 G4double gpo2 = gpo*gpo;
188 G4double gpo3 = gpo2*gpo;
189 G4double x, y, q, grej, grej2;
190 G4double z = 0.;
191 G4double xs = 0., phi =0.;
192 G4ThreeVector direction = dp->GetMomentumDirection();
193
194 //(Polarized) Moller (e-e-) scattering
195 if (isElectron) {
196 // *** dice according to polarized cross section
197 G4double G = ((2.0*gam - 1.0)/gamma2)*(1. - polT - polL*gam);
198 G4double H = (sqr(gam - 1.0)/gamma2)*(1. + polT + polL*((gam + 3.)/(gam - 1.)));
199
200 y = 1.0 - xmax;
201 grej = 1.0 - G*xmax + xmax*xmax*(H + (1.0 - G*y)/(y*y));
202 grej2 = 1.0 - G*xmin + xmin*xmin*(H + (1.0 - G*y)/(y*y));
203 if (grej2 > grej) grej = grej2;
204 G4double prefM = gamma2*classic_electr_radius*classic_electr_radius/(gmo2*(gam + 1.0));
205 grej *= prefM;
206 do {
207 q = G4UniformRand();
208 x = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
209 if (crossSectionCalculator) {
210 crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
211 theTargetPolarization,1);
212 xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
214 z=xs*sqr(x)*4.;
215 if (grej < z) {
216 G4cout<<"WARNING : error in Moller rejection routine! \n"
217 <<" z = "<<z<<" grej="<<grej<<"\n";
218 }
219 } else {
220 G4cout<<"No calculator in Moller scattering"<<G4endl;
221 }
222 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
223 } while(grej * G4UniformRand() > z);
224 //Bhabha (e+e-) scattering
225 } else {
226 // *** dice according to polarized cross section
227 y = xmax*xmax;
228 grej = 0.;
229 grej += y*y*gmo3*(1. + (polL + polT)*(gam + 3.)/gmo);
230 grej += -2.*xmin*xmin*xmin*gam*gmo2*(1. - (polL + polT)*(gam + 3.)/gmo);
231 grej += y*y*gmo*(3.*gamma2 + 6.*gam + 4.)*(1. + (polL*(3.*gam + 1.)*(gamma2 + gam + 1.) + polT*((gam + 2.)*gamma2 + 1.))/(gmo*(3.*gam*(gam + 2.) + 4.)));
232 grej /= gpo3;
233 grej += -xmin*(2.*gamma2 + 4.*gam + 1.)*(1. - gam*(polL*(2.*gam + 1.) + polT)/(2.*gam*(gam + 2.) + 1.))/gpo2;
234 grej += gamma2/(gamma2 - 1.);
235 G4double prefB = classic_electr_radius*classic_electr_radius/(gam - 1.0);
236 grej *= prefB;
237
238 do {
239 q = G4UniformRand();
240 x = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
241 if (crossSectionCalculator) {
242 crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
243 theTargetPolarization,1);
244 xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
246 z=xs*sqr(x)*4.;
247 } else {
248 G4cout<<"No calculator in Bhabha scattering"<<G4endl;
249 }
250
251 if(z > grej) {
252 G4cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<G4endl;
253 G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
254 << "Majorant " << grej << " < "
255 << z << " for x= " << x<<G4endl
256 << " e+e- (Bhabha) scattering"<<" at KinEnergy "<<kineticEnergy<<G4endl;
257 G4cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<G4endl;
258 }
259 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
260 } while(grej * G4UniformRand() > z);
261 }
262 //
263 //
264 // polar asymmetries (due to transverse polarizations)
265 //
266 //
267 if (crossSectionCalculator) {
268 // grej*=1./(sqr(x)*sqr(gamma2-1))*sqr(gam*(1+gam));
269 grej=xs*2.;
270 do {
271 phi = twopi * G4UniformRand() ;
272 crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
273 theTargetPolarization,1);
274 xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
276 if(xs > grej) {
277 if (isElectron){
278 G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
279 << "Majorant " << grej << " < "
280 << xs << " for phi= " << phi<<G4endl
281 << " e-e- (Moller) scattering"<< G4endl
282 <<"PHI DICING"<<G4endl;
283 } else {
284 G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
285 << "Majorant " << grej << " < "
286 << xs << " for phi= " << phi<<G4endl
287 << " e+e- (Bhabha) scattering"<< G4endl
288 <<"PHI DICING"<<G4endl;
289 }
290 }
291 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
292 } while(grej * G4UniformRand() > xs);
293 }
294
295 // fix kinematics of delta electron
296 G4double deltaKinEnergy = x * kineticEnergy;
297 G4double deltaMomentum =
298 std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
299 G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
300 (deltaMomentum * totalMomentum);
301 G4double sint = 1.0 - cost*cost;
302 if(sint > 0.0) sint = std::sqrt(sint);
303
304
305 G4ThreeVector deltaDirection(-sint*std::cos(phi),-sint*std::sin(phi), cost) ;
306 deltaDirection.rotateUz(direction);
307
308 // primary change
309 kineticEnergy -= deltaKinEnergy;
311
312 if(kineticEnergy > DBL_MIN) {
313 G4ThreeVector dir = totalMomentum*direction - deltaMomentum*deltaDirection;
314 direction = dir.unit();
316 }
317
318 // create G4DynamicParticle object for delta ray
319 G4DynamicParticle* delta = new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
320 vdp->push_back(delta);
321
322 // get interaction frame
323 G4ThreeVector nInteractionFrame =
324 G4PolarizationHelper::GetFrame(direction,deltaDirection);
325
326 if (crossSectionCalculator) {
327 // calculate mean final state polarizations
328
329 theBeamPolarization.InvRotateAz(nInteractionFrame,direction);
330 theTargetPolarization.InvRotateAz(nInteractionFrame,direction);
331 crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
332 theTargetPolarization,2);
333
334 // electron/positron
335 fPositronPolarization=crossSectionCalculator->GetPol2();
336 fPositronPolarization.RotateAz(nInteractionFrame,direction);
337
338 fParticleChange->ProposePolarization(fPositronPolarization);
339
340 // electron
341 fElectronPolarization=crossSectionCalculator->GetPol3();
342 fElectronPolarization.RotateAz(nInteractionFrame,deltaDirection);
343 delta->SetPolarization(fElectronPolarization.x(),
344 fElectronPolarization.y(),
345 fElectronPolarization.z());
346 }
347 else {
348 fPositronPolarization=G4ThreeVector();
349 fElectronPolarization=G4ThreeVector();
350 }
351}
352
353//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
double z() const
Hep3Vector unit() const
double x() const
double y() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
void SetPolarization(const G4ThreeVector &)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
G4ParticleChangeForLoss * fParticleChange
G4ParticleDefinition * theElectron
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
virtual G4double MaxSecondaryEnergy(const G4ParticleDefinition *, G4double kinEnergy) final
void SetProposedKineticEnergy(G4double proposedKinEnergy)
const G4Track * GetCurrentTrack() const
void ProposePolarization(const G4ThreeVector &dir)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
static G4ThreeVector GetFrame(const G4ThreeVector &, const G4ThreeVector &)
bool IsPolarized(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
const G4ThreeVector & GetVolumePolarization(G4LogicalVolume *lVol) const
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
G4PolarizedMollerBhabhaModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="PolarizedMollerBhabha")
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *, G4double kinEnergy, G4double cut, G4double emax) override
static const G4StokesVector ZERO
void InvRotateAz(G4ThreeVector nInteractionFrame, G4ThreeVector particleDirection)
void RotateAz(G4ThreeVector nInteractionFrame, G4ThreeVector particleDirection)
G4VPhysicalVolume * GetVolume() const
G4double MaxSecondaryKinEnergy(const G4DynamicParticle *dynParticle)
Definition: G4VEmModel.hh:510
G4LogicalVolume * GetLogicalVolume() const
virtual G4double XSection(const G4StokesVector &pol2, const G4StokesVector &pol3)=0
virtual G4StokesVector GetPol3()
virtual G4StokesVector GetPol2()
virtual void Initialize(G4double, G4double, G4double, const G4StokesVector &p0, const G4StokesVector &p1, G4int flag=0)
T sqr(const T &x)
Definition: templates.hh:128
#define DBL_MIN
Definition: templates.hh:54