Geant4  10.01.p01
G4PAIPhotModel.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 // $Id: G4PAIPhotModel.cc 73607 2013-09-02 10:04:03Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class
31 // File name: G4PAIPhotModel.cc
32 //
33 // Author: Vladimir.Grichine@cern.ch on base of G4PAIModel MT interface
34 //
35 // Creation date: 07.10.2013
36 //
37 // Modifications:
38 //
39 //
40 
41 #include "G4PAIPhotModel.hh"
42 
43 #include "G4SystemOfUnits.hh"
44 #include "G4PhysicalConstants.hh"
45 #include "G4Region.hh"
46 #include "G4PhysicsLogVector.hh"
47 #include "G4PhysicsFreeVector.hh"
48 #include "G4PhysicsTable.hh"
49 #include "G4ProductionCutsTable.hh"
50 #include "G4MaterialCutsCouple.hh"
51 #include "G4MaterialTable.hh"
52 #include "G4SandiaTable.hh"
53 #include "G4OrderedTable.hh"
54 
55 #include "Randomize.hh"
56 #include "G4Electron.hh"
57 #include "G4Positron.hh"
58 #include "G4Gamma.hh"
59 #include "G4Poisson.hh"
60 #include "G4Step.hh"
61 #include "G4Material.hh"
62 #include "G4DynamicParticle.hh"
63 #include "G4ParticleDefinition.hh"
65 #include "G4PAIPhotData.hh"
66 #include "G4DeltaAngle.hh"
67 
69 
70 using namespace std;
71 
74  fVerbose(0),
75  fModelData(0),
76  fParticle(0)
77 {
80 
81  fParticleChange = 0;
82 
83  if(p) { SetParticle(p); }
84  else { SetParticle(fElectron); }
85 
86  // default generator
88 
89  isInitialised = false;
90 }
91 
93 
95 {
96  //G4cout << "G4PAIPhotModel::~G4PAIPhotModel() " << this << G4endl;
97  if(IsMaster()) { delete fModelData; fModelData = 0; }
98 }
99 
101 
103  const G4DataVector& cuts)
104 {
105  // if(fVerbose > 0)
106  {
107  G4cout<<"G4PAIPhotModel::Initialise for "<<p->GetParticleName()<<G4endl;
108  }
109 
110  if(isInitialised) { return; }
111  isInitialised = true;
112 
113  SetParticle(p);
115 
116  if(IsMaster()) {
117 
119 
120  if(!fModelData) {
121 
122  G4double tmin = LowEnergyLimit()*fRatio;
124  fModelData = new G4PAIPhotData(tmin, tmax, fVerbose);
125  }
126  // Prepare initialization
127  const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
128  size_t numOfMat = G4Material::GetNumberOfMaterials();
129  size_t numRegions = fPAIRegionVector.size();
130 
131  for(size_t iReg = 0; iReg < numRegions; ++iReg) {
132  const G4Region* curReg = fPAIRegionVector[iReg];
133  G4Region* reg = const_cast<G4Region*>(curReg);
134 
135  for(size_t jMat = 0; jMat < numOfMat; ++jMat) {
136  G4Material* mat = (*theMaterialTable)[jMat];
137  const G4MaterialCutsCouple* cutCouple = reg->FindCouple(mat);
138  //G4cout << "Couple <" << fCutCouple << G4endl;
139  if(cutCouple) {
140  /*
141  G4cout << "Reg <" <<curReg->GetName() << "> mat <"
142  << fMaterial->GetName() << "> fCouple= "
143  << fCutCouple << " idx= " << fCutCouple->GetIndex()
144  <<" " << p->GetParticleName() <<G4endl;
145  // G4cout << cuts.size() << G4endl;
146  */
147  // check if this couple is not already initialized
148  size_t n = fMaterialCutsCoupleVector.size();
149  if(0 < n) {
150  for(size_t i=0; i<fMaterialCutsCoupleVector.size(); ++i) {
151  if(cutCouple == fMaterialCutsCoupleVector[i]) {
152  break;
153  }
154  }
155  }
156  // initialise data banks
157  fMaterialCutsCoupleVector.push_back(cutCouple);
158  G4double deltaCutInKinEnergy = cuts[cutCouple->GetIndex()];
159  fModelData->Initialise(cutCouple, deltaCutInKinEnergy, this);
160  }
161  }
162  }
163  }
164 }
165 
167 
169  G4VEmModel* masterModel)
170 {
171  fModelData = static_cast<G4PAIPhotModel*>(masterModel)->GetPAIPhotData();
173 }
174 
176 
178  const G4ParticleDefinition* p,
179  G4double kineticEnergy,
180  G4double cutEnergy)
181 {
182  G4int coupleIndex = FindCoupleIndex(CurrentCouple());
183  if(0 > coupleIndex) { return 0.0; }
184 
185  G4double cut = std::min(MaxSecondaryEnergy(p, kineticEnergy), cutEnergy);
186 
187  G4double scaledTkin = kineticEnergy*fRatio;
188 
189  return fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin, cut);
190 }
191 
193 
195  const G4ParticleDefinition* p,
196  G4double kineticEnergy,
197  G4double cutEnergy,
198  G4double maxEnergy )
199 {
200  G4int coupleIndex = FindCoupleIndex(CurrentCouple());
201 
202  if(0 > coupleIndex) return 0.0;
203 
204  G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
205 
206  if(tmax <= cutEnergy) return 0.0;
207 
208  G4double scaledTkin = kineticEnergy*fRatio;
210  scaledTkin,
211  cutEnergy, tmax);
212  return xsc;
213 }
214 
216 //
217 // It is analog of PostStepDoIt in terms of secondary electron.
218 //
219 
220 void G4PAIPhotModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
221  const G4MaterialCutsCouple* matCC,
222  const G4DynamicParticle* dp,
223  G4double tmin,
224  G4double maxEnergy)
225 {
226  G4int coupleIndex = FindCoupleIndex(matCC);
227  if(0 > coupleIndex) { return; }
228 
229  SetParticle(dp->GetDefinition());
230 
231  G4double kineticEnergy = dp->GetKineticEnergy();
232 
233  G4double tmax = MaxSecondaryEnergy(fParticle, kineticEnergy);
234 
235  if( maxEnergy < tmax) tmax = maxEnergy;
236  if( tmin >= tmax) return;
237 
238  G4ThreeVector direction = dp->GetMomentumDirection();
239  G4double scaledTkin = kineticEnergy*fRatio;
240  G4double totalEnergy = kineticEnergy + fMass;
241  G4double totalMomentum = sqrt(kineticEnergy*(totalEnergy + fMass));
242  G4double plRatio = fModelData->GetPlasmonRatio(coupleIndex, scaledTkin);
243 
244  if( G4UniformRand() <= plRatio )
245  {
246  G4double deltaTkin = fModelData->SamplePostStepPlasmonTransfer(coupleIndex, scaledTkin);
247 
248  // G4cout<<"G4PAIPhotModel::SampleSecondaries; dp "<<dp->GetParticleDefinition()->GetParticleName()
249  // <<"; Tkin = "<<kineticEnergy/keV<<" keV; transfer = "<<deltaTkin/keV<<" keV "<<G4endl;
250 
251  if( deltaTkin <= 0. && fVerbose > 0)
252  {
253  G4cout<<"G4PAIPhotModel::SampleSecondary e- deltaTkin = "<<deltaTkin<<G4endl;
254  }
255  if( deltaTkin <= 0.) return;
256 
257  if( deltaTkin > tmax) deltaTkin = tmax;
258 
259  const G4Element* anElement = SelectRandomAtom(matCC,fParticle,kineticEnergy);
260  G4int Z = G4lrint(anElement->GetZ());
261 
263  GetAngularDistribution()->SampleDirection(dp, deltaTkin,
264  Z, matCC->GetMaterial()),
265  deltaTkin);
266 
267  // primary change
268 
269  kineticEnergy -= deltaTkin;
270 
271  if( kineticEnergy <= 0. ) // kill primary as local? energy deposition
272  {
274  fParticleChange->ProposeLocalEnergyDeposit(kineticEnergy+deltaTkin);
275  // fParticleChange->ProposeTrackStatus(fStopAndKill);
276  return;
277  }
278  else
279  {
280  G4ThreeVector dir = totalMomentum*direction - deltaRay->GetMomentum();
281  direction = dir.unit();
284  vdp->push_back(deltaRay);
285  }
286  }
287  else // secondary X-ray CR photon
288  {
289  G4double deltaTkin = fModelData->SamplePostStepPhotonTransfer(coupleIndex, scaledTkin);
290 
291  // G4cout<<"PAIPhotonModel PhotonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl;
292 
293  if( deltaTkin <= 0. )
294  {
295  G4cout<<"G4PAIPhotonModel::SampleSecondary gamma deltaTkin = "<<deltaTkin<<G4endl;
296  }
297  if( deltaTkin <= 0.) return;
298 
299  if( deltaTkin >= kineticEnergy ) // stop primary
300  {
301  deltaTkin = kineticEnergy;
302  kineticEnergy = 0.0;
303  }
304  G4double costheta = 0.; // G4UniformRand(); // VG: ??? for start only
305  G4double sintheta = sqrt((1.+costheta)*(1.-costheta));
306 
307  // direction of the 'Cherenkov' photon
308  G4double phi = twopi*G4UniformRand();
309  G4double dirx = sintheta*cos(phi), diry = sintheta*sin(phi), dirz = costheta;
310 
311  G4ThreeVector deltaDirection(dirx,diry,dirz);
312  deltaDirection.rotateUz(direction);
313 
314  if( kineticEnergy > 0.) // primary change
315  {
316  kineticEnergy -= deltaTkin;
318  }
319  else // stop primary, but pass X-ray CR
320  {
321  // fParticleChange->ProposeLocalEnergyDeposit(deltaTkin);
323  }
324  // create G4DynamicParticle object for photon ray
325 
326  G4DynamicParticle* photonRay = new G4DynamicParticle;
327  photonRay->SetDefinition( G4Gamma::Gamma() );
328  photonRay->SetKineticEnergy( deltaTkin );
329  photonRay->SetMomentumDirection(deltaDirection);
330 
331  vdp->push_back(photonRay);
332  }
333  return;
334 }
335 
337 
339  const G4DynamicParticle* aParticle,
340  G4double, G4double step,
341  G4double eloss)
342 {
343  // return 0.;
344  G4int coupleIndex = FindCoupleIndex(matCC);
345  if(0 > coupleIndex) { return eloss; }
346 
347  SetParticle(aParticle->GetDefinition());
348 
349 
350  // G4cout << "G4PAIPhotModel::SampleFluctuations step(mm)= "<< step/mm
351  // << " Eloss(keV)= " << eloss/keV << " in "
352  // << matCC->GetMaterial()->GetName() << G4endl;
353 
354 
355  G4double Tkin = aParticle->GetKineticEnergy();
356  G4double scaledTkin = Tkin*fRatio;
357 
358  G4double loss = fModelData->SampleAlongStepPhotonTransfer(coupleIndex, Tkin,
359  scaledTkin,
360  step*fChargeSquare);
361  loss += fModelData->SampleAlongStepPlasmonTransfer(coupleIndex, Tkin,
362  scaledTkin,
363  step*fChargeSquare);
364 
365 
366  // G4cout<<" PAIPhotModel::SampleFluctuations loss = "<<loss/keV<<" keV, on step = "
367  // <<step/mm<<" mm"<<G4endl;
368  return loss;
369 
370 }
371 
373 //
374 // Returns the statistical estimation of the energy loss distribution variance
375 //
376 
377 
379  const G4DynamicParticle* aParticle,
380  G4double tmax,
381  G4double step )
382 {
383  G4double particleMass = aParticle->GetMass();
384  G4double electronDensity = material->GetElectronDensity();
385  G4double kineticEnergy = aParticle->GetKineticEnergy();
386  G4double q = aParticle->GetCharge()/eplus;
387  G4double etot = kineticEnergy + particleMass;
388  G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*particleMass)/(etot*etot);
389  G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * step
390  * electronDensity * q * q;
391 
392  return siga;
393  /*
394  G4double loss, sumLoss=0., sumLoss2=0., sigma2, meanLoss=0.;
395  for(G4int i = 0; i < fMeanNumber; i++)
396  {
397  loss = SampleFluctuations(material,aParticle,tmax,step,meanLoss);
398  sumLoss += loss;
399  sumLoss2 += loss*loss;
400  }
401  meanLoss = sumLoss/fMeanNumber;
402  sigma2 = meanLoss*meanLoss + (sumLoss2-2*sumLoss*meanLoss)/fMeanNumber;
403  return sigma2;
404  */
405 }
406 
408 
410  G4double kinEnergy)
411 {
412  SetParticle(p);
413  G4double tmax = kinEnergy;
414  if(p == fElectron) { tmax *= 0.5; }
415  else if(p != fPositron) {
416  G4double ratio= electron_mass_c2/fMass;
417  G4double gamma= kinEnergy/fMass + 1.0;
418  tmax = 2.0*electron_mass_c2*(gamma*gamma - 1.) /
419  (1. + 2.0*gamma*ratio + ratio*ratio);
420  }
421  return tmax;
422 }
423 
425 
427 {
428  fPAIRegionVector.push_back(r);
429 }
430 
431 //
432 //
const G4ParticleDefinition * fParticle
G4double MaxSecondaryEnergy(const G4ParticleDefinition *, G4double kinEnergy)
G4double SamplePostStepPhotonTransfer(G4int coupleIndex, G4double scaledTkin) const
virtual ~G4PAIPhotModel()
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:622
G4ParticleChangeForLoss * GetParticleChangeForLoss()
Definition: G4VEmModel.cc:120
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
Definition: G4VEmModel.cc:148
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:615
G4PAIPhotData * fModelData
G4PAIPhotData * GetPAIPhotData()
virtual G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
G4double GetPlasmonRatio(G4int coupleIndex, G4double scaledTkin) const
virtual void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel)
G4double GetZ() const
Definition: G4Element.hh:131
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:588
G4double SampleAlongStepPhotonTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double stepFactor) const
std::vector< G4Material * > G4MaterialTable
G4VEmAngularDistribution * GetAngularDistribution()
Definition: G4VEmModel.hh:598
virtual G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy)
G4bool IsMaster() const
Definition: G4VEmModel.hh:699
std::vector< const G4MaterialCutsCouple * > fMaterialCutsCoupleVector
void SetMomentumDirection(const G4ThreeVector &aDirection)
G4ParticleDefinition * GetDefinition() const
int G4int
Definition: G4Types.hh:78
const G4String & GetParticleName() const
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
void Initialise(const G4MaterialCutsCouple *, G4double cut, G4PAIPhotModel *)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
static const G4double reg
std::vector< const G4Region * > fPAIRegionVector
const G4MaterialCutsCouple * CurrentCouple() const
Definition: G4VEmModel.hh:433
#define G4UniformRand()
Definition: Randomize.hh:95
G4GLOB_DLL std::ostream G4cout
G4int FindCoupleIndex(const G4MaterialCutsCouple *)
G4double GetElectronDensity() const
Definition: G4Material.hh:217
const G4ParticleDefinition * fPositron
G4double GetMass() const
const G4ThreeVector & GetMomentumDirection() const
G4double DEDXPerVolume(G4int coupleIndex, G4double scaledTkin, G4double cut) const
G4double GetCharge() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
G4MaterialCutsCouple * FindCouple(G4Material *mat)
const G4int n
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
std::vector< G4EmElementSelector * > * GetElementSelectors()
Definition: G4VEmModel.hh:783
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:595
G4ParticleChangeForLoss * fParticleChange
void SetProposedMomentumDirection(const G4ThreeVector &dir)
void SetKineticEnergy(G4double aEnergy)
G4PAIPhotModel(const G4ParticleDefinition *p=0, const G4String &nam="PAI")
static G4Positron * Positron()
Definition: G4Positron.cc:94
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
Definition: G4VEmModel.hh:791
virtual G4double SampleFluctuations(const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double, G4double, G4double)
int G4lrint(double ad)
Definition: templates.hh:163
G4double SamplePostStepPlasmonTransfer(G4int coupleIndex, G4double scaledTkin) const
virtual G4double Dispersion(const G4Material *, const G4DynamicParticle *, G4double, G4double)
void SetAngularDistribution(G4VEmAngularDistribution *)
Definition: G4VEmModel.hh:605
G4double CrossSectionPerVolume(G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4double SampleAlongStepPlasmonTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double stepFactor) const
const G4ParticleDefinition * fElectron
static G4Electron * Electron()
Definition: G4Electron.cc:94
void DefineForRegion(const G4Region *r)
#define G4endl
Definition: G4ios.hh:61
G4double fChargeSquare
void SetParticle(const G4ParticleDefinition *p)
double G4double
Definition: G4Types.hh:76
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
static const double eplus
Definition: G4SIunits.hh:178
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:525
const G4Material * GetMaterial() const