Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ForwardXrayTR.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// G4ForwardXrayTR class -- implementation file
29//
30// History:
31// 1st version 11.09.97 V. Grichine ([email protected] )
32// 2nd version 17.12.97 V. Grichine
33// 17-09-01, migration of Materials to pure STL (mma)
34// 10-03-03, migration to "cut per region" (V.Ivanchenko)
35// 03.06.03, V.Ivanchenko fix compilation warnings
36
37#include "G4ForwardXrayTR.hh"
38
39#include "globals.hh"
41#include "G4SystemOfUnits.hh"
42#include "G4Poisson.hh"
43#include "G4Material.hh"
44#include "G4PhysicsTable.hh"
45#include "G4PhysicsVector.hh"
47#include "G4PhysicsLogVector.hh"
50
51// Initialization of local constants
52
54
60
64
65G4double G4ForwardXrayTR::fPlasmaCof = 4.0*pi*fine_structure_const*
66 hbarc*hbarc*hbarc/electron_mass_c2;
67
68G4double G4ForwardXrayTR::fCofTR = fine_structure_const/pi;
69
70
71//////////////////////////////////////////////////////////////////////
72//
73// Constructor for creation of physics tables (angle and energy TR
74// distributions) for a couple of selected materials.
75//
76// Recommended for use in applications with many materials involved,
77// when only few (usually couple) materials are interested for generation
78// of TR on the interface between them
79
80
82G4ForwardXrayTR( const G4String& matName1, // G4Material* pMat1,
83 const G4String& matName2, // G4Material* pMat2,
84 const G4String& processName )
85 : G4TransitionRadiation(processName)
86{
87 fPtrGamma = nullptr;
90 fSigma1 = fSigma2 = 0.0;
91 fAngleDistrTable = nullptr;
92 fEnergyDistrTable = nullptr;
94
95 // Proton energy vector initialization
96 //
99 G4int iMat;
100 const G4ProductionCutsTable* theCoupleTable=
102 G4int numOfCouples = theCoupleTable->GetTableSize();
103
104 G4bool build = true;
105
106 for(iMat=0;iMat<numOfCouples;iMat++) // check first material name
107 {
108 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(iMat);
109 if( matName1 == couple->GetMaterial()->GetName() )
110 {
111 fMatIndex1 = couple->GetIndex();
112 break;
113 }
114 }
115 if(iMat == numOfCouples)
116 {
117 G4Exception("G4ForwardXrayTR::G4ForwardXrayTR", "ForwardXrayTR01", JustWarning, "Invalid first material name in G4ForwardXrayTR constructor!");
118 build = false;
119 }
120
121 if(build) {
122 for(iMat=0;iMat<numOfCouples;iMat++) // check second material name
123 {
124 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(iMat);
125 if( matName2 == couple->GetMaterial()->GetName() )
126 {
127 fMatIndex2 = couple->GetIndex();
128 break;
129 }
130 }
131 if(iMat == numOfCouples)
132 {
133 G4Exception("G4ForwardXrayTR::G4ForwardXrayTR", "ForwardXrayTR02", JustWarning, "Invalid second material name in G4ForwardXrayTR constructor!");
134 build = false;
135 }
136 }
137 // G4cout<<"G4ForwardXray constructor is called"<<G4endl;
138 if(build) { BuildXrayTRtables(); }
139}
140
141/////////////////////////////////////////////////////////////////////////
142//
143// Constructor used by X-ray transition radiation parametrisation models
144
146G4ForwardXrayTR( const G4String& processName )
147 : G4TransitionRadiation(processName)
148{
149 fPtrGamma = nullptr;
150 fGammaCutInKineticEnergy = nullptr;
152 fSigma1 = fSigma2 = 0.0;
153 fAngleDistrTable = nullptr;
154 fEnergyDistrTable = nullptr;
156
157 // Proton energy vector initialization
158 //
161}
162
163
164//////////////////////////////////////////////////////////////////////
165//
166// Destructor
167//
168
170{
171 delete fAngleDistrTable;
172 delete fEnergyDistrTable;
173 delete fProtonEnergyVector;
174}
175
177 G4double,
179{
180 *condition = Forced;
181 return DBL_MAX; // so TR doesn't limit mean free path
182}
183
184//////////////////////////////////////////////////////////////////////////////
185//
186// Build physics tables for energy and angular distributions of X-ray TR photon
187
189{
190 G4int iMat, jMat, iTkin, iTR, iPlace;
191 const G4ProductionCutsTable* theCoupleTable=
193 G4int numOfCouples = theCoupleTable->GetTableSize();
194
196
199
200
201 for(iMat=0;iMat<numOfCouples;iMat++) // loop over pairs of different materials
202 {
203 if( iMat != fMatIndex1 && iMat != fMatIndex2 ) continue;
204
205 for(jMat=0;jMat<numOfCouples;jMat++) // transition iMat -> jMat !!!
206 {
207 if( iMat == jMat || ( jMat != fMatIndex1 && jMat != fMatIndex2 ) )
208 {
209 continue;
210 }
211 else
212 {
213 const G4MaterialCutsCouple* iCouple = theCoupleTable->GetMaterialCutsCouple(iMat);
214 const G4MaterialCutsCouple* jCouple = theCoupleTable->GetMaterialCutsCouple(jMat);
215 const G4Material* mat1 = iCouple->GetMaterial();
216 const G4Material* mat2 = jCouple->GetMaterial();
217
220
221 // fGammaTkinCut = fGammaCutInKineticEnergy[jMat]; // TR photon in jMat !
222
223 fGammaTkinCut = 0.0;
224
225 if(fGammaTkinCut > fTheMinEnergyTR) // setting of min/max TR energies
226 {
228 }
229 else
230 {
232 }
234 {
235 fMaxEnergyTR = 2.0*fGammaTkinCut; // usually very low TR rate
236 }
237 else
238 {
240 }
241 for(iTkin=0;iTkin<fTotBin;iTkin++) // Lorentz factor loop
242 {
244 energyVector = new G4PhysicsLogVector( fMinEnergyTR,
246 fBinTR );
247
248 fGamma = 1.0 + (fProtonEnergyVector->
249 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
250
251 fMaxThetaTR = 10000.0/(fGamma*fGamma);
252
254 {
256 }
257 else
258 {
260 {
262 }
263 }
264 // G4cout<<G4endl<<"fGamma = "<<fGamma<<" fMaxThetaTR = "<<fMaxThetaTR<<G4endl;
266 angleVector = new G4PhysicsLinearVector( 0.0,
268 fBinTR );
269 G4double energySum = 0.0;
270 G4double angleSum = 0.0;
271
272 energyVector->PutValue(fBinTR-1,energySum);
273 angleVector->PutValue(fBinTR-1,angleSum);
274
275 for(iTR=fBinTR-2;iTR>=0;iTR--)
276 {
277 energySum += fCofTR*EnergySum(energyVector->GetLowEdgeEnergy(iTR),
278 energyVector->GetLowEdgeEnergy(iTR+1));
279
280 angleSum += fCofTR*AngleSum(angleVector->GetLowEdgeEnergy(iTR),
281 angleVector->GetLowEdgeEnergy(iTR+1));
282
283 energyVector->PutValue(iTR,energySum);
284 angleVector ->PutValue(iTR,angleSum);
285 }
286 // G4cout<<"sumE = "<<energySum<<"; sumA = "<<angleSum<<G4endl;
287
288 if(jMat < iMat)
289 {
290 iPlace = fTotBin+iTkin; // (iMat*(numOfMat-1)+jMat)*
291 }
292 else // jMat > iMat right part of matrices (jMat-1) !
293 {
294 iPlace = iTkin; // (iMat*(numOfMat-1)+jMat-1)*fTotBin+
295 }
296 fEnergyDistrTable->insertAt(iPlace,energyVector);
297 fAngleDistrTable->insertAt(iPlace,angleVector);
298 } // iTkin
299 } // jMat != iMat
300 } // jMat
301 } // iMat
302 // G4cout<<"G4ForwardXrayTR::BuildXrayTRtables have been called"<<G4endl;
303}
304
305///////////////////////////////////////////////////////////////////////
306//
307// This function returns the spectral and angle density of TR quanta
308// in X-ray energy region generated forward when a relativistic
309// charged particle crosses interface between two materials.
310// The high energy small theta approximation is applied.
311// (matter1 -> matter2)
312// varAngle =2* (1 - std::cos(Theta)) or approximately = Theta*Theta
313//
314
317 G4double varAngle ) const
318{
319 G4double formationLength1, formationLength2;
320 formationLength1 = 1.0/
321 (1.0/(fGamma*fGamma)
322 + fSigma1/(energy*energy)
323 + varAngle);
324 formationLength2 = 1.0/
325 (1.0/(fGamma*fGamma)
326 + fSigma2/(energy*energy)
327 + varAngle);
328 return (varAngle/energy)*(formationLength1 - formationLength2)
329 *(formationLength1 - formationLength2);
330
331}
332
333
334//////////////////////////////////////////////////////////////////
335//
336// Analytical formula for angular density of X-ray TR photons
337//
338
340 G4double varAngle ) const
341{
342 G4double x, x2, /*a, b,*/ c, d, f, a2, b2, a4, b4;
343 G4double cof1, cof2, cof3;
344 x = 1.0/energy;
345 x2 = x*x;
346 c = 1.0/fSigma1;
347 d = 1.0/fSigma2;
348 f = (varAngle + 1.0/(fGamma*fGamma));
349 a2 = c*f;
350 b2 = d*f;
351 a4 = a2*a2;
352 b4 = b2*b2;
353 //a = std::sqrt(a2);
354 // b = std::sqrt(b2);
355 cof1 = c*c*(0.5/(a2*(x2 +a2)) +0.5*std::log(x2/(x2 +a2))/a4);
356 cof3 = d*d*(0.5/(b2*(x2 +b2)) +0.5*std::log(x2/(x2 +b2))/b4);
357 cof2 = -c*d*(std::log(x2/(x2 +b2))/b2 - std::log(x2/(x2 +a2))/a2)/(a2 - b2) ;
358 return -varAngle*(cof1 + cof2 + cof3);
359}
360
361/////////////////////////////////////////////////////////////////////
362//
363// Definite integral of X-ray TR spectral-angle density from energy1
364// to energy2
365//
366
368 G4double energy2,
369 G4double varAngle ) const
370{
371 return AngleDensity(energy2,varAngle)
372 - AngleDensity(energy1,varAngle);
373}
374
375//////////////////////////////////////////////////////////////////////
376//
377// Integral angle distribution of X-ray TR photons based on analytical
378// formula for angle density
379//
380
382 G4double varAngle2 ) const
383{
384 G4int i;
385 G4double h , sumEven = 0.0 , sumOdd = 0.0;
386 h = 0.5*(varAngle2 - varAngle1)/fSympsonNumber;
387 for(i=1;i<fSympsonNumber;i++)
388 {
389 sumEven += EnergyInterval(fMinEnergyTR,fMaxEnergyTR,varAngle1 + 2*i*h );
391 varAngle1 + (2*i - 1)*h );
392 }
394 varAngle1 + (2*fSympsonNumber - 1)*h );
395
396 return h*(EnergyInterval(fMinEnergyTR,fMaxEnergyTR,varAngle1)
398 + 4.0*sumOdd + 2.0*sumEven )/3.0;
399}
400
401/////////////////////////////////////////////////////////////////////
402//
403// Analytical Expression for spectral density of Xray TR photons
404// x = 2*(1 - std::cos(Theta)) ~ Theta^2
405//
406
408 G4double x ) const
409{
410 G4double a, b;
411 a = 1.0/(fGamma*fGamma)
412 + fSigma1/(energy*energy) ;
413 b = 1.0/(fGamma*fGamma)
414 + fSigma2/(energy*energy) ;
415 return ( (a + b)*std::log((x + b)/(x + a))/(a - b)
416 + a/(x + a) + b/(x + b) )/energy;
417
418}
419
420////////////////////////////////////////////////////////////////////
421//
422// The spectral density in some angle interval from varAngle1 to
423// varAngle2
424//
425
427 G4double varAngle1,
428 G4double varAngle2 ) const
429{
430 return SpectralDensity(energy,varAngle2)
431 - SpectralDensity(energy,varAngle1);
432}
433
434////////////////////////////////////////////////////////////////////
435//
436// Integral spectral distribution of X-ray TR photons based on
437// analytical formula for spectral density
438//
439
441 G4double energy2 ) const
442{
443 G4int i;
444 G4double h , sumEven = 0.0 , sumOdd = 0.0;
445 h = 0.5*(energy2 - energy1)/fSympsonNumber;
446 for(i=1;i<fSympsonNumber;i++)
447 {
448 sumEven += AngleInterval(energy1 + 2*i*h,0.0,fMaxThetaTR);
449 sumOdd += AngleInterval(energy1 + (2*i - 1)*h,0.0,fMaxThetaTR);
450 }
451 sumOdd += AngleInterval(energy1 + (2*fSympsonNumber - 1)*h,
452 0.0,fMaxThetaTR);
453
454 return h*( AngleInterval(energy1,0.0,fMaxThetaTR)
455 + AngleInterval(energy2,0.0,fMaxThetaTR)
456 + 4.0*sumOdd + 2.0*sumEven )/3.0;
457}
458
459/////////////////////////////////////////////////////////////////////////
460//
461// PostStepDoIt function for creation of forward X-ray photons in TR process
462// on boubndary between two materials with really different plasma energies
463//
464
466 const G4Step& aStep)
467{
469 // G4cout<<"call G4ForwardXrayTR::PostStepDoIt"<<G4endl;
470 G4int iMat, jMat, iTkin, iPlace, numOfTR, iTR, iTransfer;
471
472 G4double energyPos, anglePos, energyTR, theta, phi, dirX, dirY, dirZ;
473 G4double W, W1, W2, E1, E2;
474
475 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
476 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
478
479 if (pPostStepPoint->GetStepStatus() != fGeomBoundary)
480 {
481 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
482 }
483 if (aTrack.GetStepLength() <= tol)
484 {
485 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
486 }
487 // Come on boundary, so begin to try TR
488
489 const G4MaterialCutsCouple* iCouple = pPreStepPoint ->GetPhysicalVolume()->
490 GetLogicalVolume()->GetMaterialCutsCouple();
491 const G4MaterialCutsCouple* jCouple = pPostStepPoint ->GetPhysicalVolume()->
492 GetLogicalVolume()->GetMaterialCutsCouple();
493 const G4Material* iMaterial = iCouple->GetMaterial();
494 const G4Material* jMaterial = jCouple->GetMaterial();
495 iMat = iCouple->GetIndex();
496 jMat = jCouple->GetIndex();
497
498 // The case of equal or approximate (in terms of plasma energy) materials
499 // No TR photons ?!
500
501 if ( iMat == jMat
502 || ( (fMatIndex1 >= 0 && fMatIndex2 >= 0)
503 && ( iMat != fMatIndex1 && iMat != fMatIndex2 )
504 && ( jMat != fMatIndex1 && jMat != fMatIndex2 ) )
505
506 || iMaterial->GetState() == jMaterial->GetState()
507
508 ||(iMaterial->GetState() == kStateSolid && jMaterial->GetState() == kStateLiquid )
509
510 ||(iMaterial->GetState() == kStateLiquid && jMaterial->GetState() == kStateSolid ) )
511 {
512 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
513 }
514
515 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
516 G4double charge = aParticle->GetDefinition()->GetPDGCharge();
517
518 if(charge == 0.0) // Uncharged particle doesn't Generate TR photons
519 {
520 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
521 }
522 // Now we are ready to Generate TR photons
523
524 G4double chargeSq = charge*charge;
525 G4double kinEnergy = aParticle->GetKineticEnergy();
526 G4double massRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass();
527 G4double TkinScaled = kinEnergy*massRatio;
528 for(iTkin=0;iTkin<fTotBin;iTkin++)
529 {
530 if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) // <= ?
531 {
532 break;
533 }
534 }
535 if(jMat < iMat)
536 {
537 iPlace = fTotBin + iTkin - 1; // (iMat*(numOfMat - 1) + jMat)*
538 }
539 else
540 {
541 iPlace = iTkin - 1; // (iMat*(numOfMat - 1) + jMat - 1)*fTotBin +
542 }
543 // G4PhysicsVector* energyVector1 = (*fEnergyDistrTable)(iPlace) ;
544 // G4PhysicsVector* energyVector2 = (*fEnergyDistrTable)(iPlace + 1);
545
546 // G4PhysicsVector* angleVector1 = (*fAngleDistrTable)(iPlace) ;
547 // G4PhysicsVector* angleVector2 = (*fAngleDistrTable)(iPlace + 1) ;
548
549 G4ParticleMomentum particleDir = aParticle->GetMomentumDirection();
550
551 if(iTkin == fTotBin) // TR plato, try from left
552 {
553 // G4cout<<iTkin<<" mean TR number = "<<( (*(*fEnergyDistrTable)(iPlace))(0) +
554 // (*(*fAngleDistrTable)(iPlace))(0) )
555 // *chargeSq*0.5<<G4endl;
556
557 numOfTR = G4Poisson( ( (*(*fEnergyDistrTable)(iPlace))(0) +
558 (*(*fAngleDistrTable)(iPlace))(0) )
559 *chargeSq*0.5 );
560 if(numOfTR == 0)
561 {
562 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
563 }
564 else
565 {
566 // G4cout<<"Number of X-ray TR photons = "<<numOfTR<<G4endl;
567
569
570 for(iTR=0;iTR<numOfTR;iTR++)
571 {
572 energyPos = (*(*fEnergyDistrTable)(iPlace))(0)*G4UniformRand();
573 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
574 {
575 if(energyPos >= (*(*fEnergyDistrTable)(iPlace))(iTransfer)) break;
576 }
577 energyTR = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
578
579 // G4cout<<"energyTR = "<<energyTR/keV<<"keV"<<G4endl;
580
581 kinEnergy -= energyTR;
583
584 anglePos = (*(*fAngleDistrTable)(iPlace))(0)*G4UniformRand();
585 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
586 {
587 if(anglePos > (*(*fAngleDistrTable)(iPlace))(iTransfer)) break;
588 }
589 theta = std::sqrt((*fAngleDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1));
590
591 // G4cout<<iTransfer<<" : theta = "<<theta<<G4endl;
592
593 phi = twopi*G4UniformRand();
594 dirX = std::sin(theta)*std::cos(phi) ;
595 dirY = std::sin(theta)*std::sin(phi) ;
596 dirZ = std::cos(theta) ;
597 G4ThreeVector directionTR(dirX,dirY,dirZ);
598 directionTR.rotateUz(particleDir);
600 directionTR,
601 energyTR );
602 aParticleChange.AddSecondary(aPhotonTR);
603 }
604 }
605 }
606 else
607 {
608 if(iTkin == 0) // Tkin is too small, neglect of TR photon generation
609 {
610 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
611 }
612 else // general case: Tkin between two vectors of the material
613 {
614 E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1);
616 W = 1.0/(E2 - E1);
617 W1 = (E2 - TkinScaled)*W;
618 W2 = (TkinScaled - E1)*W;
619
620 // G4cout<<iTkin<<" mean TR number = "<<(((*(*fEnergyDistrTable)(iPlace))(0)+
621 // (*(*fAngleDistrTable)(iPlace))(0))*W1 +
622 // ((*(*fEnergyDistrTable)(iPlace + 1))(0)+
623 // (*(*fAngleDistrTable)(iPlace + 1))(0))*W2)
624 // *chargeSq*0.5<<G4endl;
625
626 numOfTR = G4Poisson((((*(*fEnergyDistrTable)(iPlace))(0)+
627 (*(*fAngleDistrTable)(iPlace))(0))*W1 +
628 ((*(*fEnergyDistrTable)(iPlace + 1))(0)+
629 (*(*fAngleDistrTable)(iPlace + 1))(0))*W2)
630 *chargeSq*0.5 );
631 if(numOfTR == 0)
632 {
633 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
634 }
635 else
636 {
637 // G4cout<<"Number of X-ray TR photons = "<<numOfTR<<G4endl;
638
640 for(iTR=0;iTR<numOfTR;iTR++)
641 {
642 energyPos = ((*(*fEnergyDistrTable)(iPlace))(0)*W1+
643 (*(*fEnergyDistrTable)(iPlace + 1))(0)*W2)*G4UniformRand();
644 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
645 {
646 if(energyPos >= ((*(*fEnergyDistrTable)(iPlace))(iTransfer)*W1+
647 (*(*fEnergyDistrTable)(iPlace + 1))(iTransfer)*W2)) break;
648 }
649 energyTR = ((*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer))*W1+
650 ((*fEnergyDistrTable)(iPlace + 1)->GetLowEdgeEnergy(iTransfer))*W2;
651
652 // G4cout<<"energyTR = "<<energyTR/keV<<"keV"<<G4endl;
653
654 kinEnergy -= energyTR;
656
657 anglePos = ((*(*fAngleDistrTable)(iPlace))(0)*W1+
658 (*(*fAngleDistrTable)(iPlace + 1))(0)*W2)*G4UniformRand();
659 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
660 {
661 if(anglePos > ((*(*fAngleDistrTable)(iPlace))(iTransfer)*W1+
662 (*(*fAngleDistrTable)(iPlace + 1))(iTransfer)*W2)) break;
663 }
664 theta = std::sqrt(((*fAngleDistrTable)(iPlace)->
665 GetLowEdgeEnergy(iTransfer-1))*W1+
666 ((*fAngleDistrTable)(iPlace + 1)->
667 GetLowEdgeEnergy(iTransfer-1))*W2);
668
669 // G4cout<<iTransfer<<" : theta = "<<theta<<G4endl;
670
671 phi = twopi*G4UniformRand();
672 dirX = std::sin(theta)*std::cos(phi) ;
673 dirY = std::sin(theta)*std::sin(phi) ;
674 dirZ = std::cos(theta) ;
675 G4ThreeVector directionTR(dirX,dirY,dirZ);
676 directionTR.rotateUz(particleDir);
678 directionTR,
679 energyTR );
680 aParticleChange.AddSecondary(aPhotonTR);
681 }
682 }
683 }
684 }
685 return &aParticleChange;
686}
687
688////////////////////////////////////////////////////////////////////////////
689//
690// Test function for checking of PostStepDoIt random preparation of TR photon
691// energy
692//
693
696{
697 G4int iPlace, numOfTR, iTR, iTransfer;
698 G4double energyTR = 0.0; // return this value for no TR photons
699 G4double energyPos ;
700 G4double W1, W2;
701
702 const G4ProductionCutsTable* theCoupleTable=
704 G4int numOfCouples = theCoupleTable->GetTableSize();
705
706 // The case of equal or approximate (in terms of plasma energy) materials
707 // No TR photons ?!
708
709 const G4MaterialCutsCouple* iCouple = theCoupleTable->GetMaterialCutsCouple(iMat);
710 const G4MaterialCutsCouple* jCouple = theCoupleTable->GetMaterialCutsCouple(jMat);
711 const G4Material* iMaterial = iCouple->GetMaterial();
712 const G4Material* jMaterial = jCouple->GetMaterial();
713
714 if ( iMat == jMat
715
716 || iMaterial->GetState() == jMaterial->GetState()
717
718 ||(iMaterial->GetState() == kStateSolid && jMaterial->GetState() == kStateLiquid )
719
720 ||(iMaterial->GetState() == kStateLiquid && jMaterial->GetState() == kStateSolid ) )
721
722 {
723 return energyTR;
724 }
725
726 if(jMat < iMat)
727 {
728 iPlace = (iMat*(numOfCouples - 1) + jMat)*fTotBin + iTkin - 1;
729 }
730 else
731 {
732 iPlace = (iMat*(numOfCouples - 1) + jMat - 1)*fTotBin + iTkin - 1;
733 }
734 G4PhysicsVector* energyVector1 = (*fEnergyDistrTable)(iPlace) ;
735 G4PhysicsVector* energyVector2 = (*fEnergyDistrTable)(iPlace + 1);
736
737 if(iTkin == fTotBin) // TR plato, try from left
738 {
739 numOfTR = G4Poisson( (*energyVector1)(0) );
740 if(numOfTR == 0)
741 {
742 return energyTR;
743 }
744 else
745 {
746 for(iTR=0;iTR<numOfTR;iTR++)
747 {
748 energyPos = (*energyVector1)(0)*G4UniformRand();
749 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
750 {
751 if(energyPos >= (*energyVector1)(iTransfer)) break;
752 }
753 energyTR += energyVector1->GetLowEdgeEnergy(iTransfer);
754 }
755 }
756 }
757 else
758 {
759 if(iTkin == 0) // Tkin is too small, neglect of TR photon generation
760 {
761 return energyTR;
762 }
763 else // general case: Tkin between two vectors of the material
764 { // use trivial mean half/half
765 W1 = 0.5;
766 W2 = 0.5;
767 numOfTR = G4Poisson( (*energyVector1)(0)*W1 +
768 (*energyVector2)(0)*W2 );
769 if(numOfTR == 0)
770 {
771 return energyTR;
772 }
773 else
774 {
775 G4cout<<"It is still OK in GetEnergyTR(int,int,int)"<<G4endl;
776 for(iTR=0;iTR<numOfTR;iTR++)
777 {
778 energyPos = ((*energyVector1)(0)*W1+
779 (*energyVector2)(0)*W2)*G4UniformRand();
780 for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
781 {
782 if(energyPos >= ((*energyVector1)(iTransfer)*W1+
783 (*energyVector2)(iTransfer)*W2)) break;
784 }
785 energyTR += (energyVector1->GetLowEdgeEnergy(iTransfer))*W1+
786 (energyVector2->GetLowEdgeEnergy(iTransfer))*W2;
787
788 }
789 }
790 }
791 }
792
793 return energyTR;
794}
795
796////////////////////////////////////////////////////////////////////////////
797//
798// Test function for checking of PostStepDoIt random preparation of TR photon
799// theta angle relative to particle direction
800//
801
804{
805 return 0.0;
806}
807
809{
810 return fSympsonNumber;
811}
812
814{
815 return fBinTR;
816}
817
819{
820 return fMinProtonTkin;
821}
822
824{
825 return fMaxProtonTkin;
826}
827
829{
830 return fTotBin;
831}
832
833// end of G4ForwardXrayTR implementation file
834//
835///////////////////////////////////////////////////////////////////////////
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4ForceCondition
@ Forced
@ kStateSolid
Definition: G4Material.hh:111
@ kStateLiquid
Definition: G4Material.hh:111
G4long G4Poisson(G4double mean)
Definition: G4Poisson.hh:50
@ idxG4GammaCut
@ fGeomBoundary
Definition: G4StepStatus.hh:43
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4int fSympsonNumber
G4double SpectralDensity(G4double energy, G4double x) const
G4ForwardXrayTR(const G4String &matName1, const G4String &matName2, const G4String &processName="XrayTR")
static G4double GetMinProtonTkin()
G4double EnergyInterval(G4double energy1, G4double energy2, G4double varAngle) const
static G4double fPlasmaCof
G4double EnergySum(G4double energy1, G4double energy2) const
static G4double fCofTR
static G4int GetSympsonNumber()
static G4double fTheMaxAngle
static G4double fTheMinEnergyTR
static G4double GetMaxProtonTkin()
static G4int GetTotBin()
static G4int GetBinTR()
const std::vector< G4double > * fGammaCutInKineticEnergy
G4PhysicsTable * fEnergyDistrTable
static G4int fBinTR
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
G4PhysicsTable * fAngleDistrTable
G4double AngleDensity(G4double energy, G4double varAngle) const
G4double GetEnergyTR(G4int iMat, G4int jMat, G4int iTkin) const
static G4double fMinProtonTkin
G4double AngleInterval(G4double energy, G4double varAngle1, G4double varAngle2) const
G4double GetThetaTR(G4int iMat, G4int jMat, G4int iTkin) const
G4PhysicsLogVector * fProtonEnergyVector
G4ParticleDefinition * fPtrGamma
static G4double fTheMinAngle
G4double SpectralAngleTRdensity(G4double energy, G4double varAngle) const override
static G4int fTotBin
G4double AngleSum(G4double varAngle1, G4double varAngle2) const
static G4double fTheMaxEnergyTR
static G4double fMaxProtonTkin
virtual ~G4ForwardXrayTR()
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition) override
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
const G4Material * GetMaterial() const
G4State GetState() const
Definition: G4Material.hh:179
G4double GetElectronDensity() const
Definition: G4Material.hh:215
const G4String & GetName() const
Definition: G4Material.hh:175
void AddSecondary(G4Track *aSecondary)
void ProposeEnergy(G4double finalEnergy)
virtual void Initialize(const G4Track &)
G4double GetPDGCharge() const
void insertAt(std::size_t, G4PhysicsVector *)
G4double GetLowEdgeEnergy(std::size_t binNumber) const
void PutValue(std::size_t index, G4double theValue)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4StepStatus GetStepStatus() const
G4VPhysicalVolume * GetPhysicalVolume() const
Definition: G4Step.hh:62
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void SetNumberOfSecondaries(G4int totSecondaries)
G4ParticleChange aParticleChange
Definition: G4VProcess.hh:327
const G4double pi
#define DBL_MAX
Definition: templates.hh:62