Import Geant4 11.0.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2021-06-25 16:12:29 +02:00
parent c968e26a39
commit 6399a014b6
4200 changed files with 207479 additions and 237366 deletions
@@ -1,17 +0,0 @@
#------------------------------------------------------------------------------
# CMakeLists.txt
# Module : G4xrays
# Package: Geant4.src.G4processes.G4electromagnetic.G4xrays
#
# CMakeLists.txt for building a single granular library.
#
# Generated on : 24/9/2010
#
#
#------------------------------------------------------------------------------
if(GEANT4_BUILD_GRANULAR_LIBS)
include(Geant4MacroLibraryTargets)
GEANT4_GRANULAR_LIBRARY_TARGET(COMPONENT sources.cmake)
endif()
+60 -46
View File
@@ -16,10 +16,24 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
26 May 21: D. Sawkey (xrays-V10-06-09)
26 May 21: D. Sawkey (xrays-V10-07-03)
- G4Scintillation: change IsApplicable to all particles except opticalphoton
and short-lived. Address bug 2372.
16 April 21: B. Morgan (xrays-V10-07-02)
- Migrate to build to modular CMake API
24 February 21: D. Sawkey (xrays-V10-07-01)
- G4Scintillation. Remove deprecated optical commands.
11 February 21: D. Sawkey (xrays-V10-07-00)
- large cleaning (all files)
- remove commented out code
- add ProcessDescription and DumpInfo
- organize order of headers, remove and add as needed
- use constexpr for numbers
- replace G4PhysicsOrderedFreeVector with G4PhysicsFreeVector
5 October 20: D. Sawkey (xrays-V10-06-08)
- G4Cerenkov, G4Scintillation: apply clang-format style guidelines
@@ -56,7 +70,7 @@ committal in the CVS repository !
- G4SynchrotronRadiation, G4VTransitionRadiation - fixed deregistration
03 April 19: V. Ivanchenko (xrays-V10-05-01)
- G4SynchrotronRadiation, G4VTransitionRadiation - added
- G4SynchrotronRadiation, G4VTransitionRadiation - added
Register/DeRegister mechnism
11 March 19: D. Sawkey (xrays-V10-05-00)
@@ -89,7 +103,7 @@ committal in the CVS repository !
Thanks to Raphael Isemann for reporting this.
11 September 17: S.Y.Jun (xrays-V10-03-00)
- Change material property keys by the enum (index) type defined in
- Change material property keys by the enum (index) type defined in
G4MaterialPropertiesIndex
20 Jun 16: P. Gumplinger (xrays-V10-02-05)
@@ -126,7 +140,7 @@ committal in the CVS repository !
- G4ForwardXrayTR - fixed Coverity report (V.Grichine)
27 Oct 14: A.Dotti (xrays-V10-00-06)
- Address problem #1675, this requires re engineering of
- Address problem #1675, this requires re engineering of
all UI commands related to optical processes and created
in G4OpticalPhysics.
- Co-working tags: xrays-V10-00-06, op-V10-00-09, phys-ctor-em-V10-00-17
@@ -142,8 +156,8 @@ committal in the CVS repository !
- G4VXTRenergyLoss - fixed Coverity reports
01 Aug 14: V.Ivanchenko (xrays-V10-00-02)
- G4SynchrotronRadiation - H.Burkhardt extend model from e+, e- to be
universal - applicable for all relativistic charged particles
- G4SynchrotronRadiation - H.Burkhardt extend model from e+, e- to be
universal - applicable for all relativistic charged particles
07 Jan 14: P.Gumplinger (xrays-V10-00-01)
- make all static 'Set/Add/Remove' methods non-inline in G4Scintillation
@@ -168,12 +182,12 @@ committal in the CVS repository !
- G4Cerenkov - added BuildPhysicsTable method which is doing initialisation
as before but at the moment when material list is fully defined;
it is assumed that the list of materials is not changed for the next runs;
internal table has NULL pointer to PhysicsVector if material properties
internal table has NULL pointer to PhysicsVector if material properties
are not defined for a given material, this pointer is check in when step
limitation is computed.
limitation is computed.
28 May 13: P.Gumplinger (xrays-V09-06-03)
- G4Scintillation.cc: Fixed bug in G4Scintillation
- G4Scintillation.cc: Fixed bug in G4Scintillation
"ScintillationYieldByParticleType" mode to correctly produce photons for
nonlinear scintillators, accounting for variable particle step size in the
scintillator (dependent on G4 tracking and production cuts) and attempting
@@ -184,18 +198,18 @@ committal in the CVS repository !
13 May 13: P. Gumplinger (xrays-V09-06-02)
- G4Scintillation.cc give the YieldRatio priority in cases when the
ExcitationRatio is both 0.0 or 1.0; necessary because the defaults in
G4Scintillation.cc (1.0) and G4OpticalPhysics.cc (0.0) are inconsistent
G4Scintillation.cc (1.0) and G4OpticalPhysics.cc (0.0) are inconsistent
21 Feb 13: V.Ivanchenko (xrays-V09-06-01)
- G4VXTRenergyLoss, G4StrawTubeXTRadiator - use const declaration to
array of G4SandiaTable values
18 Feb 13: V.Ivanchenko (xrays-V09-06-00)
- G4SynchrotronRadiation, G4ForwardXrayTR - removed G4ThreadLocal
- G4SynchrotronRadiation, G4ForwardXrayTR - removed G4ThreadLocal
declarations
21 Sept 12: P.Gumplinger (xrays-V09-05-06)
- Remove what has now become an annoying NOTE warning in the constructor of
- Remove what has now become an annoying NOTE warning in the constructor of
G4Cerenkov
10 July 12: G.Cosmo (xrays-V09-05-05)
@@ -213,12 +227,12 @@ committal in the CVS repository !
- G4Cerenkov.hh, G4Scintillation.hh trying to fix Coverity warnings
08 February 12: V. Grichine (xrays-V09-05-01)
- G4SynchrotronRadiarion and G4SynchrotronRadiarionInMat was modified to
provide more realistic angualr distribution for secondary SR gammas
- G4SynchrotronRadiarion and G4SynchrotronRadiarionInMat was modified to
provide more realistic angualr distribution for secondary SR gammas
accordong to simplified dipole busted approach.
20 December 11: V. Grichine (xrays-V09-05-00)
- G4VXTRenergyLoss.cc and regular XTR radiators/models were updated for more
- G4VXTRenergyLoss.cc and regular XTR radiators/models were updated for more
accurate angular distribution of XTR
18 November 11: G.Folger (xrays-V09-04-10)
@@ -243,8 +257,8 @@ committal in the CVS repository !
and deallocate it directly inside class constructors/destructor.
30 July 11: V.Ivant (xrays-V09-04-05)
- G4SynchrotronRadiation, G4SynchrotronRadiationInMat - fixed
length of C-arrays for the interface with EM field (addressed
- G4SynchrotronRadiation, G4SynchrotronRadiationInMat - fixed
length of C-arrays for the interface with EM field (addressed
bug report #1236)
12 July 11: V.Ivant (xrays-V09-04-04)
@@ -256,7 +270,7 @@ committal in the CVS repository !
- G4TransparentRegXTRadiator - fixed new gcc-4.6.0 warnings
16 May 11: V.Ivant (xrays-V09-04-01)
- G4ForwardXrayTR, G4Scintillation, G4TransparentRegXTRadiator,
- G4ForwardXrayTR, G4Scintillation, G4TransparentRegXTRadiator,
G4VXTRenergyLoss - fixed gcc-4.6.0 warnings
05 May 11: V.Ivanchenko (xrays-V09-04-00)
@@ -280,7 +294,7 @@ committal in the CVS repository !
of Nuclear Science and Engineeering - MIT)
14 October 10: V. Ivanchenko (xrays-V09-03-02)
- G4SynchrotronRadiationInMat, G4SynchrotronRadiation,
- G4SynchrotronRadiationInMat, G4SynchrotronRadiation,
G4TransitionRadiation - added process sub-types
16 June 10: G. Cosmo (xrays-V09-03-01)
@@ -290,7 +304,7 @@ committal in the CVS repository !
- Scintillation rise time included, thanks to Martin Goettlich/DESY
29 July 09: P. Gumplinger (xrays-V09-02-00)
- Change IsApplicable for G4Cerenkov and G4Scintillation to
- Change IsApplicable for G4Cerenkov and G4Scintillation to
exclude short-lived particles.
14 November 08: P. Gumplinger (xrays-V09-01-06)
@@ -312,7 +326,7 @@ committal in the CVS repository !
tracking-V09-01-03 or newer is required.
04 July 08: P. Gumplinger (xrays-V09-01-03)
- In G4Scintillation and G4Cerenkov now
- In G4Scintillation and G4Cerenkov now
SetTouchableHandle(aStep.GetPreStepPoint()->GetTouchableHandle())
for the secondaries in the DoIt.
@@ -331,7 +345,7 @@ committal in the CVS repository !
01 February 08: V. Grichine
- G4BirkScintillation class was added. The class implements the scintillation
process with Birk's law
02 November 07: P. Gumplinger (xrays-V09-00-03)
- G4Cerenkov constructor add warning printout about the change
to G4VDiscreteProcess
@@ -344,13 +358,13 @@ committal in the CVS repository !
- G4VXTRenergyLoss: general cleanup of old comments;
removed all static members;
use verboseLevel variable to control cout
- G4XTRTransparentRegRadModel, G4XTRRegularRadModel,
- G4XTRTransparentRegRadModel, G4XTRRegularRadModel,
G4StrawTubeXTRadiator : cleanup, use verboseLevel to control cout
02 July 07: V.Ivant (xrays-V09-00-00)
- G4VXTRenergyLoss: fixed valgrind complains for wrong memory allocation
by removing internal initialisation of Sandia table but using Sandia
table from material
table from material
19 June 07: V.Ivant (xrays-V08-03-01)
- G4VXTRenergyLoss: restore version 1.34 after failing to clean it up
@@ -381,19 +395,19 @@ committal in the CVS repository !
20 Jan 06: V.Ivant (xrays-V08-00-00)
20 Jan 06: V. Grichine
- New algorithm for XTR angular distribution based on the transparent regular radiator
was developed. The method can help for more precise estimation of XTR angular
distribution needed in tracking applications of XTR detectors (ATLAS). The algorithm is
under futher testing.
was developed. The method can help for more precise estimation of XTR angular
distribution needed in tracking applications of XTR detectors (ATLAS). The algorithm is
under futher testing.
25 Aug 05: V.Ivant (xrays-V07-01-03)
- G4XTRTransparentRegRadModel: abs -> std::abs
- G4XTRTransparentRegRadModel: abs -> std::abs
15 Aug 05: V.Ivant (xrays-V07-01-02)
14 Oct 05: V. Grichine
- new XTR models were added with G4VXTRenergyLoss::fExitFlux=true for
the description of XTR after radiator. These are: G4XTRRegularRadModel,
G4XTRGammaRadModel, G4XTRTransparentRegRadModel. XTR process was
transformed to be discrete.
G4XTRGammaRadModel, G4XTRTransparentRegRadModel. XTR process was
transformed to be discrete.
17 Aug 05: P.Gumplinger (xrays-V07-01-01)
@@ -408,7 +422,7 @@ committal in the CVS repository !
- Change IsApplicable for G4Cerenkov to exclude 'chargedgeantino'
06 June 05: V.Ivant (xrays-V07-00-03)
- V.Grichine fix in G4TransparentRegXTRadiator - low limit of integration
- V.Grichine fix in G4TransparentRegXTRadiator - low limit of integration
over theta, which strongly effect the results for ALICE
27 May 05: V.Ivant (xrays-V07-00-02)
@@ -502,7 +516,7 @@ committal in the CVS repository !
particle.
09 may 02: P. Gumplinger (xrays-V04-00-02)
- changed method 'IsApplicable' for G4Scintillation to return .false. when it
- changed method 'IsApplicable' for G4Scintillation to return .false. when it
is called for an optical photon.
28 mar 02: G. Cosmo (xrays-V04-00-01)
@@ -511,10 +525,10 @@ committal in the CVS repository !
22 mar 02: V. Grichine (xrays-V04-00-00)
- new classes (G4VXTRenergyLoss,G4GammaXTRadiator and G4RegularXTRadiator) were
added for the description of X-ray transition radiation as continuous process.
12 nov 01: mma (xrays-V03-02-02)
- merge of 00a and 01
24 oct 01: mma (xrays-V03-02-01)
- modified G4ForwardXrayTR.cc for cuts per material.
Does NOT include mods in "xrays-V03-02-00a".
@@ -525,7 +539,7 @@ committal in the CVS repository !
17 sep 01: mma (xrays-V03-02-00)
- modifs in almost all classes for the migration of Materials to pure STL,
but backward compatible with g4rw
but backward compatible with g4rw
12 Nov 00: pg (xrays-V02-00-04)
- G4Cerenkov.cc: add check on CerenkovAngleIntegrals->IsFilledVectorExist()
@@ -537,29 +551,29 @@ committal in the CVS repository !
04 oct 00: pg (xrays-V02-00-02)
- G4Cerenkov.cc: calculate secondary position from aStep.GetDeltaPosition().
- G4Scintillation.cc: calculate secondary position from aStep.GetDeltaPosition().
11 aug 00: mma (xrays-V02-00-01)
03 aug 00: gc (xrays-V02-00-00r)
- G4Scintillation.cc: changed RandGauss to G4RandGauss for fixing
events' reproducibility problem.
24 may 00: mma (xrays-V01-01-02)
24 may 00: mma (xrays-V01-01-02)
27 apr 00 mma (em-V01-01-01)
- G4endl (dec/iso)
- G4endl (dec/iso)
26 apr 00 mma (em-V01-01-00)
- all EnergyLoss classes renamed G4V...
- all EnergyLoss classes renamed G4V...
Most classes in standard and muons affected.
- G4Muls moved in utils
- bugs fixe in MuPairProduction
- bugs fixe in MuPairProduction
- cowork with geant4-01-01-ref-02
02 mar 00 mma (em-V01-00-00)
- new G4VEnergyLoss class and related structure
- cowork with geant4-01-00-ref-06
10 nov 99 mma (em-V00-01-03)
- migration to STL: remove RWT hash dictionnary
@@ -23,9 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
////////////////////////////////////////////////////////////////////////
// Cerenkov Radiation Class Definition
////////////////////////////////////////////////////////////////////////
@@ -46,22 +43,19 @@
#ifndef G4Cerenkov_h
#define G4Cerenkov_h 1
#include <CLHEP/Units/SystemOfUnits.h>
#include "globals.hh"
#include "templates.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4ParticleMomentum.hh"
#include "G4Step.hh"
#include "G4VProcess.hh"
#include "G4OpticalPhoton.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4PhysicsTable.hh"
#include "G4ForceCondition.hh"
#include "G4GPILSelection.hh"
#include "G4MaterialPropertyVector.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4PhysicsOrderedFreeVector.hh"
#include "G4VProcess.hh"
class G4Material;
class G4ParticleDefinition;
class G4PhysicsTable;
class G4Step;
class G4Track;
class G4VParticleChange;
class G4Cerenkov : public G4VProcess
{
@@ -72,10 +66,8 @@ class G4Cerenkov : public G4VProcess
explicit G4Cerenkov(const G4Cerenkov& right);
private:
G4Cerenkov& operator=(const G4Cerenkov& right) = delete;
public:
G4bool IsApplicable(const G4ParticleDefinition& aParticleType) override;
// Returns true -> 'is applicable', for all charged particles
// except short-lived particles.
@@ -168,17 +160,21 @@ class G4Cerenkov : public G4VProcess
const G4Material* aMaterial,
G4MaterialPropertyVector* Rindex) const;
void DumpInfo() const override {ProcessDescription(G4cout);};
void ProcessDescription(std::ostream& out) const override;
protected:
G4PhysicsTable* thePhysicsTable;
private:
G4bool fTrackSecondariesFirst;
G4double fMaxBetaChange;
G4int fMaxPhotons;
G4int fNumPhotons;
G4bool fStackingFlag;
G4bool fTrackSecondariesFirst;
G4int fNumPhotons;
};
inline G4bool G4Cerenkov::GetTrackSecondariesFirst() const
@@ -23,8 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// G4ForwardXrayTR
//
// Class for description
@@ -42,149 +40,117 @@
#ifndef G4FORWARDXRAYTR_H
#define G4FORWARDXRAYTR_H
#include "globals.hh"
#include "templates.hh"
#include "geomdefs.hh"
#include "Randomize.hh"
#include "G4Step.hh"
#include "G4VDiscreteProcess.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4LogicalBorderSurface.hh"
#include "G4LogicalSkinSurface.hh"
#include "G4OpticalSurface.hh"
#include "G4OpticalPhoton.hh"
#include "G4TransportationManager.hh"
#include "G4Track.hh"
#include "G4TransitionRadiation.hh"
#include "G4PhysicsTable.hh"
#include "G4Gamma.hh"
#include "G4PhysicsLogVector.hh"
#include "G4VParticleChange.hh"
class G4ParticleDefinition;
class G4PhysicsTable;
class G4PhysicsLogVector;
class G4ForwardXrayTR : public G4TransitionRadiation
{
public:
public:
explicit G4ForwardXrayTR(const G4String& matName1, const G4String& matName2,
const G4String& processName = "XrayTR");
// Constructors
explicit G4ForwardXrayTR(const G4String& processName = "XrayTR");
explicit G4ForwardXrayTR( const G4String& matName1, // G4Material* pMat1,
const G4String& matName2, // G4Material* pMat2,
const G4String& processName="XrayTR" );
explicit G4ForwardXrayTR( const G4String& processName="XrayTR" );
~G4ForwardXrayTR();
// Destructor // virtual
G4ForwardXrayTR(const G4ForwardXrayTR& right) = delete;
G4ForwardXrayTR& operator=(const G4ForwardXrayTR& right) = delete;
virtual ~G4ForwardXrayTR();
/////////////////////// Methods /////////////////////////////////
/////////////////////// Methods /////////////////////////////////
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
void BuildXrayTRtables();
G4double GetMeanFreePath(const G4Track&, G4double,
G4ForceCondition* condition) override;
G4ForceCondition* condition) override;
G4VParticleChange* PostStepDoIt( const G4Track& aTrack,
const G4Step& aStep ) override;
G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
G4double GetEnergyTR(G4int iMat, G4int jMat, G4int iTkin) const;
G4double GetThetaTR(G4int iMat, G4int jMat, G4int iTkin) const;
G4double GetThetaTR(G4int iMat, G4int jMat, G4int iTkin) const;
///////////////////// Angle distribution /////////////////////////////
//
///////////////////// Angle distribution /////////////////////////////
G4double SpectralAngleTRdensity( G4double energy,
G4double varAngle ) const override;
G4double SpectralAngleTRdensity(G4double energy,
G4double varAngle) const override;
G4double AngleDensity( G4double energy,
G4double varAngle ) const;
G4double AngleDensity(G4double energy, G4double varAngle) const;
G4double EnergyInterval( G4double energy1,
G4double energy2,
G4double varAngle ) const;
G4double EnergyInterval(G4double energy1, G4double energy2,
G4double varAngle) const;
G4double AngleSum( G4double varAngle1,
G4double varAngle2 ) const;
G4double AngleSum(G4double varAngle1, G4double varAngle2) const;
///////////////////////// Energy distribution ///////////////////////////////
///////////////////////// Energy distribution ///////////////////////////////
G4double SpectralDensity( G4double energy,
G4double x ) const;
G4double SpectralDensity(G4double energy, G4double x) const;
G4double AngleInterval( G4double energy,
G4double varAngle1,
G4double varAngle2 ) const;
G4double AngleInterval(G4double energy, G4double varAngle1,
G4double varAngle2) const;
G4double EnergySum( G4double energy1,
G4double energy2 ) const;
G4double EnergySum(G4double energy1, G4double energy2) const;
/////////////////////////// Access functions ////////////////////////////
/////////////////////////// Access functions ////////////////////////////
G4PhysicsTable* GetAngleDistrTable();
G4PhysicsTable* GetEnergyDistrTable();
static G4int GetSympsonNumber();
static G4int GetBinTR();
static G4int GetSympsonNumber();
static G4int GetBinTR();
static G4double GetMinProtonTkin();
static G4double GetMaxProtonTkin();
static G4int GetTotBin();
static G4int GetTotBin();
protected: // for access from X-ray TR fast simulation models
static constexpr G4double fTheMinEnergyTR =
1. * CLHEP::keV; // static min TR energy
static constexpr G4double fTheMaxEnergyTR =
100. * CLHEP::keV; // static max TR energy
static constexpr G4double fTheMaxAngle = 1.0e-3; // max theta of TR quanta
static constexpr G4double fTheMinAngle = 5.0e-6; // min theta of TR quanta
static constexpr G4double fMinProtonTkin =
100. * CLHEP::GeV; // min Tkin of proton in tables
static constexpr G4double fMaxProtonTkin =
100. * CLHEP::TeV; // max Tkin of proton in tables
static constexpr G4double fPlasmaCof =
4.0 * CLHEP::pi * CLHEP::fine_structure_const * CLHEP::hbarc *
CLHEP::hbarc * CLHEP::hbarc /
CLHEP::electron_mass_c2; // physical consts for plasma energy
static constexpr G4double fCofTR = CLHEP::fine_structure_const / CLHEP::pi;
protected: // for access from X-ray TR fast simulation models
static constexpr G4int fSympsonNumber =
100; // Accuracy of Sympson integration
static constexpr G4int fBinTR = 50; // number of bins in TR vectors
static constexpr G4int fTotBin = 50; // number of bins in log scale
// private : /////////////// Data members ///////////////////////////
const std::vector<G4double>* fGammaCutInKineticEnergy;
// TR photon cut in energy array
G4ParticleDefinition* fPtrGamma; // pointer to TR photon
G4ParticleDefinition* fPtrGamma; // pointer to TR photon
const std::vector<G4double>* fGammaCutInKineticEnergy;
// TR photon cut in energy array
G4double fGammaTkinCut; // Tkin cut of TR photon in current mat.
G4PhysicsTable* fAngleDistrTable;
G4PhysicsTable* fEnergyDistrTable;
G4PhysicsLogVector* fProtonEnergyVector;
static G4int fSympsonNumber; // Accuracy of Sympson integration
static G4double fTheMinEnergyTR; // static min TR energy
static G4double fTheMaxEnergyTR; // static max TR energy
G4double fMinEnergyTR; // min TR energy in material
G4double fMaxEnergyTR; // max TR energy in material
static G4double fTheMaxAngle; // max theta of TR quanta
static G4double fTheMinAngle; // max theta of TR quanta
G4double fMaxThetaTR; // max theta of TR quanta
static G4int fBinTR; // number of bins in TR vectors
static G4double fMinProtonTkin; // min Tkin of proton in tables
static G4double fMaxProtonTkin; // max Tkin of proton in tables
static G4int fTotBin; // number of bins in log scale
G4double fGamma; // current Lorentz factor
static G4double fPlasmaCof; // physical consts for plasma energy
static G4double fCofTR;
G4double fSigma1; // plasma energy Sq of matter1
G4double fSigma2; // plasma energy Sq of matter2
private:
// Operators
G4ForwardXrayTR(const G4ForwardXrayTR& right) = delete;
G4ForwardXrayTR& operator=(const G4ForwardXrayTR& right) = delete;
// G4bool operator==(const G4ForwardXrayTR& right)const;
// G4bool operator!=(const G4ForwardXrayTR& right)const;
}; // end of G4ForwardXrayTR class ---------------------------
#endif // G4FORWARDXRAYTR_H
G4PhysicsTable* fAngleDistrTable;
G4PhysicsTable* fEnergyDistrTable;
G4PhysicsLogVector* fProtonEnergyVector;
G4double fMinEnergyTR; // min TR energy in material
G4double fMaxEnergyTR; // max TR energy in material
G4double fMaxThetaTR; // max theta of TR quanta
G4double fGamma; // current Lorentz factor
G4double fGammaTkinCut; // Tkin cut of TR photon in current mat.
G4double fSigma1; // plasma energy Sq of matter1
G4double fSigma2; // plasma energy Sq of matter2
};
#endif // G4FORWARDXRAYTR_H
@@ -23,13 +23,10 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
// Rough process describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are distributed according to gamma
//
// Rough process describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are distributed according to gamma
// distribution. x are thicknesses of plates or gas gaps:
//
// p(x) = (alpha/<x>)^alpha * x^(alpha-1) * std::exp(-alpha*x/<x>) / G(alpha)
@@ -41,42 +38,32 @@
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 21.01.02 V. Grichine, first version
//
// History:
// 21.01.02 V. Grichine, first version
//
#ifndef G4GammaXTRadiator_h
#define G4GammaXTRadiator_h 1
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4GammaXTRadiator : public G4VXTRenergyLoss
{
public:
public:
explicit G4GammaXTRadiator(G4LogicalVolume* anEnvelope, G4double, G4double,
G4Material*, G4Material*, G4double, G4double,
G4int,
const G4String& processName = "XTRgammaRadiator");
~G4GammaXTRadiator();
explicit G4GammaXTRadiator (G4LogicalVolume *anEnvelope,
G4double,G4double,
G4Material*,G4Material*,
G4double,G4double,G4int,
const G4String & processName = "XTRgammaRadiator");
~G4GammaXTRadiator ();
// Pure virtual function from base class
G4double GetStackFactor( G4double energy, G4double gamma,
G4double varAngle) override;
private:
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
};
#endif
@@ -23,45 +23,41 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
// Process describing a radiator of X-ray transition radiation.
//
// Process describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are fixed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 16.01.02 V. Grichine, first version
//
//
// History:
// 16.01.02 V. Grichine, first version
//
#ifndef G4RegularXTRadiator_h
#define G4RegularXTRadiator_h 1
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4RegularXTRadiator : public G4VXTRenergyLoss
{
public:
explicit G4RegularXTRadiator (G4LogicalVolume *anEnvelope,
G4Material*,G4Material*,
G4double,G4double,G4int,
const G4String & processName = "XTRegularRadiator");
~G4RegularXTRadiator ();
public:
explicit G4RegularXTRadiator(
G4LogicalVolume* anEnvelope, G4Material*, G4Material*, G4double, G4double,
G4int, const G4String& processName = "XTRegularRadiator");
~G4RegularXTRadiator();
G4double SpectralXTRdEdx(G4double energy) override;
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
G4double GetStackFactor( G4double energy, G4double gamma,
G4double varAngle) override;
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
};
#endif
@@ -23,9 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
////////////////////////////////////////////////////////////////////////
// Scintillation Light Class Definition
////////////////////////////////////////////////////////////////////////
@@ -54,21 +51,13 @@
#define G4Scintillation_h 1
#include "globals.hh"
#include "templates.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4ThreeVector.hh"
#include "G4ParticleMomentum.hh"
#include "G4Step.hh"
#include "G4VRestDiscreteProcess.hh"
#include "G4OpticalPhoton.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4PhysicsTable.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4PhysicsOrderedFreeVector.hh"
#include "G4EmSaturation.hh"
#include "G4OpticalPhoton.hh"
#include "G4VRestDiscreteProcess.hh"
class G4PhysicsTable;
class G4Step;
class G4Track;
// Class Description:
// RestDiscrete Process - Generation of Scintillation Photons.
@@ -82,11 +71,9 @@ class G4Scintillation : public G4VRestDiscreteProcess
G4ProcessType type = fElectromagnetic);
~G4Scintillation();
private:
G4Scintillation(const G4Scintillation& right) = delete;
G4Scintillation& operator=(const G4Scintillation& right) = delete;
public:
// G4Scintillation Process has both PostStepDoIt (for energy
// deposition of particles in flight) and AtRestDoIt (for energy
// given to the medium by particles at rest)
@@ -95,6 +82,9 @@ class G4Scintillation : public G4VRestDiscreteProcess
// Returns true -> 'is applicable', for any particle type except
// for an 'opticalphoton' and for short-lived particles
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override {ProcessDescription(G4cout);};
void BuildPhysicsTable(const G4ParticleDefinition& aParticleType) override;
// Build table at the right time
@@ -117,20 +107,16 @@ class G4Scintillation : public G4VRestDiscreteProcess
G4VParticleChange* AtRestDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
G4double GetScintillationYieldByParticleType(const G4Track& aTrack,
const G4Step& aStep);
// Returns the number of scintillation photons calculated when
// scintillation depends on the particle type and energy
// deposited (includes nonlinear dependendency)
// DEPRECATED: to be removed in the next major release. Use the
// following instead.
G4double GetScintillationYieldByParticleType(const G4Track& aTrack,
const G4Step& aStep,
G4double& yield1,
G4double& yield2,
G4double& yield3);
// allow multiple time constants with scint by particle type
// Returns the number of scintillation photons calculated when
// scintillation depends on the particle type and energy
// deposited (includes nonlinear dependendency) and updates the
// yields for each channel
void SetTrackSecondariesFirst(const G4bool state);
// If set, the primary particle tracking is interrupted and any
@@ -142,7 +128,7 @@ class G4Scintillation : public G4VRestDiscreteProcess
void SetFiniteRiseTime(const G4bool state);
// If set, the G4Scintillation process expects the user to have
// set the constant material property FAST/SLOWSCINTILLATIONRISETIME.
// set the constant material property SCINTILLATIONRISETIME{1,2,3}.
G4bool GetFiniteRiseTime() const;
// Returns the boolean flag for a finite scintillation rise time.
@@ -155,29 +141,6 @@ class G4Scintillation : public G4VRestDiscreteProcess
G4double GetScintillationYieldFactor() const;
// Returns the photon yield factor.
void SetScintillationExcitationRatio(const G4double ratio);
// Called to set the scintillation excitation ratio, needed when
// the scintillation level excitation is different for different
// types of particles. This overwrites the YieldRatio obtained
// from the G4MaterialPropertiesTable.
// DEPRECATED and will be removed in the next major release. Set
// the yields for different particles in material property table instead.
G4double GetScintillationExcitationRatio() const;
// Returns the scintillation level excitation ratio.
// DEPRECATED and will be removed in the next major release. Set
// the yields for different particles in material property table instead.
G4PhysicsTable* GetFastIntegralTable() const;
// Returns the address of the fast scintillation integral table.
// DEPRECATED and will be removed in the next major release. Use
// GetIntegralTable1() instead.
G4PhysicsTable* GetSlowIntegralTable() const;
// Returns the address of the slow scintillation integral table.
// DEPRECATED and will be removed in the next major release. Use
// GetIntegralTable3() instead.
G4PhysicsTable* GetIntegralTable1() const;
// Returns the address of scintillation integral table #1.
@@ -204,12 +167,6 @@ class G4Scintillation : public G4VRestDiscreteProcess
// Return the boolean that determines the method of scintillation
// production
void SetEnhancedTimeConstants(G4bool);
G4bool GetEnhancedTimeConstants() const;
// Starting with 10.7.beta, enable 3 time constants, either for
// all particles or by particle type. The names of the material
// properties have been generalized from FAST and SLOW to 1, 2, 3.
void SetScintillationTrackInfo(const G4bool trackType);
// Call by the user to set the G4ScintillationTrackInformation
// to scintillation photon track
@@ -230,21 +187,23 @@ class G4Scintillation : public G4VRestDiscreteProcess
void DumpPhysicsTable() const;
// Prints the fast and slow scintillation integral tables.
protected:
private:
G4PhysicsTable* fIntegralTable1;
G4PhysicsTable* fIntegralTable2;
G4PhysicsTable* fIntegralTable3;
private:
G4bool fTrackSecondariesFirst;
G4bool fFiniteRiseTime;
G4double fYieldFactor;
G4double fExcitationRatio;
G4EmSaturation* fEmSaturation;
const G4ParticleDefinition* opticalphoton =
G4OpticalPhoton::OpticalPhotonDefinition();
G4int fNumPhotons;
G4bool fScintillationByParticleType;
G4bool fScintillationTrackInfo;
G4bool fStackingFlag;
G4int fNumPhotons;
G4bool fEnhancedTimeConstants;
G4bool fTrackSecondariesFirst;
G4bool fFiniteRiseTime;
#ifdef G4DEBUG_SCINTILLATION
G4double ScintTrackEDep, ScintTrackYield;
@@ -256,9 +215,6 @@ class G4Scintillation : public G4VRestDiscreteProcess
// emission time distribution when there is a finite rise time
G4double sample_time(G4double tau1, G4double tau2);
G4EmSaturation* fEmSaturation;
G4ParticleDefinition* opticalphoton =
G4OpticalPhoton::OpticalPhotonDefinition();
};
////////////////////
@@ -285,38 +241,6 @@ inline G4bool G4Scintillation::GetFiniteRiseTime() const
return fFiniteRiseTime;
}
inline void G4Scintillation::SetScintillationYieldFactor(
const G4double yieldfactor)
{
fYieldFactor = yieldfactor;
}
inline G4double G4Scintillation::GetScintillationYieldFactor() const
{
return fYieldFactor;
}
inline void G4Scintillation::SetScintillationExcitationRatio(
const G4double ratio)
{
fExcitationRatio = ratio;
}
inline G4double G4Scintillation::GetScintillationExcitationRatio() const
{
return fExcitationRatio;
}
inline G4PhysicsTable* G4Scintillation::GetSlowIntegralTable() const
{
return fIntegralTable3;
}
inline G4PhysicsTable* G4Scintillation::GetFastIntegralTable() const
{
return fIntegralTable1;
}
inline G4PhysicsTable* G4Scintillation::GetIntegralTable1() const
{
return fIntegralTable1;
@@ -349,16 +273,6 @@ inline G4bool G4Scintillation::GetScintillationByParticleType() const
return fScintillationByParticleType;
}
inline void G4Scintillation::SetEnhancedTimeConstants(G4bool val)
{
fEnhancedTimeConstants = val;
}
inline G4bool G4Scintillation::GetEnhancedTimeConstants() const
{
return fEnhancedTimeConstants;
}
inline void G4Scintillation::SetScintillationTrackInfo(const G4bool trackType)
{
fScintillationTrackInfo = trackType;
@@ -23,8 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// Author : Valentin Libioulle valentin.libioulle@usherbrooke.ca (3IT - GRAMS)
//
//---------------------------------------------------------------
@@ -40,6 +38,7 @@
#ifndef G4SCINTILLATIONTRACKINFORMATION_H
#define G4SCINTILLATIONTRACKINFORMATION_H
#include "G4Allocator.hh"
#include "G4VUserTrackInformation.hh"
// Represents the scintillation type used to create the track (opticalphoton).
@@ -91,8 +90,6 @@ class G4ScintillationTrackInformation : public G4VUserTrackInformation
// Inline methods
///
#include "G4Allocator.hh"
// Forward declaration for the Allocator
class G4ScintillationTrackInformation;
@@ -23,58 +23,57 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
// Process describing a straw tube radiator of X-ray transition radiation.
//
// Process describing a straw tube radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are gamma distributed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
//
// History:
// 22.04.05 V. Grichine, first version
// 22.04.05 V. Grichine, first version
// 28.09.07, V.Ivanchenko general cleanup without change of algorithms
//
#ifndef G4StrawTubeXTRadiator_h
#define G4StrawTubeXTRadiator_h 1
#include <complex>
#include "globals.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4SandiaTable;
class G4StrawTubeXTRadiator : public G4VXTRenergyLoss
{
public:
explicit G4StrawTubeXTRadiator (G4LogicalVolume* anEnvelope, G4Material*,
G4Material*, G4double,G4double,G4Material*,G4bool unishut = false,
const G4String & processName = "StrawTubeXTRadiator");
virtual ~G4StrawTubeXTRadiator ();
public:
explicit G4StrawTubeXTRadiator(
G4LogicalVolume* anEnvelope, G4Material*, G4Material*, G4double, G4double,
G4Material*, G4bool unishut = false,
const G4String& processName = "StrawTubeXTRadiator");
~G4StrawTubeXTRadiator();
// Auxiliary functions for plate/gas material parameters
G4double GetMediumFormationZone(G4double, G4double, G4double);
void ComputeMediumPhotoAbsCof();
G4double GetMediumLinearPhotoAbs(G4double);
G4complex GetMediumComplexFZ(G4double, G4double, G4double);
G4double GetMediumFormationZone(G4double,G4double,G4double) ;
void ComputeMediumPhotoAbsCof() ;
G4double GetMediumLinearPhotoAbs(G4double) ;
G4complex GetMediumComplexFZ(G4double,G4double,G4double) ;
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
protected:
G4int fMatIndex3;
G4double fSigma3;
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
protected:
G4SandiaTable* fMediumPhotoAbsCof;
G4double fSigma3;
G4int fMatIndex3;
};
#endif
@@ -23,107 +23,91 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
//
//
// History:
// 21-5-98 1 version , V. Grichine
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
// 23-05-06, H. Burkhardt: Energy spectrum from function rather than table
//
//
// ------------------------------------------------------------
#ifndef G4SynchrotronRadiation_h
#define G4SynchrotronRadiation_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "Randomize.hh"
#include "G4VDiscreteProcess.hh"
#include "G4TransportationManager.hh"
#include "G4FieldManager.hh"
#include "G4Field.hh"
#include "G4ThreeVector.hh"
#include "G4PropagatorInField.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ThreeVector.hh"
#include "G4Track.hh"
#include "G4VDiscreteProcess.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
class G4VEmAngularDistribution;
class G4LossTableManager;
class G4ParticleDefinition;
class G4PropagatorInField;
class G4VEmAngularDistribution;
class G4SynchrotronRadiation : public G4VDiscreteProcess
{
public:
public:
explicit G4SynchrotronRadiation(const G4String& pName = "SynRad",
G4ProcessType type = fElectromagnetic);
G4ProcessType type = fElectromagnetic);
virtual ~G4SynchrotronRadiation();
virtual G4double GetMeanFreePath( const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition ) override;
G4SynchrotronRadiation& operator=(const G4SynchrotronRadiation& right) =
delete;
G4SynchrotronRadiation(const G4SynchrotronRadiation&) = delete;
virtual G4VParticleChange *PostStepDoIt( const G4Track& track,
const G4Step& Step ) override;
virtual G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
G4double GetPhotonEnergy( const G4Track& trackData,
const G4Step& stepData );
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& Step) override;
G4double GetRandomEnergySR( G4double, G4double, G4double );
G4double GetPhotonEnergy(const G4Track& trackData, const G4Step& stepData);
G4double GetRandomEnergySR(G4double, G4double, G4double);
G4double InvSynFracInt(G4double x);
G4double Chebyshev(G4double a,G4double b,const G4double c[],
G4int n, G4double x);
G4double Chebyshev(G4double a, G4double b, const G4double c[], G4int n,
G4double x);
virtual G4bool IsApplicable(const G4ParticleDefinition&) override;
virtual void BuildPhysicsTable(const G4ParticleDefinition& ) override;
virtual void PrintInfoDefinition();
virtual void BuildPhysicsTable(const G4ParticleDefinition&) override;
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
void SetAngularGenerator(G4VEmAngularDistribution* p);
private:
G4SynchrotronRadiation &
operator=(const G4SynchrotronRadiation &right);
G4SynchrotronRadiation(const G4SynchrotronRadiation&);
G4LossTableManager* theManager;
G4VEmAngularDistribution* genAngle;
G4ParticleDefinition* theGamma;
private:
G4LossTableManager* theManager;
G4VEmAngularDistribution* genAngle;
G4ParticleDefinition* theGamma;
G4PropagatorInField* fFieldPropagator;
G4bool FirstTime;
G4bool FirstTime1;
};
////////////////////////// INLINE METHODS /////////////////////////////
inline G4double
G4SynchrotronRadiation::Chebyshev(G4double a, G4double b, const G4double c[],
G4int n, G4double x)
inline G4double G4SynchrotronRadiation::Chebyshev(G4double a, G4double b,
const G4double c[], G4int n,
G4double x)
{
G4double y;
G4double y2=2.0*(y=(2.0*x-a-b)/(b-a)); // Change of variable.
G4double d=0.,dd=0.;
for (G4int j=n-1;j>=1;--j) // Clenshaw's recurrence.
{ G4double sv=d;
d=y2*d-dd+c[j];
dd=sv;
G4double y2 = 2.0 * (y = (2.0 * x - a - b) / (b - a)); // Change of variable.
G4double d = 0., dd = 0.;
for(G4int j = n - 1; j >= 1; --j) // Clenshaw's recurrence.
{
G4double sv = d;
d = y2 * d - dd + c[j];
dd = sv;
}
return y*d-dd+0.5*c[0];
return y * d - dd + 0.5 * c[0];
}
#endif // end of G4SynchrotronRadiation.hh
@@ -23,133 +23,121 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
//
//
// History:
// History:
// 21-5-98 1 version , V. Grichine
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
// 19-05-06, V.Ivanchenko rename from G4SynchrotronRadiation
//
//
// ------------------------------------------------------------
#ifndef G4SynchrotronRadiationInMat_h
#define G4SynchrotronRadiationInMat_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "Randomize.hh"
#include "G4VDiscreteProcess.hh"
#include "G4TransportationManager.hh"
#include "G4FieldManager.hh"
#include "G4Field.hh"
#include "G4ThreeVector.hh"
#include "G4PropagatorInField.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4PhysicsTable.hh"
#include "G4Gamma.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PhysicsTable.hh"
#include "G4Positron.hh"
#include "G4Step.hh"
#include "G4ThreeVector.hh"
#include "G4Track.hh"
#include "G4TransportationManager.hh"
#include "G4VDiscreteProcess.hh"
#include "G4VParticleChange.hh"
class G4ParticleDefinition;
class G4PropagatorInField;
class G4SynchrotronRadiationInMat : public G4VDiscreteProcess
{
public:
public:
explicit G4SynchrotronRadiationInMat(
const G4String& processName = "SynchrotronRadiation",
G4ProcessType type = fElectromagnetic);
explicit G4SynchrotronRadiationInMat(const G4String& processName =
"SynchrotronRadiation",
G4ProcessType type = fElectromagnetic);
~G4SynchrotronRadiationInMat();
virtual ~G4SynchrotronRadiationInMat();
private:
G4SynchrotronRadiationInMat &
operator=(const G4SynchrotronRadiationInMat &right) = delete;
G4SynchrotronRadiationInMat& operator=(
const G4SynchrotronRadiationInMat& right) = delete;
G4SynchrotronRadiationInMat(const G4SynchrotronRadiationInMat&) = delete;
public: ///////////////// Post Step functions //////////////////////////
G4double GetMeanFreePath(const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition) override;
G4double GetMeanFreePath( const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition ) override;
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& Step) override;
G4VParticleChange *PostStepDoIt( const G4Track& track,
const G4Step& Step ) override;
G4double GetPhotonEnergy(const G4Track& trackData, const G4Step& stepData);
G4double GetPhotonEnergy( const G4Track& trackData,
const G4Step& stepData );
G4double GetRandomEnergySR(G4double, G4double);
G4double GetRandomEnergySR( G4double, G4double );
G4double GetProbSpectrumSRforInt(G4double);
G4double GetIntProbSR(G4double);
G4double GetProbSpectrumSRforInt( G4double );
G4double GetIntProbSR( G4double );
G4double GetProbSpectrumSRforEnergy(G4double);
G4double GetEnergyProbSR(G4double);
G4double GetProbSpectrumSRforEnergy( G4double );
G4double GetEnergyProbSR( G4double );
G4double GetIntegrandForAngleK( G4double );
G4double GetAngleK( G4double );
G4double GetAngleNumberAtGammaKsi( G4double );
G4double GetIntegrandForAngleK(G4double);
G4double GetAngleK(G4double);
G4double GetAngleNumberAtGammaKsi(G4double);
G4bool IsApplicable(const G4ParticleDefinition&) override;
static G4double GetLambdaConst();
static G4double GetEnergyConst();
void SetRootNumber(G4int rn){ fRootNumber = rn; };
void SetVerboseLevel(G4int v){ fVerboseLevel = v; };
void SetKsi(G4double ksi){ fKsi = ksi; };
void SetEta(G4double eta){ fEta = eta; };
void SetPsiGamma(G4double psg){ fPsiGamma = psg; };
void SetOrderAngleK(G4double ord){ fOrderAngleK = ord; }; // should be 1/3 or 2/3
void SetRootNumber(G4int rn) { fRootNumber = rn; };
void SetVerboseLevel(G4int v) { fVerboseLevel = v; };
void SetKsi(G4double ksi) { fKsi = ksi; };
void SetEta(G4double eta) { fEta = eta; };
void SetPsiGamma(G4double psg) { fPsiGamma = psg; };
void SetOrderAngleK(G4double ord)
{
fOrderAngleK = ord;
}; // should be 1/3 or 2/3
private:
private:
// Constant for calculation of mean free path
// sqrt(3.) = 1.73...
static constexpr G4double fLambdaConst =
1.73205080756887729352 * CLHEP::electron_mass_c2 /
(2.5 * CLHEP::fine_structure_const * CLHEP::eplus * ::CLHEP::c_light);
static const G4double fLambdaConst;
// Constant for calculation of characterictic energy
static constexpr G4double fEnergyConst =
1.5 * CLHEP::c_light * CLHEP::c_light * CLHEP::eplus * CLHEP::hbar_Planck /
CLHEP::electron_mass_c2;
static const G4double fEnergyConst;
static const G4double fIntegralProbabilityOfSR[200];
const G4double
LowestKineticEnergy; // low energy limit of the cross-section formula
G4double CutInRange;
// Array of integral probability of synchrotron photons:
// the corresponding energy = 0.0001*i*i*(characteristic energy)
static const G4double fIntegralProbabilityOfSR[200];
const G4ParticleDefinition* theGamma;
const G4ParticleDefinition* theElectron;
const G4ParticleDefinition* thePositron;
G4PropagatorInField* fFieldPropagator;
const G4double
LowestKineticEnergy; // low energy limit of the cross-section formula
G4double CutInRange;
G4double GammaCutInKineticEnergyNow;
G4double ElectronCutInKineticEnergyNow;
G4double PositronCutInKineticEnergyNow;
G4double ParticleCutInKineticEnergyNow;
G4double fAlpha;
G4int fRootNumber;
G4double fKsi; // omega/omega_c
G4double fPsiGamma; // Psi-angle*gamma
G4double fEta; //
G4double fOrderAngleK; // 1/3 or 2/3
G4int fVerboseLevel;
G4PropagatorInField* fFieldPropagator;
G4double fKsi; // omega/omega_c
G4double fPsiGamma; // Psi-angle*gamma
G4double fEta; //
G4double fOrderAngleK; // 1/3 or 2/3
G4int fRootNumber;
G4int fVerboseLevel;
};
#endif // end of G4SynchrotronRadiationInMat.hh
@@ -23,9 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4TransitionRadiation -- header file
//
// Class for description of transition radiation generated
// by charged particle crossed interface between material 1
// and material 2 (1 -> 2). Transition radiation could be of kind:
@@ -34,10 +31,7 @@
// - X-ray forward (for relativistic case Tkin/mass >= 10^2)
//
// GEANT 4 class header file --- Copyright CERN 1995
// CERB Geneva Switzerland
//
// for information related to this code, please, contact
// CERN, CN Division, ASD Group
// History:
// 18.12.97, V. Grichine (Vladimir.Grichine@cern.ch)
// 02.02.00, V.Grichine, new data fEnergy and fVarAngle for double
@@ -48,81 +42,71 @@
#ifndef G4TransitionRadiation_h
#define G4TransitionRadiation_h
#include "globals.hh"
#include "G4ParticleDefinition.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4VDiscreteProcess.hh"
#include "G4Material.hh"
#include "G4VParticleChange.hh"
class G4TransitionRadiation : public G4VDiscreteProcess
class G4TransitionRadiation : public G4VDiscreteProcess
{
public:
public:
explicit G4TransitionRadiation(const G4String& processName = "TR",
G4ProcessType type = fElectromagnetic);
explicit G4TransitionRadiation( const G4String& processName = "TR",
G4ProcessType type = fElectromagnetic) ;
virtual ~G4TransitionRadiation();
virtual ~G4TransitionRadiation() ;
G4TransitionRadiation(const G4TransitionRadiation& right) = delete;
G4TransitionRadiation& operator=(const G4TransitionRadiation& right) = delete;
// Methods
G4bool IsApplicable(const G4ParticleDefinition& aParticleType) override;
virtual G4double GetMeanFreePath(const G4Track&, G4double,
G4ForceCondition* condition) override;
G4ForceCondition* condition) override;
virtual G4VParticleChange* PostStepDoIt(const G4Track&,
virtual G4VParticleChange* PostStepDoIt(const G4Track&,
const G4Step&) override;
virtual
G4double SpectralAngleTRdensity( G4double energy,
G4double varAngle ) const = 0 ;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
G4double IntegralOverEnergy( G4double energy1,
G4double energy2,
G4double varAngle ) const ;
virtual G4double SpectralAngleTRdensity(G4double energy,
G4double varAngle) const = 0;
G4double IntegralOverAngle( G4double energy,
G4double varAngle1,
G4double varAngle2 ) const ;
G4double IntegralOverEnergy(G4double energy1, G4double energy2,
G4double varAngle) const;
G4double AngleIntegralDistribution( G4double varAngle1,
G4double varAngle2 ) const ;
G4double IntegralOverAngle(G4double energy, G4double varAngle1,
G4double varAngle2) const;
G4double EnergyIntegralDistribution( G4double energy1,
G4double energy2 ) const ;
G4double AngleIntegralDistribution(G4double varAngle1,
G4double varAngle2) const;
G4double EnergyIntegralDistribution(G4double energy1, G4double energy2) const;
// Access functions
protected :
G4int fMatIndex1 ; // index of the 1st material
G4int fMatIndex2 ; // index of the 2nd material
// private :
G4double fGamma ;
G4double fEnergy ;
G4double fVarAngle ;
protected:
// Local constants
static const G4int fSympsonNumber ; // Accuracy of Sympson integration 10
static const G4int fGammaNumber ; // = 15
static const G4int fPointNumber ; // = 100
// Accuracy of Sympson integration
static constexpr G4int fSympsonNumber = 100;
static constexpr G4int fGammaNumber = 15;
static constexpr G4int fPointNumber = 100;
G4double fMinEnergy ; // min TR energy
G4double fMaxEnergy ; // max TR energy
G4double fMaxTheta ; // max theta of TR quanta
G4double fGamma;
G4double fEnergy;
G4double fVarAngle;
G4double fSigma1 ; // plasma energy Sq of matter1
G4double fSigma2 ; // plasma energy Sq of matter2
G4double fMinEnergy; // min TR energy
G4double fMaxEnergy; // max TR energy
G4double fMaxTheta; // max theta of TR quanta
private:
// Operators
G4TransitionRadiation(const G4TransitionRadiation& right) = delete;
G4TransitionRadiation&
operator=(const G4TransitionRadiation& right) = delete;
G4double fSigma1; // plasma energy Sq of matter1
G4double fSigma2; // plasma energy Sq of matter2
G4int fMatIndex1; // index of the 1st material
G4int fMatIndex2; // index of the 2nd material
};
#endif // G4TransitionRadiation_h
#endif // G4TransitionRadiation_h
@@ -23,46 +23,43 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
// Process describing a radiator of X-ray transition radiation.
//
// Process describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are fixed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
//
// History:
//
// 05.04.05 V. Grichine, first version
// 05.04.05 V. Grichine, first version
//
#ifndef G4TransparentRegXTRadiator_h
#define G4TransparentRegXTRadiator_h 1
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4TransparentRegXTRadiator : public G4VXTRenergyLoss
{
public:
explicit G4TransparentRegXTRadiator (G4LogicalVolume *anEnvelope,
G4Material*,G4Material*, G4double,G4double,G4int,
const G4String & processName = "TransparentRegXTRadiator");
~G4TransparentRegXTRadiator ();
public:
explicit G4TransparentRegXTRadiator(
G4LogicalVolume* anEnvelope, G4Material*, G4Material*, G4double, G4double,
G4int, const G4String& processName = "TransparentRegXTRadiator");
~G4TransparentRegXTRadiator();
// reimplementation of base class function in analytical way
G4double SpectralXTRdEdx(G4double energy) override;
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle) override;
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
};
#endif
@@ -23,60 +23,52 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// G4VTRModel -- header file
//
// The model of transition radiation
//
// History:
//
// 04.10.05, V.Grichine move from pure virtual and new class name
// 04.10.05, V.Grichine move from pure virtual and new class name
// 29.02.04, V.Ivanchenko created
#ifndef G4VTRModel_h
#define G4VTRModel_h
#include "globals.hh"
#include "G4Material.hh"
#include "G4ThreeVector.hh"
#include "G4Track.hh"
#include "G4VParticleChange.hh"
#include <vector>
#include "globals.hh"
#include "G4ThreeVector.hh"
class G4Material;
class G4Track;
class G4VParticleChange;
class G4VTRModel
{
public:
public:
// Constructors
explicit G4VTRModel( const G4String& modelName) {fName = modelName;};
explicit G4VTRModel(const G4String& modelName) { fName = modelName; };
// Destructor
virtual ~G4VTRModel(){};
virtual ~G4VTRModel() {};
const G4String& GetName() const {return fName;};
const G4String& GetName() const { return fName; };
virtual void GenerateSecondaries(G4VParticleChange& pChange,
std::vector<const G4Material*>& materials,
std::vector<G4double>& steps,
std::vector<G4ThreeVector>& normals,
G4ThreeVector& startingPosition,
const G4Track& track);
G4ThreeVector& startingPosition,
const G4Track& track);
// disable assignment operator & copy constructor
G4VTRModel& operator=(const G4VTRModel& right) = delete;
G4VTRModel(const G4VTRModel&) = delete;
virtual void PrintInfo() { return; };
// disable assignment operator & copy constructor
G4VTRModel & operator=(const G4VTRModel &right) = delete;
G4VTRModel(const G4VTRModel&) = delete;
protected:
G4String fName;
protected:
G4String fName;
};
#endif // G4VTRModel_h
#endif // G4VTRModel_h
@@ -23,8 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// G4VTransitionRadiation -- header file
//
// Generic process of transition radiation
@@ -36,72 +34,70 @@
#ifndef G4VTransitionRadiation_h
#define G4VTransitionRadiation_h
#include "G4VDiscreteProcess.hh"
#include "G4Track.hh"
#include "G4ForceCondition.hh"
#include "globals.hh"
#include "G4ForceCondition.hh"
#include "G4ParticleDefinition.hh"
#include "G4Region.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4VDiscreteProcess.hh"
#include "G4VParticleChange.hh"
#include <vector>
class G4Material;
class G4Region;
class G4VTRModel;
class G4particleDefinition;
class G4LossTableManager;
class G4Material;
class G4VTRModel;
class G4VTransitionRadiation : public G4VDiscreteProcess
class G4VTransitionRadiation : public G4VDiscreteProcess
{
public:
public:
// Constructors
explicit G4VTransitionRadiation(const G4String& processName = "TR",
G4ProcessType type = fElectromagnetic);
// Constructors
explicit G4VTransitionRadiation( const G4String& processName = "TR",
G4ProcessType type = fElectromagnetic);
// Destructor
virtual ~G4VTransitionRadiation();
virtual G4bool IsApplicable(
const G4ParticleDefinition& aParticleType) override;
// Destructor
virtual ~G4VTransitionRadiation() ;
virtual G4bool
IsApplicable(const G4ParticleDefinition& aParticleType) override;
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
virtual G4double GetMeanFreePath(const G4Track& track, G4double,
G4ForceCondition* condition) override;
G4ForceCondition* condition) override;
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step) override;
virtual void PrintInfoDefinition();
// Print out of the class parameters
const G4Step& step) override;
void SetRegion(const G4Region* reg);
void SetModel(G4VTRModel* m);
// private :
void Clear();
// hide assignment operator
G4VTransitionRadiation &
operator=(const G4VTransitionRadiation &right);
G4VTransitionRadiation(const G4VTransitionRadiation&);
G4VTransitionRadiation& operator=(const G4VTransitionRadiation& right) =
delete;
G4VTransitionRadiation(const G4VTransitionRadiation&) = delete;
G4LossTableManager* theManager;
private:
G4LossTableManager* theManager;
const G4Region* region;
G4VTRModel* model;
std::vector<const G4Material*> materials;
std::vector<G4double> steps;
std::vector<G4ThreeVector> normals;
std::vector<const G4Material*> materials;
std::vector<G4double> steps;
std::vector<G4ThreeVector> normals;
G4ThreeVector startingPosition;
G4ThreeVector startingDirection;
const G4Region* region;
G4VTRModel* model;
G4ThreeVector startingPosition;
G4ThreeVector startingDirection;
G4int nSteps;
G4double gammaMin;
G4double cosDThetaMax;
G4double gammaMin;
G4double cosDThetaMax;
G4int nSteps;
};
#endif // G4VTransitionRadiation_h
#endif // G4VTransitionRadiation_h
@@ -23,15 +23,12 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
//
// base class for 'fast' parametrisation model describing X-ray transition
// created in some G4Envelope. Anglur distribuiton is very rough !!! (see DoIt
// created in some G4Envelope. Angular distribuiton is very rough !!! (see DoIt
// method
//
//
// History:
// 06.10.05 V. Grichine first step to discrete process
// 15.01.02 V. Grichine first version
@@ -42,203 +39,182 @@
#ifndef G4VXTRenergyLoss_h
#define G4VXTRenergyLoss_h 1
#include <complex>
#include "globals.hh"
#include "Randomize.hh"
#include "G4LogicalVolume.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4Gamma.hh"
#include "G4ThreeVector.hh"
#include "G4ParticleMomentum.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4ParticleChange.hh"
#include "G4PhysicsTable.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4VContinuousProcess.hh"
#include "G4VDiscreteProcess.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4PhysicsTable.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4PhysicsOrderedFreeVector.hh"
#include "G4Integrator.hh"
#include "G4ParticleChange.hh"
class G4SandiaTable;
class G4VParticleChange;
class G4PhysicsFreeVector;
class G4PhysicsLinearVector;
class G4PhysicsLogVector;
class G4VXTRenergyLoss : public G4VDiscreteProcess // G4VContinuousProcess
class G4VXTRenergyLoss : public G4VDiscreteProcess
{
public:
public:
explicit G4VXTRenergyLoss(G4LogicalVolume* anEnvelope, G4Material*,
G4Material*, G4double, G4double, G4int,
const G4String& processName = "XTRenergyLoss",
G4ProcessType type = fElectromagnetic);
virtual ~G4VXTRenergyLoss();
explicit G4VXTRenergyLoss (G4LogicalVolume *anEnvelope,G4Material*,
G4Material*, G4double,G4double,G4int,
const G4String & processName = "XTRenergyLoss",
G4ProcessType type = fElectromagnetic);
virtual ~G4VXTRenergyLoss ();
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
// These virtual has to be implemented in inherited particular TR radiators
virtual G4double GetStackFactor( G4double energy, G4double gamma,
G4double varAngle );
G4VXTRenergyLoss(G4VXTRenergyLoss&) = delete;
G4VXTRenergyLoss& operator=(const G4VXTRenergyLoss& right) = delete;
// Virtual methods to be implemented in inherited particular TR radiators
virtual G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle);
virtual G4bool IsApplicable(const G4ParticleDefinition&) override;
virtual G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
virtual G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep) override;
virtual G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition) override;
G4double previousStepSize,
G4ForceCondition* condition) override;
virtual void BuildPhysicsTable(const G4ParticleDefinition&) override;
void BuildEnergyTable() ;
void BuildAngleForEnergyBank() ;
void BuildEnergyTable();
void BuildAngleForEnergyBank();
void BuildTable(){} ;
void BuildAngleTable() ;
void BuildGlobalAngleTable() ;
void BuildTable(){};
void BuildAngleTable();
void BuildGlobalAngleTable();
G4complex OneInterfaceXTRdEdx( G4double energy,
G4double gamma,
G4double varAngle ) ;
G4complex OneInterfaceXTRdEdx(G4double energy, G4double gamma,
G4double varAngle);
G4double SpectralAngleXTRdEdx(G4double varAngle) ;
G4double SpectralAngleXTRdEdx(G4double varAngle);
virtual G4double SpectralXTRdEdx(G4double energy) ;
virtual G4double SpectralXTRdEdx(G4double energy);
G4double AngleSpectralXTRdEdx(G4double energy) ;
G4double AngleSpectralXTRdEdx(G4double energy);
G4double AngleXTRdEdx(G4double varAngle) ;
/////////////////////////////////////////////////////////////
G4double OneBoundaryXTRNdensity( G4double energy,
G4double gamma,
G4double varAngle ) const ;
G4double AngleXTRdEdx(G4double varAngle);
G4double OneBoundaryXTRNdensity(G4double energy, G4double gamma,
G4double varAngle) const;
// for photon energy distribution tables
G4double XTRNSpectralAngleDensity(G4double varAngle);
G4double XTRNSpectralDensity(G4double energy);
G4double XTRNSpectralAngleDensity(G4double varAngle) ;
G4double XTRNSpectralDensity(G4double energy) ;
// for photon angle distribution tables
G4double XTRNAngleSpectralDensity(G4double energy);
G4double XTRNAngleDensity(G4double varAngle);
G4double XTRNAngleSpectralDensity(G4double energy) ;
G4double XTRNAngleDensity(G4double varAngle) ;
void GetNumberOfPhotons() ;
void GetNumberOfPhotons();
// Auxiliary functions for plate/gas material parameters
G4double GetPlateFormationZone(G4double, G4double, G4double);
G4complex GetPlateComplexFZ(G4double, G4double, G4double);
void ComputePlatePhotoAbsCof();
G4double GetPlateLinearPhotoAbs(G4double);
void GetPlateZmuProduct();
G4double GetPlateZmuProduct(G4double, G4double, G4double);
G4double GetPlateFormationZone(G4double,G4double,G4double);
G4complex GetPlateComplexFZ(G4double,G4double,G4double);
void ComputePlatePhotoAbsCof();
G4double GetPlateLinearPhotoAbs(G4double);
void GetPlateZmuProduct() ;
G4double GetPlateZmuProduct(G4double,G4double,G4double);
G4double GetGasFormationZone(G4double, G4double, G4double);
G4complex GetGasComplexFZ(G4double, G4double, G4double);
void ComputeGasPhotoAbsCof();
G4double GetGasLinearPhotoAbs(G4double);
void GetGasZmuProduct();
G4double GetGasZmuProduct(G4double, G4double, G4double);
G4double GetGasFormationZone(G4double,G4double,G4double);
G4complex GetGasComplexFZ(G4double,G4double,G4double);
void ComputeGasPhotoAbsCof();
G4double GetGasLinearPhotoAbs(G4double);
void GetGasZmuProduct();
G4double GetGasZmuProduct(G4double,G4double,G4double);
G4double GetPlateCompton(G4double);
G4double GetGasCompton(G4double);
G4double GetComptonPerAtom(G4double, G4double);
G4double GetPlateCompton(G4double);
G4double GetGasCompton(G4double);
G4double GetComptonPerAtom(G4double,G4double);
G4double GetXTRrandomEnergy(G4double scaledTkin, G4int iTkin);
G4double GetXTRenergy(G4int iPlace, G4double position, G4int iTransfer);
G4double GetXTRrandomEnergy( G4double scaledTkin, G4int iTkin );
G4double GetXTRenergy( G4int iPlace, G4double position, G4int iTransfer );
G4double GetRandomAngle(G4double energyXTR, G4int iTkin);
G4double GetAngleXTR(G4int iTR, G4double position, G4int iAngle);
G4double GetRandomAngle( G4double energyXTR, G4int iTkin );
G4double GetAngleXTR(G4int iTR,G4double position,G4int iAngle);
G4double GetGamma() { return fGamma; };
G4double GetEnergy() { return fEnergy; };
G4double GetVarAngle() { return fVarAngle; };
G4double GetGamma() {return fGamma;};
G4double GetEnergy() {return fEnergy;};
G4double GetVarAngle(){return fVarAngle;};
void SetGamma(G4double gamma) {fGamma = gamma;};
void SetEnergy(G4double energy) {fEnergy = energy;};
void SetVarAngle(G4double varAngle){fVarAngle = varAngle;};
void SetAngleRadDistr(G4bool pAngleRadDistr){fAngleRadDistr=pAngleRadDistr;};
void SetCompton(G4bool pC){fCompton=pC;};
void SetGamma(G4double gamma) { fGamma = gamma; };
void SetEnergy(G4double energy) { fEnergy = energy; };
void SetVarAngle(G4double varAngle) { fVarAngle = varAngle; };
void SetAngleRadDistr(G4bool pAngleRadDistr)
{
fAngleRadDistr = pAngleRadDistr;
};
void SetCompton(G4bool pC) { fCompton = pC; };
G4PhysicsLogVector* GetProtonVector(){ return fProtonEnergyVector;};
G4int GetTotBin(){return fTotBin;};
G4PhysicsLogVector* GetProtonVector() { return fProtonEnergyVector; };
G4int GetTotBin() { return fTotBin; };
G4PhysicsFreeVector* GetAngleVector(G4double energy, G4int n);
protected:
protected:
// min TR energy
static constexpr G4double fTheMinEnergyTR = 1. * CLHEP::keV;
// max TR energy
static constexpr G4double fTheMaxEnergyTR = 100. * CLHEP::keV;
static constexpr G4double fTheMinAngle = 1.e-3; // min theta of TR quanta
static constexpr G4double fTheMaxAngle = 1.e-2; // max theta of TR quanta
// min Tkin of proton in tables
static constexpr G4double fMinProtonTkin = 100. * CLHEP::GeV;
// max Tkin of proton in tables
static constexpr G4double fMaxProtonTkin = 100. * CLHEP::TeV;
// physical constants for plasma energy
static constexpr G4double fPlasmaCof =
4. * CLHEP::pi * CLHEP::fine_structure_const * CLHEP::hbarc * CLHEP::hbarc *
CLHEP::hbarc / CLHEP::electron_mass_c2;
static constexpr G4double fCofTR = CLHEP::fine_structure_const / CLHEP::pi;
G4ParticleDefinition* fPtrGamma ; // pointer to TR photon
G4double* fGammaCutInKineticEnergy ; // TR photon cut in energy array
G4double fGammaTkinCut ; // Tkin cut of TR photon in current mat.
G4LogicalVolume* fEnvelope ;
G4PhysicsTable* fAngleDistrTable ;
G4PhysicsTable* fEnergyDistrTable ;
G4PhysicsLogVector* fProtonEnergyVector ;
G4PhysicsLogVector* fXTREnergyVector ;
G4double fTheMinEnergyTR; // min TR energy
G4double fTheMaxEnergyTR; // max TR energy
G4double fMinEnergyTR; // min TR energy in material
G4double fMaxEnergyTR; // max TR energy in material
G4double fTheMaxAngle; // max theta of TR quanta
G4double fTheMinAngle; // max theta of TR quanta
G4double fMaxThetaTR; // max theta of TR quanta
G4int fBinTR; // number of bins in TR vectors
G4double fMinProtonTkin; // min Tkin of proton in tables
G4double fMaxProtonTkin; // max Tkin of proton in tables
G4int fTotBin; // number of bins in log scale
G4double fGamma; // current Lorentz factor
G4double fEnergy; // energy and
G4double fVarAngle; // angle squared
G4double fLambda;
G4double fPlasmaCof ; // physical consts for plasma energy
G4double fCofTR ;
G4bool fExitFlux;
G4bool fAngleRadDistr;
G4bool fCompton;
G4double fSigma1;
G4double fSigma2; // plasma energy Sq of matter1/2
G4int fMatIndex1;
G4int fMatIndex2;
G4int fPlateNumber;
G4double fTotalDist;
G4double fPlateThick;
G4double fGasThick;
G4double fAlphaPlate;
G4double fAlphaGas ;
static constexpr G4int fBinTR = 200; // number of bins in TR vectors
static constexpr G4int fTotBin = 50; // number of bins in log scale
G4ParticleDefinition* fPtrGamma; // pointer to TR photon
G4double* fGammaCutInKineticEnergy; // TR photon cut in energy array
G4LogicalVolume* fEnvelope;
G4PhysicsTable* fAngleDistrTable;
G4PhysicsTable* fEnergyDistrTable;
G4PhysicsTable* fAngleForEnergyTable;
G4PhysicsLogVector* fProtonEnergyVector;
G4PhysicsLogVector* fXTREnergyVector;
G4SandiaTable* fPlatePhotoAbsCof;
G4SandiaTable* fGasPhotoAbsCof;
G4ParticleChange fParticleChange;
std::vector<G4PhysicsTable*> fAngleBank;
G4PhysicsTable* fAngleForEnergyTable;
std::vector<G4PhysicsTable*> fAngleBank;
G4double fGammaTkinCut; // Tkin cut of TR photon in current mat.
G4double fMinEnergyTR; // min TR energy in material
G4double fMaxEnergyTR; // max TR energy in material
G4double fMaxThetaTR; // max theta of TR quanta
G4double fTotalDist;
G4double fPlateThick;
G4double fGasThick;
G4double fAlphaPlate;
G4double fAlphaGas;
G4double fGamma; // current Lorentz factor
G4double fEnergy; // energy and
G4double fVarAngle; // angle squared
G4double fLambda;
G4double fSigma1;
G4double fSigma2; // plasma energy Sq of matter1/2
private:
// copy constructor and hide assignment operator
G4VXTRenergyLoss(G4VXTRenergyLoss &) = delete;
G4VXTRenergyLoss & operator=(const G4VXTRenergyLoss &right) = delete;
G4int fMatIndex1;
G4int fMatIndex2;
G4int fPlateNumber;
G4bool fExitFlux;
G4bool fAngleRadDistr;
G4bool fCompton;
};
#endif
@@ -23,13 +23,11 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
///////////////////////////////////////////////////////////////////////////
//
// Rough model describing a gamma function distributed radiator of X-ray
// transition radiation. XTR is considered to flux after radiator!
// Thicknesses of plates and gas gaps are distributed according to gamma
//
// Rough model describing a gamma function distributed radiator of X-ray
// transition radiation. XTR is considered to flux after radiator!
// Thicknesses of plates and gas gaps are distributed according to gamma
// distribution. x are thicknesses of plates or gas gaps:
//
// p(x) = (alpha/<x>)^alpha * x^(alpha-1) * std::exp(-alpha*x/<x>) / G(alpha)
@@ -41,37 +39,33 @@
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
//
// History:
//
// 03.10.05 V. Grichine, first version
// 03.10.05 V. Grichine, first version
//
#ifndef G4XTRGammaRadModel_h
#define G4XTRGammaRadModel_h 1
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4XTRGammaRadModel : public G4VXTRenergyLoss
{
public:
public:
explicit G4XTRGammaRadModel(G4LogicalVolume* anEnvelope, G4double, G4double,
G4Material*, G4Material*, G4double, G4double,
G4int,
const G4String& processName = "XTRgammaRadiator");
~G4XTRGammaRadModel();
explicit G4XTRGammaRadModel (G4LogicalVolume *anEnvelope,
G4double,G4double,
G4Material*,G4Material*,
G4double,G4double,G4int,
const G4String & processName = "XTRgammaRadiator" );
virtual ~G4XTRGammaRadModel ();
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
private:
// G4double fAlphaPlate, fAlphaGas ;
};
#endif
@@ -23,43 +23,41 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
///////////////////////////////////////////////////////////////////////////
//
//
// Model describing a regular radiator of X-ray transition radiation.
// It is Garibian like model for XTR after radiator
// It is Garibian like model for XTR after radiator
// Thicknesses of plates and gas gaps are fixed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
//
// History:
// 10.10.05 V. Grichine, first version
// 10.10.05 V. Grichine, first version
//
#ifndef G4XTRRegularRadModel_h
#define G4XTRRegularRadModel_h 1
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4XTRRegularRadModel : public G4VXTRenergyLoss
{
public:
public:
explicit G4XTRRegularRadModel(G4LogicalVolume* anEnvelope, G4Material*,
G4Material*, G4double, G4double, G4int,
const G4String& processName = "XTRegularModel");
~G4XTRRegularRadModel();
explicit G4XTRRegularRadModel (G4LogicalVolume *anEnvelope,G4Material*,
G4Material*, G4double,G4double,G4int,
const G4String & processName = "XTRegularModel");
virtual ~G4XTRRegularRadModel ();
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
G4double SpectralXTRdEdx(G4double energy) override;
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
};
@@ -23,44 +23,42 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
///////////////////////////////////////////////////////////////////////////
//
// Process describing a radiator of X-ray transition radiation.
//
// Process describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are fixed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
//
// History:
//
// 05.04.05 V. Grichine, first version
// 05.04.05 V. Grichine, first version
//
#ifndef G4XTRTransparentRegRadModel_h
#define G4XTRTransparentRegRadModel_h 1
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VXTRenergyLoss.hh"
class G4XTRTransparentRegRadModel : public G4VXTRenergyLoss
{
public:
public:
explicit G4XTRTransparentRegRadModel(
G4LogicalVolume* anEnvelope, G4Material*, G4Material*, G4double, G4double,
G4int, const G4String& processName = "XTRTransparentRegRadModel");
~G4XTRTransparentRegRadModel();
explicit G4XTRTransparentRegRadModel (G4LogicalVolume *anEnvelope,G4Material*,
G4Material*, G4double,G4double,G4int,
const G4String & processName = "XTRTransparentRegRadModel");
~G4XTRTransparentRegRadModel ();
void ProcessDescription(std::ostream&) const override;
void DumpInfo() const override { ProcessDescription(G4cout); };
// reimplementation of base class function in analytical way
G4double SpectralXTRdEdx(G4double energy) override;
// Pure virtual function from base class
G4double GetStackFactor(G4double energy, G4double gamma,
G4double GetStackFactor(G4double energy, G4double gamma,
G4double varAngle) override;
};
@@ -1,84 +1,58 @@
#------------------------------------------------------------------------------
# sources.cmake
# Module : G4xrays
# Package: Geant4.src.G4processes.G4electromagnetic.G4xrays
#
# Sources description for a library.
# Lists the sources and headers of the code explicitly.
# Lists include paths needed.
# Lists the internal granular and global dependencies of the library.
# Source specific properties should be added at the end.
#
# Generated on : 24/9/2010
#
#
#------------------------------------------------------------------------------
# - G4xrays module build definition
#
# Define the Geant4 Module.
#
GEANT4_DEFINE_MODULE(NAME G4xrays
HEADERS
G4Cerenkov.hh
G4ForwardXrayTR.hh
G4GammaXTRadiator.hh
G4RegularXTRadiator.hh
G4Scintillation.hh
G4ScintillationTrackInformation.hh
G4StrawTubeXTRadiator.hh
G4SynchrotronRadiation.hh
G4SynchrotronRadiationInMat.hh
G4TransitionRadiation.hh
G4TransparentRegXTRadiator.hh
G4VTRModel.hh
G4VTransitionRadiation.hh
G4VXTRenergyLoss.hh
G4XTRGammaRadModel.hh
G4XTRRegularRadModel.hh
G4XTRTransparentRegRadModel.hh
SOURCES
G4Cerenkov.cc
G4ForwardXrayTR.cc
G4GammaXTRadiator.cc
G4RegularXTRadiator.cc
G4Scintillation.cc
G4ScintillationTrackInformation.cc
G4StrawTubeXTRadiator.cc
G4SynchrotronRadiation.cc
G4SynchrotronRadiationInMat.cc
G4TransitionRadiation.cc
G4TransparentRegXTRadiator.cc
G4VTransitionRadiation.cc
G4VXTRenergyLoss.cc
G4XTRGammaRadModel.cc
G4XTRRegularRadModel.cc
G4XTRTransparentRegRadModel.cc
GRANULAR_DEPENDENCIES
G4baryons
G4bosons
G4cuts
G4emutils
G4geometrymng
G4globman
G4hepnumerics
G4ions
G4leptons
G4magneticfield
G4materials
G4mesons
G4navigation
G4partman
G4procman
G4track
G4volumes
GLOBAL_DEPENDENCIES
G4geometry
G4global
G4materials
G4particles
G4track
LINK_LIBRARIES
)
# List any source specific properties here
geant4_add_module(G4xrays
PUBLIC_HEADERS
G4Cerenkov.hh
G4ForwardXrayTR.hh
G4GammaXTRadiator.hh
G4RegularXTRadiator.hh
G4Scintillation.hh
G4ScintillationTrackInformation.hh
G4StrawTubeXTRadiator.hh
G4SynchrotronRadiation.hh
G4SynchrotronRadiationInMat.hh
G4TransitionRadiation.hh
G4TransparentRegXTRadiator.hh
G4VTRModel.hh
G4VTransitionRadiation.hh
G4VXTRenergyLoss.hh
G4XTRGammaRadModel.hh
G4XTRRegularRadModel.hh
G4XTRTransparentRegRadModel.hh
SOURCES
G4Cerenkov.cc
G4ForwardXrayTR.cc
G4GammaXTRadiator.cc
G4RegularXTRadiator.cc
G4Scintillation.cc
G4ScintillationTrackInformation.cc
G4StrawTubeXTRadiator.cc
G4SynchrotronRadiation.cc
G4SynchrotronRadiationInMat.cc
G4TransitionRadiation.cc
G4TransparentRegXTRadiator.cc
G4VTransitionRadiation.cc
G4VXTRenergyLoss.cc
G4XTRGammaRadModel.cc
G4XTRRegularRadModel.cc
G4XTRTransparentRegRadModel.cc)
geant4_module_link_libraries(G4xrays
PUBLIC
G4bosons
G4emutils
G4geometrymng
G4globman
G4leptons
G4materials
G4navigation
G4partman
G4procman
G4track
PRIVATE
G4cuts
G4emstandard
G4hepnumerics
G4heprandom
G4magneticfield)
@@ -23,8 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
////////////////////////////////////////////////////////////////////////
// Cerenkov Radiation Class Implementation
////////////////////////////////////////////////////////////////////////
@@ -56,22 +54,26 @@
// > add protection against /0
// > G4MaterialPropertiesTable; new physics/tracking scheme
//
//
////////////////////////////////////////////////////////////////////////
#include "G4ios.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Poisson.hh"
#include "G4EmProcessSubType.hh"
#include "G4LossTableManager.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ParticleDefinition.hh"
#include "G4OpticalParameters.hh"
#include "G4Cerenkov.hh"
#include "G4ios.hh"
#include "G4LossTableManager.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4OpticalParameters.hh"
#include "G4OpticalPhoton.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleMomentum.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsFreeVector.hh"
#include "G4Poisson.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Cerenkov::G4Cerenkov(const G4String& processName, G4ProcessType type)
: G4VProcess(processName, type)
@@ -98,6 +100,21 @@ G4Cerenkov::~G4Cerenkov()
}
}
void G4Cerenkov::ProcessDescription(std::ostream& out) const
{
out << "The Cerenkov effect simulates optical photons created by the\n";
out << "passage of charged particles through matter. Materials need\n";
out << "to have the property RINDEX (refractive index) defined.\n";
G4VProcess::DumpInfo();
G4OpticalParameters* params = G4OpticalParameters::Instance();
out << "Maximum beta change per step: " << params->GetCerenkovMaxBetaChange();
out << "Maximum photons per step: " << params->GetCerenkovMaxPhotonsPerStep();
out << "Track secondaries first: " << params->GetCerenkovTrackSecondariesFirst();
out << "Stack photons: " << params->GetCerenkovStackPhotons();
out << "Verbose level: " << params->GetCerenkovVerboseLevel();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4Cerenkov::IsApplicable(const G4ParticleDefinition& aParticleType)
{
@@ -134,33 +151,30 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
// loop over materials
for(G4int i = 0; i < numOfMaterials; ++i)
{
G4PhysicsOrderedFreeVector* aPhysicsOrderedFreeVector = 0;
G4PhysicsFreeVector* cerenkovIntegral = nullptr;
// Retrieve vector of refraction indices for the material
// from the material's optical properties table
G4Material* aMaterial = (*theMaterialTable)[i];
G4MaterialPropertiesTable* aMaterialPropertiesTable =
aMaterial->GetMaterialPropertiesTable();
G4MaterialPropertiesTable* MPT = aMaterial->GetMaterialPropertiesTable();
if(aMaterialPropertiesTable)
if(MPT)
{
aPhysicsOrderedFreeVector = new G4PhysicsOrderedFreeVector();
G4MaterialPropertyVector* theRefractionIndexVector =
aMaterialPropertiesTable->GetProperty(kRINDEX);
cerenkovIntegral = new G4PhysicsFreeVector();
G4MaterialPropertyVector* refractiveIndex = MPT->GetProperty(kRINDEX);
if(theRefractionIndexVector)
if(refractiveIndex)
{
// Retrieve the first refraction index in vector
// of (photon energy, refraction index) pairs
G4double currentRI = (*theRefractionIndexVector)[0];
G4double currentRI = (*refractiveIndex)[0];
if(currentRI > 1.0)
{
// Create first (photon energy, Cerenkov Integral) pair
G4double currentPM = theRefractionIndexVector->Energy(0);
G4double currentPM = refractiveIndex->Energy(0);
G4double currentCAI = 0.0;
aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
cerenkovIntegral->InsertValues(currentPM, currentCAI);
// Set previous values to current ones prior to loop
G4double prevPM = currentPM;
@@ -169,16 +183,15 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
// loop over all (photon energy, refraction index)
// pairs stored for this material
for(size_t ii = 1; ii < theRefractionIndexVector->GetVectorLength();
++ii)
for(size_t ii = 1; ii < refractiveIndex->GetVectorLength(); ++ii)
{
currentRI = (*theRefractionIndexVector)[ii];
currentPM = theRefractionIndexVector->Energy(ii);
currentRI = (*refractiveIndex)[ii];
currentPM = refractiveIndex->Energy(ii);
currentCAI = prevCAI + (currentPM - prevPM) * 0.5 *
(1.0 / (prevRI * prevRI) +
1.0 / (currentRI * currentRI));
aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
cerenkovIntegral->InsertValues(currentPM, currentCAI);
prevPM = currentPM;
prevCAI = currentCAI;
@@ -191,7 +204,7 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
// The Cerenkov integral for a given material will be inserted in
// thePhysicsTable according to the position of the material in
// the material table.
thePhysicsTable->insertAt(i, aPhysicsOrderedFreeVector);
thePhysicsTable->insertAt(i, cerenkovIntegral);
}
}
@@ -206,10 +219,6 @@ G4VParticleChange* G4Cerenkov::PostStepDoIt(const G4Track& aTrack,
// they are added to the particle change.
{
////////////////////////////////////////////////////
// Should we ensure that the material is dispersive?
////////////////////////////////////////////////////
aParticleChange.Initialize(aTrack);
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
@@ -233,8 +242,6 @@ G4VParticleChange* G4Cerenkov::PostStepDoIt(const G4Track& aTrack,
G4double charge = aParticle->GetDefinition()->GetPDGCharge();
G4double beta = (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta()) * 0.5;
// fNumPhotons = 0; // in PostStepGetPhysicalInteractionLength()
G4double MeanNumberOfPhotons =
GetAverageNumberOfPhotons(charge, beta, aMaterial, Rindex);
@@ -447,9 +454,8 @@ G4double G4Cerenkov::PostStepGetPhysicalInteractionLength(
particleType, kineticEnergy, couple);
G4double Step = Range - RangeMin;
// If the step is smaller than 1e-16 mm, it may happen that the particle
// If the step is smaller than 1e-15 mm, it may happen that the particle
// does not move. See bug 1992.
// 2019-03-11: change to 1e-15
if(Step < 1.e-15 * mm)
return StepLimit;
@@ -493,22 +499,21 @@ G4double G4Cerenkov::GetAverageNumberOfPhotons(
const G4double charge, const G4double beta, const G4Material* aMaterial,
G4MaterialPropertyVector* Rindex) const
// This routine computes the number of Cerenkov photons produced per
// GEANT4-unit (millimeter) in the current medium.
// ^^^^^^^^^^
// Geant4-unit (millimeter) in the current medium.
{
const G4double Rfact = 369.81 / (eV * cm);
constexpr G4double Rfact = 369.81 / (eV * cm);
if(beta <= 0.0)
return 0.0;
G4double BetaInverse = 1. / beta;
// Vectors used in computation of Cerenkov Angle Integral:
// - Refraction Indices for the current material
// - new G4PhysicsOrderedFreeVector allocated to hold CAI's
// - new G4PhysicsFreeVector allocated to hold CAI's
G4int materialIndex = aMaterial->GetIndex();
// Retrieve the Cerenkov Angle Integrals for this material
G4PhysicsOrderedFreeVector* CerenkovAngleIntegrals =
(G4PhysicsOrderedFreeVector*) ((*thePhysicsTable)(materialIndex));
G4PhysicsFreeVector* CerenkovAngleIntegrals =
(G4PhysicsFreeVector*) ((*thePhysicsTable)(materialIndex));
if(!(CerenkovAngleIntegrals->IsFilledVectorExist()))
return 0.0;
@@ -583,10 +588,9 @@ void G4Cerenkov::SetMaxNumPhotonsPerStep(const G4int NumPhotons)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4Cerenkov::DumpPhysicsTable() const
{
G4PhysicsOrderedFreeVector* v;
G4cout << "Dump Physics Table!" << G4endl;
for(size_t i = 0; i < thePhysicsTable->entries(); ++i)
{
v = (G4PhysicsOrderedFreeVector*) (*thePhysicsTable)[i];
v->DumpValues();
((G4PhysicsFreeVector*) (*thePhysicsTable)[i])->DumpValues();
}
}
File diff suppressed because it is too large Load Diff
@@ -23,99 +23,77 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
#include <complex>
#include "G4GammaXTRadiator.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4GammaXTRadiator::G4GammaXTRadiator(G4LogicalVolume* anEnvelope,
G4double alphaPlate,
G4double alphaGas,
G4Material* foilMat,G4Material* gasMat,
G4GammaXTRadiator::G4GammaXTRadiator(G4LogicalVolume* anEnvelope,
G4double alphaPlate, G4double alphaGas,
G4Material* foilMat, G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
G4cout<<"Gamma distributed X-ray TR radiator model is called"<<G4endl ;
G4cout << "Gamma distributed X-ray TR radiator model is called" << G4endl;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fAlphaPlate = alphaPlate ;
fAlphaGas = alphaGas ;
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
// BuildTable() ;
fAlphaPlate = alphaPlate;
fAlphaGas = alphaGas;
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
<< G4endl;
}
///////////////////////////////////////////////////////////////////////////
G4GammaXTRadiator::~G4GammaXTRadiator() {}
G4GammaXTRadiator::~G4GammaXTRadiator()
void G4GammaXTRadiator::ProcessDescription(std::ostream& out) const
{
;
out
<< "Rough approximation describing a radiator of X-ray transition "
"radiation.\n"
"Thicknesses of plates and gas gaps are distributed according to gamma\n"
"description.\n";
}
///////////////////////////////////////////////////////////////////////////
//
// Rough approximation for radiator interference factor for the case of
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4GammaXTRadiator::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in corresponding material.
G4double G4GammaXTRadiator::GetStackFactor(G4double energy, G4double gamma,
G4double varAngle)
{
G4double result, Za, Zb, Ma, Mb ;
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
G4double result, Za, Zb, Ma, Mb;
Ma = GetPlateLinearPhotoAbs(energy) ;
Mb = GetGasLinearPhotoAbs(energy) ;
Za = GetPlateFormationZone(energy, gamma, varAngle);
Zb = GetGasFormationZone(energy, gamma, varAngle);
Ma = GetPlateLinearPhotoAbs(energy);
Mb = GetGasLinearPhotoAbs(energy);
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate) ;
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas) ;
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
fPlateThick / Za / fAlphaPlate);
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
fGasThick / Zb / fAlphaGas);
G4complex Ha = std::pow(Ca,-fAlphaPlate) ;
G4complex Hb = std::pow(Cb,-fAlphaGas) ;
G4complex H = Ha*Hb ;
G4complex Ha = std::pow(Ca, -fAlphaPlate);
G4complex Hb = std::pow(Cb, -fAlphaGas);
G4complex H = Ha * Hb;
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
* G4double(fPlateNumber) ;
G4complex F1 = (1.0 - Ha) * (1.0 - Hb) / (1.0 - H) * G4double(fPlateNumber);
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
* (1.0 - std::pow(H,fPlateNumber)) ;
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb / (1.0 - H) / (1.0 - H) *
(1.0 - std::pow(H, fPlateNumber));
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle) ;
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
result = 2.0*std::real(R) ;
return result ;
result = 2.0 * std::real(R);
return result;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -23,235 +23,142 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
#include <complex>
#include "G4RegularXTRadiator.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
#include "G4PhysicalConstants.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4RegularXTRadiator::G4RegularXTRadiator(G4LogicalVolume *anEnvelope,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
G4RegularXTRadiator::G4RegularXTRadiator(G4LogicalVolume* anEnvelope,
G4Material* foilMat,
G4Material* gasMat, G4double a,
G4double b, G4int n,
const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
G4cout<<"Regular X-ray TR radiator EM process is called"<<G4endl ;
G4cout << "Regular X-ray TR radiator EM process is called" << G4endl;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fAlphaPlate = 10000;
fAlphaGas = 1000;
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
// BuildTable() ;
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
<< G4endl;
}
///////////////////////////////////////////////////////////////////////////
G4RegularXTRadiator::~G4RegularXTRadiator() {}
G4RegularXTRadiator::~G4RegularXTRadiator()
void G4RegularXTRadiator::ProcessDescription(std::ostream& out) const
{
;
out << "Simulation of X-ray transition radiation generated by\n"
"relativistic charged particles crossing the interface between\n"
"two materials. Thicknesses of plates and gaps are fixed.\n";
}
///////////////////////////////////////////////////////////////////////////
//
//
G4double G4RegularXTRadiator::SpectralXTRdEdx(G4double energy)
{
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
G4double aMa, bMb ,sigma, dump;
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
G4double aMa, bMb, sigma, dump;
G4int k, kMax, kMin;
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
sigma = 0.5*(aMa + bMb);
dump = std::exp(-fPlateNumber*sigma);
if(verboseLevel > 2) G4cout<<" dump = "<<dump<<G4endl;
cofPHC = 4*pi*hbarc;
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
cof1 = fPlateThick*tmp;
cof2 = fGasThick*tmp;
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
sigma = 0.5 * (aMa + bMb);
dump = std::exp(-fPlateNumber * sigma);
if(verboseLevel > 2)
G4cout << " dump = " << dump << G4endl;
cofPHC = 4 * pi * hbarc;
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
cof1 = fPlateThick * tmp;
cof2 = fGasThick * tmp;
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
cofMin /= cofPHC;
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
// else kMin = 1;
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
kMin = G4int(cofMin);
if (cofMin > kMin) kMin++;
if(cofMin > kMin)
kMin++;
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
// tmp /= cofPHC;
// kMax = G4int(tmp);
// if(kMax < 0) kMax = 0;
// kMax += kMin;
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
// tmp /= fGamma;
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
kMax = kMin + 49;
if(verboseLevel > 2)
{
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
}
for( k = kMin; k <= kMax; k++ )
{
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
if( k == kMin && kMin == G4int(cofMin) )
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
}
for(k = kMin; k <= kMax; ++k)
{
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
if(k == kMin && kMin == G4int(cofMin))
{
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum +=
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
else
{
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
if(verboseLevel > 2)
{
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
// <<"; sum = "<<sum<<G4endl;
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
<<" "<<sum<<G4endl;
}
{
G4cout << k << " " << theta2k << " "
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
<< " " << sum << G4endl;
}
}
result = 2*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
// fPlateNumber;
result *= ( 1 - dump + 2*dump*fPlateNumber );
/*
fEnergy = energy;
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.0,0.3*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.6*fMaxThetaTR,fMaxThetaTR) ;
result += tmp;
*/
result = 2 * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
result *= (1 - dump + 2 * dump * fPlateNumber);
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in corresponding material.
G4double
G4RegularXTRadiator::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
G4double G4RegularXTRadiator::GetStackFactor(G4double energy, G4double gamma,
G4double varAngle)
{
// some gamma (10000/1000) like algorithm
G4double result, Za, Zb, Ma, Mb;
Za = GetPlateFormationZone(energy,gamma,varAngle);
Zb = GetGasFormationZone(energy,gamma,varAngle);
Za = GetPlateFormationZone(energy, gamma, varAngle);
Zb = GetGasFormationZone(energy, gamma, varAngle);
Ma = GetPlateLinearPhotoAbs(energy);
Mb = GetGasLinearPhotoAbs(energy);
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
fPlateThick / Za / fAlphaPlate);
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
fGasThick / Zb / fAlphaGas);
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
G4complex Ha = std::pow(Ca, -fAlphaPlate);
G4complex Hb = std::pow(Cb, -fAlphaGas);
G4complex H = Ha * Hb;
G4complex Ha = std::pow(Ca,-fAlphaPlate);
G4complex Hb = std::pow(Cb,-fAlphaGas);
G4complex H = Ha*Hb;
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
* G4double(fPlateNumber);
G4complex F1 = (1.0 - Ha) * (1.0 - Hb) / (1.0 - H) * G4double(fPlateNumber);
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
* (1.0 - std::pow(H,fPlateNumber));
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb / (1.0 - H) / (1.0 - H) *
(1.0 - std::pow(H, fPlateNumber));
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
/*
// numerically stable but slow algorithm
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb; // , D;
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
Qa = std::exp(-aMa);
Qb = std::exp(-bMb);
Q = Qa*Qb;
G4complex Ha( std::exp(-0.5*aMa)*std::cos(aZa),
-std::exp(-0.5*aMa)*std::sin(aZa) );
G4complex Hb( std::exp(-0.5*bMb)*std::cos(bZb),
-std::exp(-0.5*bMb)*std::sin(bZb) );
G4complex H = Ha*Hb;
G4complex Hs = conj(H);
D = 1.0 /( (1 - std::sqrt(Q))*(1 - std::sqrt(Q)) +
4*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) );
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
* G4double(fPlateNumber)*D;
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb*(1.0-Hs)*(1.0-Hs)
* (1.0 - std::pow(H,fPlateNumber)) * D*D;
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0 * std::real(R);
G4complex S(0.,0.), c(1.,0.);
G4int k;
for(k = 1; k < fPlateNumber; k++)
{
c *= H;
S += ( G4double(fPlateNumber) - G4double(k) )*c;
}
G4complex R = (2.- Ha - 1./Ha)*S + (1. - Ha)*G4double(fPlateNumber);
R *= OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
*/
return result;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -22,8 +22,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
////////////////////////////////////////////////////////////////////////
// Scintillation Light Class Implementation
////////////////////////////////////////////////////////////////////////
@@ -62,20 +60,29 @@
// 2001-09-17, migration of Materials to pure STL (mma)
// 2003-06-03, V.Ivanchenko fix compilation warnings
//
//
////////////////////////////////////////////////////////////////////////
#include "G4ios.hh"
#include "globals.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleTypes.hh"
#include "G4EmProcessSubType.hh"
#include "G4OpticalParameters.hh"
#include "G4ScintillationTrackInformation.hh"
#include "G4Scintillation.hh"
#include "globals.hh"
#include "G4DynamicParticle.hh"
#include "G4EmProcessSubType.hh"
#include "G4Material.hh"
#include "G4MaterialPropertiesTable.hh"
#include "G4MaterialPropertyVector.hh"
#include "G4OpticalParameters.hh"
#include "G4ParticleMomentum.hh"
#include "G4ParticleTypes.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsFreeVector.hh"
#include "G4PhysicsTable.hh"
#include "G4Poisson.hh"
#include "G4ScintillationTrackInformation.hh"
#include "G4StepPoint.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4Scintillation::G4Scintillation(const G4String& processName,
G4ProcessType type)
@@ -83,8 +90,8 @@ G4Scintillation::G4Scintillation(const G4String& processName,
, fIntegralTable1(nullptr)
, fIntegralTable2(nullptr)
, fIntegralTable3(nullptr)
, fNumPhotons(0)
, fEmSaturation(nullptr)
, fNumPhotons(0)
{
SetProcessSubType(fScintillation);
@@ -120,6 +127,23 @@ G4Scintillation::~G4Scintillation()
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4Scintillation::ProcessDescription(std::ostream& out) const
{
out << "Scintillation simulates production of optical photons produced\n"
"by a high energy particle traversing matter.\n"
"Various material properties need to be defined.\n";
G4VRestDiscreteProcess::DumpInfo();
G4OpticalParameters* params = G4OpticalParameters::Instance();
out << "Track secondaries first: " << params->GetScintTrackSecondariesFirst();
out << "Finite rise time: " << params->GetScintFiniteRiseTime();
out << "Scintillation by particle type: " << params->GetScintByParticleType();
out << "Save track information: " << params->GetScintTrackInfo();
out << "Stack photons: " << params->GetScintStackPhotons();
out << "Verbose level: " << params->GetScintVerboseLevel();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4Scintillation::IsApplicable(const G4ParticleDefinition& aParticleType)
{
@@ -142,10 +166,7 @@ void G4Scintillation::Initialise()
G4OpticalParameters* params = G4OpticalParameters::Instance();
SetTrackSecondariesFirst(params->GetScintTrackSecondariesFirst());
SetFiniteRiseTime(params->GetScintFiniteRiseTime());
SetScintillationYieldFactor(params->GetScintYieldFactor());
SetScintillationExcitationRatio(params->GetScintExcitationRatio());
SetScintillationByParticleType(params->GetScintByParticleType());
SetEnhancedTimeConstants(params->GetScintEnhancedTimeConstants());
SetScintillationTrackInfo(params->GetScintTrackInfo());
SetStackPhotons(params->GetScintStackPhotons());
SetVerboseLevel(params->GetScintVerboseLevel());
@@ -186,9 +207,9 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
for(size_t i = 0; i < numOfMaterials; ++i)
{
G4PhysicsOrderedFreeVector* vector1 = new G4PhysicsOrderedFreeVector();
G4PhysicsOrderedFreeVector* vector2 = new G4PhysicsOrderedFreeVector();
G4PhysicsOrderedFreeVector* vector3 = new G4PhysicsOrderedFreeVector();
G4PhysicsFreeVector* vector1 = new G4PhysicsFreeVector();
G4PhysicsFreeVector* vector2 = new G4PhysicsFreeVector();
G4PhysicsFreeVector* vector3 = new G4PhysicsFreeVector();
// Retrieve vector of scintillation wavelength intensity for
// the material from the material's optical properties table.
@@ -197,10 +218,7 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
if(MPT)
{
// integral table 1 is either FASTCOMPONENT or SCINTILLATIONCOMPONENT1
G4MaterialPropertyVector* MPV = MPT->GetProperty(kFASTCOMPONENT);
if(!MPV)
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT1);
G4MaterialPropertyVector* MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT1);
if(MPV)
{
// Retrieve the first intensity point in vector
@@ -236,7 +254,6 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
}
}
// integral table 2 is SCINTILLATIONCOMPONENT2
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT2);
if(MPV)
{
@@ -272,10 +289,7 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
}
}
}
// integral table 3 is either SLOWCOMPONENT or SCINTILLATIONCOMPONENT3
MPV = MPT->GetProperty(kSLOWCOMPONENT);
if(!MPV)
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT3);
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT3);
if(MPV)
{
// Retrieve the first intensity point in vector
@@ -355,30 +369,14 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
G4int N_timeconstants = 1;
// only needed for old (two time constants) version
G4MaterialPropertyVector* Fast_Intensity = nullptr;
G4MaterialPropertyVector* Slow_Intensity = nullptr;
if(fEnhancedTimeConstants)
if(MPT->GetProperty(kSCINTILLATIONCOMPONENT3))
N_timeconstants = 3;
else if(MPT->GetProperty(kSCINTILLATIONCOMPONENT2))
N_timeconstants = 2;
else if(!(MPT->GetProperty(kSCINTILLATIONCOMPONENT1)))
{
if(MPT->GetProperty(kSCINTILLATIONCOMPONENT3))
N_timeconstants = 3;
else if(MPT->GetProperty(kSCINTILLATIONCOMPONENT2))
N_timeconstants = 2;
else if(!(MPT->GetProperty(kSCINTILLATIONCOMPONENT1)))
{
// no components were specified
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
}
else
{ // OLD METHOD
Fast_Intensity = MPT->GetProperty(kFASTCOMPONENT);
Slow_Intensity = MPT->GetProperty(kSLOWCOMPONENT);
if(!Fast_Intensity && !Slow_Intensity)
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
if(Fast_Intensity && Slow_Intensity)
N_timeconstants = 2;
// no components were specified
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
G4double ResolutionScale = MPT->GetConstProperty(kRESOLUTIONSCALE);
@@ -389,61 +387,37 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
G4double yield3 = 0.;
G4double sum_yields = 0.;
if(!fEnhancedTimeConstants)
{
// Scintillation depends on particle type, energy deposited
if(fScintillationByParticleType)
{
MeanNumberOfPhotons = GetScintillationYieldByParticleType(aTrack, aStep);
}
else
{
// The default linear scintillation process
// Units: [# scintillation photons / MeV]
MeanNumberOfPhotons =
MPT->GetConstProperty(kSCINTILLATIONYIELD) * fYieldFactor;
// Birk's correction via fEmSaturation and specifying scintillation by
// by particle type are physically mutually exclusive
if(fEmSaturation)
MeanNumberOfPhotons *=
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
else
MeanNumberOfPhotons *= TotalEnergyDeposit;
}
}
if(fScintillationByParticleType)
{
MeanNumberOfPhotons = GetScintillationYieldByParticleType(
aTrack, aStep, yield1, yield2, yield3);
}
else
{
if(fScintillationByParticleType)
{
MeanNumberOfPhotons = GetScintillationYieldByParticleType(
aTrack, aStep, yield1, yield2, yield3);
}
yield1 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD1)
? MPT->GetConstProperty(kSCINTILLATIONYIELD1)
: 1.;
yield2 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD2)
? MPT->GetConstProperty(kSCINTILLATIONYIELD2)
: 0.;
yield3 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD3)
? MPT->GetConstProperty(kSCINTILLATIONYIELD3)
: 0.;
// The default linear scintillation process
// Units: [# scintillation photons / MeV]
MeanNumberOfPhotons =
MPT->GetConstProperty(kSCINTILLATIONYIELD);
// Birk's correction via fEmSaturation and specifying scintillation by
// by particle type are physically mutually exclusive
if(fEmSaturation)
MeanNumberOfPhotons *=
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
else
{
yield1 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD1)
? MPT->GetConstProperty(kSCINTILLATIONYIELD1)
: 1.;
yield2 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD2)
? MPT->GetConstProperty(kSCINTILLATIONYIELD2)
: 0.;
yield3 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD3)
? MPT->GetConstProperty(kSCINTILLATIONYIELD3)
: 0.;
// The default linear scintillation process
// Units: [# scintillation photons / MeV]
MeanNumberOfPhotons =
MPT->GetConstProperty(kSCINTILLATIONYIELD) * fYieldFactor;
// Birk's correction via fEmSaturation and specifying scintillation by
// by particle type are physically mutually exclusive
if(fEmSaturation)
MeanNumberOfPhotons *=
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
else
MeanNumberOfPhotons *= TotalEnergyDeposit;
}
sum_yields = yield1 + yield2 + yield3;
MeanNumberOfPhotons *= TotalEnergyDeposit;
}
sum_yields = yield1 + yield2 + yield3;
if(MeanNumberOfPhotons > 10.)
{
@@ -473,134 +447,66 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
G4int materialIndex = aMaterial->GetIndex();
// Retrieve the Scintillation Integral for this material
// new G4PhysicsOrderedFreeVector allocated to hold CII's
size_t numPhot = fNumPhotons;
G4double scintTime = 0.;
G4double riseTime = 0.;
G4PhysicsOrderedFreeVector* scintIntegral = nullptr;
G4ScintillationType scintType = Slow;
// new G4PhysicsFreeVector allocated to hold CII's
size_t numPhot = fNumPhotons;
G4double scintTime = 0.;
G4double riseTime = 0.;
G4PhysicsFreeVector* scintIntegral = nullptr;
G4ScintillationType scintType = Slow;
for(G4int scnt = 0; scnt < N_timeconstants; ++scnt)
{
// Original method with FAST and SLOW
if(!fEnhancedTimeConstants)
// if there is 1 time constant it is #1, etc.
if(scnt == 0)
{
if(scnt == 0)
if(N_timeconstants == 1)
{
if(N_timeconstants == 1)
{
if(Fast_Intensity)
{
scintTime = MPT->GetConstProperty(kFASTTIMECONSTANT);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kFASTSCINTILLATIONRISETIME);
}
scintType = Fast;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
}
if(Slow_Intensity)
{
scintTime = MPT->GetConstProperty(kSLOWTIMECONSTANT);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSLOWSCINTILLATIONRISETIME);
}
scintType = Slow;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
}
}
else
{ /// N_timeconstants != 1 and still scnt == 0
G4double yieldRatio = MPT->GetConstProperty(kYIELDRATIO);
if(fExcitationRatio == 1.0 || fExcitationRatio == 0.0)
{
numPhot = G4int(std::min(yieldRatio, 1.0) * fNumPhotons);
}
else
{
numPhot = G4int(std::min(fExcitationRatio, 1.0) * fNumPhotons);
}
scintTime = MPT->GetConstProperty(kFASTTIMECONSTANT);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kFASTSCINTILLATIONRISETIME);
}
scintType = Fast;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
}
numPhot = fNumPhotons;
}
else
{ // scnt != 0
numPhot = fNumPhotons - numPhot;
scintTime = MPT->GetConstProperty(kSLOWTIMECONSTANT);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSLOWSCINTILLATIONRISETIME);
}
scintType = Slow;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
{
numPhot = yield1 / sum_yields * fNumPhotons;
}
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT1);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME1);
}
scintType = Fast;
scintIntegral =
(G4PhysicsFreeVector*) ((*fIntegralTable1)(materialIndex));
}
else
{ // fEnhancedTimeConstants == true
// in the new method, if there is 1 time constant it is #1, etc.
// Note: fExcitationRatio is not used
if(scnt == 0)
else if(scnt == 1)
{
// to be consistent with old version (due to double->int conversion)
if(N_timeconstants == 2)
{
if(N_timeconstants == 1)
{
numPhot = fNumPhotons;
}
else
{
numPhot = yield1 / sum_yields * fNumPhotons;
}
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT1);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME1);
}
scintType = Fast;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
numPhot = fNumPhotons - numPhot;
}
else if(scnt == 1)
else
{
// to be consistent with old version (due to double->int conversion)
if(N_timeconstants == 2)
{
numPhot = fNumPhotons - numPhot;
}
else
{
numPhot = yield2 / sum_yields * fNumPhotons;
}
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT2);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME2);
}
scintType = Medium;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable2)(materialIndex));
numPhot = yield2 / sum_yields * fNumPhotons;
}
else if(scnt == 2)
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT2);
if(fFiniteRiseTime)
{
numPhot = yield3 / sum_yields * fNumPhotons;
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT3);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME3);
}
scintType = Slow;
scintIntegral =
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME2);
}
scintType = Medium;
scintIntegral =
(G4PhysicsFreeVector*) ((*fIntegralTable2)(materialIndex));
}
else if(scnt == 2)
{
numPhot = yield3 / sum_yields * fNumPhotons;
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT3);
if(fFiniteRiseTime)
{
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME3);
}
scintType = Slow;
scintIntegral =
(G4PhysicsFreeVector*) ((*fIntegralTable3)(materialIndex));
}
if(!scintIntegral)
@@ -739,137 +645,6 @@ G4double G4Scintillation::sample_time(G4double tau1, G4double tau2)
return -1.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4Scintillation::GetScintillationYieldByParticleType(
const G4Track& aTrack, const G4Step& aStep)
{
// Get the G4MaterialPropertyVector containing the scintillation
// yield as a function of the energy deposited and particle type
G4ParticleDefinition* pDef = aTrack.GetDynamicParticle()->GetDefinition();
G4MaterialPropertyVector* scintVector = nullptr;
G4MaterialPropertiesTable* MPT =
aTrack.GetMaterial()->GetMaterialPropertiesTable();
// Protons
if(pDef == G4Proton::ProtonDefinition())
scintVector = MPT->GetProperty(kPROTONSCINTILLATIONYIELD);
// Deuterons
else if(pDef == G4Deuteron::DeuteronDefinition())
scintVector = MPT->GetProperty(kDEUTERONSCINTILLATIONYIELD);
// Tritons
else if(pDef == G4Triton::TritonDefinition())
scintVector = MPT->GetProperty(kTRITONSCINTILLATIONYIELD);
// Alphas
else if(pDef == G4Alpha::AlphaDefinition())
scintVector = MPT->GetProperty(kALPHASCINTILLATIONYIELD);
// Ions (particles derived from G4VIon and G4Ions) and recoil ions
// below the production cut from neutrons after hElastic
else if(pDef->GetParticleType() == "nucleus" ||
pDef == G4Neutron::NeutronDefinition())
scintVector = MPT->GetProperty(kIONSCINTILLATIONYIELD);
// Electrons (must also
else if(pDef == G4Electron::ElectronDefinition() ||
pDef == G4Gamma::GammaDefinition())
scintVector = MPT->GetProperty(kELECTRONSCINTILLATIONYIELD);
// Default for particles not enumerated/listed above
// includes gamma to account for shell-binding energy
// attributed to gamma from standard photoelectric effect)
else
scintVector = MPT->GetProperty(kELECTRONSCINTILLATIONYIELD);
// Throw an exception if no scintillation yield vector is found
if(!scintVector)
{
G4ExceptionDescription ed;
ed << "\nG4Scintillation::PostStepDoIt(): "
<< "Request for scintillation yield for energy deposit and particle\n"
<< "type without correct entry in MaterialPropertiesTable.\n"
<< "ScintillationByParticleType requires at minimum that \n"
<< "ELECTRONSCINTILLATIONYIELD is set by the user\n"
<< G4endl;
G4String comments = "Missing MaterialPropertiesTable entry - No correct "
"entry in MaterialPropertiesTable";
G4Exception("G4Scintillation::PostStepDoIt", "Scint01", FatalException, ed,
comments);
}
///////////////////////////////////////
// Calculate the scintillation light //
///////////////////////////////////////
// To account for potential nonlinearity and scintillation photon
// density along the track, light (L) is produced according to:
// L_currentStep = L(PreStepKE) - L(PreStepKE - EDep)
G4double ScintillationYield = 0.;
G4double StepEnergyDeposit = aStep.GetTotalEnergyDeposit();
G4double PreStepKineticEnergy = aStep.GetPreStepPoint()->GetKineticEnergy();
if(PreStepKineticEnergy <= scintVector->GetMaxEnergy())
{
G4double Yield1 = scintVector->Value(PreStepKineticEnergy);
G4double Yield2 =
scintVector->Value(PreStepKineticEnergy - StepEnergyDeposit);
ScintillationYield = Yield1 - Yield2;
}
else
{
G4ExceptionDescription ed;
ed << "\nG4Scintillation::GetScintillationYieldByParticleType(): Request\n"
<< "for scintillation light yield above the available energy range\n"
<< "specified in G4MaterialPropertiesTable. A linear interpolation\n"
<< "will be performed to compute the scintillation light yield using\n"
<< "(L_max / E_max) as the photon yield per unit energy." << G4endl;
G4String cmt = "\nScintillation yield may be unphysical!\n";
G4Exception("G4Scintillation::GetScintillationYieldByParticleType()",
"Scint03", JustWarning, ed, cmt);
// Units: [# scintillation photons]
ScintillationYield = scintVector->GetMaxValue() /
scintVector->GetMaxEnergy() * StepEnergyDeposit;
}
#ifdef G4DEBUG_SCINTILLATION
// Increment track aggregators
ScintTrackYield += ScintillationYield;
ScintTrackEDep += StepEnergyDeposit;
G4cout << "\n--- G4Scintillation::GetScintillationYieldByParticleType() ---\n"
<< "--\n"
<< "-- Name = "
<< aTrack.GetParticleDefinition()->GetParticleName() << "\n"
<< "-- TrackID = " << aTrack.GetTrackID() << "\n"
<< "-- ParentID = " << aTrack.GetParentID() << "\n"
<< "-- Current KE = " << aTrack.GetKineticEnergy() / MeV
<< " MeV\n"
<< "-- Step EDep = " << aStep.GetTotalEnergyDeposit() / MeV
<< " MeV\n"
<< "-- Track EDep = " << ScintTrackEDep / MeV << " MeV\n"
<< "-- Vertex KE = " << aTrack.GetVertexKineticEnergy() / MeV
<< " MeV\n"
<< "-- Step yield = " << ScintillationYield << " photons\n"
<< "-- Track yield = " << ScintTrackYield << " photons\n"
<< G4endl;
// The track has terminated within or has left the scintillator volume
if((aTrack.GetTrackStatus() == fStopButAlive) or
(aStep.GetPostStepPoint()->GetStepStatus() == fGeomBoundary))
{
// Reset aggregators for the next track
ScintTrackEDep = 0.;
ScintTrackYield = 0.;
}
#endif
return ScintillationYield;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4Scintillation::GetScintillationYieldByParticleType(
const G4Track& aTrack, const G4Step& aStep, G4double& yield1,
@@ -1069,29 +844,25 @@ G4double G4Scintillation::GetScintillationYieldByParticleType(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4Scintillation::DumpPhysicsTable() const
{
G4PhysicsOrderedFreeVector* v;
if(fIntegralTable1)
{
for(size_t i = 0; i < fIntegralTable1->entries(); ++i)
{
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable1)[i];
v->DumpValues();
((G4PhysicsFreeVector*) (*fIntegralTable1)[i])->DumpValues();
}
}
if(fIntegralTable2)
{
for(size_t i = 0; i < fIntegralTable2->entries(); ++i)
{
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable2)[i];
v->DumpValues();
((G4PhysicsFreeVector*) (*fIntegralTable2)[i])->DumpValues();
}
}
if(fIntegralTable3)
{
for(size_t i = 0; i < fIntegralTable3->entries(); ++i)
{
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable3)[i];
v->DumpValues();
((G4PhysicsFreeVector*) (*fIntegralTable3)[i])->DumpValues();
}
}
}
@@ -23,8 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// Author : Valentin Libioulle valentin.libioulle@usherbrooke.ca (3IT - GRAMS)
//
@@ -23,198 +23,164 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
#include "G4StrawTubeXTRadiator.hh"
#include "G4Gamma.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4StrawTubeXTRadiator::G4StrawTubeXTRadiator(G4LogicalVolume *anEnvelope,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4Material* mediumMat,
G4bool unishut,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,1,processName)
G4StrawTubeXTRadiator::G4StrawTubeXTRadiator(G4LogicalVolume* anEnvelope,
G4Material* foilMat,
G4Material* gasMat, G4double a,
G4double b, G4Material* mediumMat,
G4bool unishut,
const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, 1, processName)
{
if(verboseLevel > 0)
G4cout<<"Straw tube X-ray TR radiator EM process is called"<<G4endl;
G4cout << "Straw tube X-ray TR radiator EM process is called" << G4endl;
if( unishut )
if(unishut)
{
fAlphaPlate = 1./3.;
fAlphaPlate = 1. / 3.;
fAlphaGas = 12.4;
if(verboseLevel > 0)
G4cout<<"straw uniform shooting: "<<"fAlphaPlate = "
<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl;
G4cout << "straw uniform shooting: "
<< "fAlphaPlate = " << fAlphaPlate
<< " ; fAlphaGas = " << fAlphaGas << G4endl;
}
else
{
fAlphaPlate = 0.5;
fAlphaGas = 5.;
if(verboseLevel > 0)
G4cout<<"straw isotropical shooting: "<<"fAlphaPlate = "
<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl;
G4cout << "straw isotropical shooting: "
<< "fAlphaPlate = " << fAlphaPlate
<< " ; fAlphaGas = " << fAlphaGas << G4endl;
}
// index of medium material
// index of medium material
fMatIndex3 = mediumMat->GetIndex();
if(verboseLevel > 0)
G4cout<<"medium material = "<<mediumMat->GetName()<<G4endl;
G4cout << "medium material = " << mediumMat->GetName() << G4endl;
// plasma energy squared for plate material
fSigma3 = fPlasmaCof*mediumMat->GetElectronDensity();
fSigma3 = fPlasmaCof * mediumMat->GetElectronDensity();
if(verboseLevel > 0)
G4cout<<"medium plasma energy = "<<std::sqrt(fSigma3)/eV<<" eV"<<G4endl;
G4cout << "medium plasma energy = " << std::sqrt(fSigma3) / eV << " eV"
<< G4endl;
// Compute cofs for preparation of linear photo absorption in external medium
ComputeMediumPhotoAbsCof();
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
// BuildTable();
}
///////////////////////////////////////////////////////////////////////////
G4StrawTubeXTRadiator::~G4StrawTubeXTRadiator() {}
G4StrawTubeXTRadiator::~G4StrawTubeXTRadiator()
void G4StrawTubeXTRadiator::ProcessDescription(std::ostream& out) const
{
out << "Simulation of forward X-ray transition radiation for the case of\n"
"a straw tube radiator.\n";
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// straw tube radiator. The plate (window, straw wall) and gas (inside straw)
// gap thicknesses are gamma distributed.
// The mean values of the plate and gas gap thicknesses
// straw tube radiator. The plate (window, straw wall) and gas (inside straw)
// gap thicknesses are gamma distributed.
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zone.
G4double
G4StrawTubeXTRadiator::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
G4double G4StrawTubeXTRadiator::GetStackFactor(G4double energy, G4double gamma,
G4double varAngle)
{
G4double result, L2, L3, M2, M3;
L2 = GetPlateFormationZone(energy,gamma,varAngle);
L3 = GetGasFormationZone(energy,gamma,varAngle);
L2 = GetPlateFormationZone(energy, gamma, varAngle);
L3 = GetGasFormationZone(energy, gamma, varAngle);
M2 = GetPlateLinearPhotoAbs(energy);
M3 = GetGasLinearPhotoAbs(energy);
G4complex C2(1.0 + 0.5*fPlateThick*M2/fAlphaPlate, fPlateThick/L2/fAlphaPlate);
G4complex C3(1.0 + 0.5*fGasThick*M3/fAlphaGas, fGasThick/L3/fAlphaGas);
G4complex C2(1.0 + 0.5 * fPlateThick * M2 / fAlphaPlate,
fPlateThick / L2 / fAlphaPlate);
G4complex C3(1.0 + 0.5 * fGasThick * M3 / fAlphaGas,
fGasThick / L3 / fAlphaGas);
G4complex H2 = std::pow(C2,-fAlphaPlate);
G4complex H3 = std::pow(C3,-fAlphaGas);
G4complex H = H2*H3;
G4complex H2 = std::pow(C2, -fAlphaPlate);
G4complex H3 = std::pow(C3, -fAlphaGas);
G4complex H = H2 * H3;
G4complex Z1 = GetMediumComplexFZ(energy,gamma,varAngle);
G4complex Z2 = GetPlateComplexFZ(energy,gamma,varAngle);
G4complex Z3 = GetGasComplexFZ(energy,gamma,varAngle);
G4complex Z1 = GetMediumComplexFZ(energy, gamma, varAngle);
G4complex Z2 = GetPlateComplexFZ(energy, gamma, varAngle);
G4complex Z3 = GetGasComplexFZ(energy, gamma, varAngle);
G4complex R = (Z1 - Z2) * (Z1 - Z2) * (1. - H2 * H) +
(Z2 - Z3) * (Z2 - Z3) * (1. - H3) +
2. * (Z1 - Z2) * (Z2 - Z3) * H2 * (1. - H3);
G4complex R = ( Z1 - Z2 )*( Z1 - Z2 )*( 1. - H2*H ) +
( Z2 - Z3 )*( Z2 - Z3 )*( 1. - H3 ) +
2.*( Z1 - Z2 )*( Z2 - Z3 )*H2*( 1. - H3 ) ;
result = 2.0*std::real(R)*(varAngle*energy/hbarc/hbarc);
return result;
result = 2.0 * std::real(R) * (varAngle * energy / hbarc / hbarc);
return result;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////
// Calculates formation zone for external medium. Omega is energy !!!
G4double G4StrawTubeXTRadiator::GetMediumFormationZone( G4double omega ,
G4double gamma ,
G4double varAngle )
G4double G4StrawTubeXTRadiator::GetMediumFormationZone(G4double omega,
G4double gamma,
G4double varAngle)
{
G4double cof, lambda;
lambda = 1.0/gamma/gamma + varAngle + fSigma3/omega/omega;
cof = 2.0*hbarc/omega/lambda ;
return cof ;
lambda = 1.0 / gamma / gamma + varAngle + fSigma3 / omega / omega;
cof = 2.0 * hbarc / omega / lambda;
return cof;
}
//////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////
// Calculates complex formation zone for external medium. Omega is energy !!!
G4complex G4StrawTubeXTRadiator::GetMediumComplexFZ( G4double omega ,
G4double gamma ,
G4double varAngle )
G4complex G4StrawTubeXTRadiator::GetMediumComplexFZ(G4double omega,
G4double gamma,
G4double varAngle)
{
G4double cof, length,delta, real_v, image_v;
G4double cof, length, delta, real_v, image_v;
length = 0.5*GetMediumFormationZone(omega,gamma,varAngle);
delta = length*GetMediumLinearPhotoAbs(omega);
cof = 1.0/(1.0 + delta*delta);
length = 0.5 * GetMediumFormationZone(omega, gamma, varAngle);
delta = length * GetMediumLinearPhotoAbs(omega);
cof = 1.0 / (1.0 + delta * delta);
real_v = length*cof;
image_v = real_v*delta;
real_v = length * cof;
image_v = real_v * delta;
G4complex zone(real_v,image_v);
G4complex zone(real_v, image_v);
return zone;
}
////////////////////////////////////////////////////////////////////////
//
// Computes matrix of Sandia photo absorption cross section coefficients for
// medium material
void G4StrawTubeXTRadiator::ComputeMediumPhotoAbsCof()
void G4StrawTubeXTRadiator::ComputeMediumPhotoAbsCof()
{
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
const G4Material* mat = (*theMaterialTable)[fMatIndex3];
fMediumPhotoAbsCof = mat->GetSandiaTable();
const G4Material* mat = (*theMaterialTable)[fMatIndex3];
fMediumPhotoAbsCof = mat->GetSandiaTable();
}
//////////////////////////////////////////////////////////////////////
//
// Returns the value of linear photo absorption coefficient (in reciprocal
// Returns the value of linear photo absorption coefficient (in reciprocal
// length) for medium for given energy of X-ray photon omega
G4double G4StrawTubeXTRadiator::GetMediumLinearPhotoAbs(G4double omega)
G4double G4StrawTubeXTRadiator::GetMediumLinearPhotoAbs(G4double omega)
{
G4double omega2, omega3, omega4;
G4double omega2, omega3, omega4;
omega2 = omega*omega;
omega3 = omega2*omega;
omega4 = omega2*omega2;
omega2 = omega * omega;
omega3 = omega2 * omega;
omega4 = omega2 * omega2;
const G4double* SandiaCof = fMediumPhotoAbsCof->GetSandiaCofForMaterial(omega);
const G4double* SandiaCof =
fMediumPhotoAbsCof->GetSandiaCofForMaterial(omega);
G4double cross = SandiaCof[0]/omega + SandiaCof[1]/omega2 +
SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
G4double cross = SandiaCof[0] / omega + SandiaCof[1] / omega2 +
SandiaCof[2] / omega3 + SandiaCof[3] / omega4;
return cross;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -23,42 +23,39 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
//
// History: first implementation,
// History: first implementation,
// 21-5-98 V.Grichine
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
// 04.03.05, V.Grichine: get local field interface
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
// 04.03.05, V.Grichine: get local field interface
// 18-05-06 H. Burkhardt: Energy spectrum from function rather than table
//
//
//
//
///////////////////////////////////////////////////////////////////////////
#include "G4SynchrotronRadiation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4EmProcessSubType.hh"
#include "G4DipBustGenerator.hh"
#include "G4Electron.hh"
#include "G4EmProcessSubType.hh"
#include "G4Log.hh"
#include "G4LossTableManager.hh"
#include "G4Gamma.hh"
#include "G4PhysicalConstants.hh"
#include "G4PropagatorInField.hh"
#include "G4SystemOfUnits.hh"
#include "G4TransportationManager.hh"
#include "G4UnitsTable.hh"
///////////////////////////////////////////////////////////////////////
//
// Constructor
//
G4SynchrotronRadiation::G4SynchrotronRadiation(const G4String& processName,
G4ProcessType type):G4VDiscreteProcess (processName, type),
theGamma (G4Gamma::Gamma() )
G4ProcessType type)
: G4VDiscreteProcess(processName, type)
, theGamma(G4Gamma::Gamma())
{
G4TransportationManager* transportMgr =
G4TransportationManager* transportMgr =
G4TransportationManager::GetTransportationManager();
fFieldPropagator = transportMgr->GetPropagatorInField();
@@ -74,10 +71,7 @@ G4SynchrotronRadiation::G4SynchrotronRadiation(const G4String& processName,
}
/////////////////////////////////////////////////////////////////////////
//
// Destructor
//
G4SynchrotronRadiation::~G4SynchrotronRadiation()
{
delete genAngle;
@@ -85,122 +79,115 @@ G4SynchrotronRadiation::~G4SynchrotronRadiation()
}
/////////////////////////////// METHODS /////////////////////////////////
//
void
G4SynchrotronRadiation::SetAngularGenerator(G4VEmAngularDistribution* p)
void G4SynchrotronRadiation::SetAngularGenerator(G4VEmAngularDistribution* p)
{
if(p != genAngle) {
if(p != genAngle)
{
delete genAngle;
genAngle = p;
}
}
G4bool
G4SynchrotronRadiation::IsApplicable(const G4ParticleDefinition& particle)
G4bool G4SynchrotronRadiation::IsApplicable(
const G4ParticleDefinition& particle)
{
return (particle.GetPDGCharge() != 0.0 && !particle.IsShortLived());
return (particle.GetPDGCharge() != 0.0 && !particle.IsShortLived());
}
/////////////////////////////////////////////////////////////////////////
//
// Production of synchrotron X-ray photon
// GEANT4 internal units.
//
G4double
G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
G4double,
G4ForceCondition* condition)
// Geant4 internal units.
G4double G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
G4double,
G4ForceCondition* condition)
{
// gives the MeanFreePath in GEANT4 internal units
// gives the MeanFreePath in Geant4 internal units
G4double MeanFreePath = DBL_MAX;
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
*condition = NotForced;
G4double gamma = aDynamicParticle->GetTotalEnergy()/
aDynamicParticle->GetMass();
G4double gamma =
aDynamicParticle->GetTotalEnergy() / aDynamicParticle->GetMass();
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
if ( gamma < 1.0e3 || 0.0 == particleCharge) { MeanFreePath = DBL_MAX; }
if(gamma < 1.0e3 || 0.0 == particleCharge)
{
MeanFreePath = DBL_MAX;
}
else
{
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4bool fieldExertsForce = false;
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr =
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
G4FieldManager* fieldMgr =
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
if ( fieldMgr != nullptr )
if(fieldMgr != nullptr)
{
// If the field manager has no field, there is no field !
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
}
if ( fieldExertsForce )
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
if(fieldExertsForce)
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
globPosVec[0] = globPosition.x();
globPosVec[1] = globPosition.y();
globPosVec[2] = globPosition.z();
globPosVec[3] = trackData.GetGlobalTime();
pField->GetFieldValue( globPosVec, FieldValueVec );
pField->GetFieldValue(globPosVec, FieldValueVec);
FieldValue = G4ThreeVector( FieldValueVec[0],
FieldValueVec[1],
FieldValueVec[2] );
FieldValue =
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
static const G4double fLambdaConst = std::sqrt(3.0)*eplus/
(2.5*fine_structure_const*c_light);
if( perpB > 0.0 )
static const G4double fLambdaConst =
std::sqrt(3.0) * eplus / (2.5 * fine_structure_const * c_light);
if(perpB > 0.0)
{
MeanFreePath =
fLambdaConst*aDynamicParticle->GetDefinition()->GetPDGMass()
/(perpB*particleCharge*particleCharge);
MeanFreePath = fLambdaConst *
aDynamicParticle->GetDefinition()->GetPDGMass() /
(perpB * particleCharge * particleCharge);
}
if(verboseLevel > 0 && FirstTime)
{
G4cout << "G4SynchrotronRadiation::GetMeanFreePath "
<< " for particle "
<< aDynamicParticle->GetDefinition()->GetParticleName()
<< ":" << '\n' //hbunew
<< " MeanFreePath = " << G4BestUnit(MeanFreePath, "Length")
<< G4endl;
<< " for particle "
<< aDynamicParticle->GetDefinition()->GetParticleName() << ":"
<< '\n'
<< " MeanFreePath = " << G4BestUnit(MeanFreePath, "Length")
<< G4endl;
if(verboseLevel > 1)
{
G4ThreeVector pvec = aDynamicParticle->GetMomentum();
G4double Btot = FieldValue.getR();
G4double ptot = pvec.getR();
G4double rho = ptot / (MeV * c_light * Btot );
// full bending radius
G4double Theta=unitMomentum.theta(FieldValue);
// angle between particle and field
G4cout << " B = " << Btot/tesla << " Tesla"
<< " perpB = " << perpB/tesla << " Tesla"
<< " Theta = " << Theta << " std::sin(Theta)="
<< std::sin(Theta) << '\n'
<< " ptot = " << G4BestUnit(ptot,"Energy")
<< " rho = " << G4BestUnit(rho,"Length")
<< G4endl;
G4double Btot = FieldValue.getR();
G4double ptot = pvec.getR();
G4double rho = ptot / (MeV * c_light * Btot);
// full bending radius
G4double Theta = unitMomentum.theta(FieldValue);
// angle between particle and field
G4cout << " B = " << Btot / tesla << " Tesla"
<< " perpB = " << perpB / tesla << " Tesla"
<< " Theta = " << Theta
<< " std::sin(Theta)=" << std::sin(Theta) << '\n'
<< " ptot = " << G4BestUnit(ptot, "Energy")
<< " rho = " << G4BestUnit(rho, "Length") << G4endl;
}
FirstTime=false;
FirstTime = false;
}
}
}
@@ -208,220 +195,229 @@ G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
}
///////////////////////////////////////////////////////////////////////////////
//
//
G4VParticleChange*
G4SynchrotronRadiation::PostStepDoIt(const G4Track& trackData,
const G4Step& stepData )
G4VParticleChange* G4SynchrotronRadiation::PostStepDoIt(
const G4Track& trackData, const G4Step& stepData)
{
aParticleChange.Initialize(trackData);
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
G4double gamma = aDynamicParticle->GetTotalEnergy()/
(aDynamicParticle->GetDefinition()->GetPDGMass());
G4double gamma = aDynamicParticle->GetTotalEnergy() /
(aDynamicParticle->GetDefinition()->GetPDGMass());
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
if(gamma <= 1.0e3 || 0.0 == particleCharge)
if(gamma <= 1.0e3 || 0.0 == particleCharge)
{
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr =
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr =
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
if ( fieldMgr != nullptr )
if(fieldMgr != nullptr)
{
// If the field manager has no field, there is no field !
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
}
if ( fieldExertsForce )
if(fieldExertsForce)
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
globPosVec[0] = globPosition.x();
globPosVec[1] = globPosition.y();
globPosVec[2] = globPosition.z();
globPosVec[3] = trackData.GetGlobalTime();
pField->GetFieldValue( globPosVec, FieldValueVec );
FieldValue = G4ThreeVector( FieldValueVec[0],
FieldValueVec[1],
FieldValueVec[2] );
pField->GetFieldValue(globPosVec, FieldValueVec);
FieldValue =
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
if(perpB > 0.0)
{
// M-C of synchrotron photon energy
G4double energyOfSR =
GetRandomEnergySR(gamma,perpB,
aDynamicParticle->GetDefinition()->GetPDGMass());
G4double energyOfSR = GetRandomEnergySR(
gamma, perpB, aDynamicParticle->GetDefinition()->GetPDGMass());
// check against insufficient energy
if( energyOfSR <= 0.0 )
if(energyOfSR <= 0.0)
{
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
G4ThreeVector gammaDirection =
genAngle->SampleDirection(aDynamicParticle,
energyOfSR, 1, 0);
G4ThreeVector gammaDirection =
genAngle->SampleDirection(aDynamicParticle, energyOfSR, 1, 0);
G4ThreeVector gammaPolarization = FieldValue.cross(gammaDirection);
gammaPolarization = gammaPolarization.unit();
gammaPolarization = gammaPolarization.unit();
// create G4DynamicParticle object for the SR photon
G4DynamicParticle* aGamma= new G4DynamicParticle ( theGamma,
gammaDirection,
energyOfSR );
aGamma->SetPolarization( gammaPolarization.x(),
gammaPolarization.y(),
gammaPolarization.z() );
G4DynamicParticle* aGamma =
new G4DynamicParticle(theGamma, gammaDirection, energyOfSR);
aGamma->SetPolarization(gammaPolarization.x(), gammaPolarization.y(),
gammaPolarization.z());
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(aGamma);
// Update the incident particle
G4double newKinEnergy = kineticEnergy - energyOfSR;
if (newKinEnergy > 0.)
if(newKinEnergy > 0.)
{
aParticleChange.ProposeEnergy( newKinEnergy );
aParticleChange.ProposeEnergy(newKinEnergy);
}
else
{
aParticleChange.ProposeEnergy( 0. );
aParticleChange.ProposeEnergy(0.);
}
}
}
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
///////////////////////////////////////////////////////////////////////////////
//
//
G4double G4SynchrotronRadiation::InvSynFracInt(G4double x)
// direct generation
{
// from 0 to 0.7
static const G4double aa1=0 ,aa2=0.7;
static const G4int ncheb1=27;
static const G4double cheb1[] =
{ 1.22371665676046468821,0.108956475422163837267,0.0383328524358594396134,0.00759138369340257753721,
0.00205712048644963340914,0.000497810783280019308661,0.000130743691810302187818,0.0000338168760220395409734,
8.97049680900520817728e-6,2.38685472794452241466e-6,6.41923109149104165049e-7,1.73549898982749277843e-7,
4.72145949240790029153e-8,1.29039866111999149636e-8,3.5422080787089834182e-9,9.7594757336403784905e-10,
2.6979510184976065731e-10,7.480422622550977077e-11,2.079598176402699913e-11,5.79533622220841193e-12,
1.61856011449276096e-12,4.529450993473807e-13,1.2698603951096606e-13,3.566117394511206e-14,1.00301587494091e-14,
2.82515346447219e-15,7.9680747949792e-16};
static constexpr G4double aa1 = 0;
static constexpr G4double aa2 = 0.7;
static constexpr G4int ncheb1 = 27;
static constexpr G4double cheb1[ncheb1] = {
1.22371665676046468821, 0.108956475422163837267,
0.0383328524358594396134, 0.00759138369340257753721,
0.00205712048644963340914, 0.000497810783280019308661,
0.000130743691810302187818, 0.0000338168760220395409734,
8.97049680900520817728e-6, 2.38685472794452241466e-6,
6.41923109149104165049e-7, 1.73549898982749277843e-7,
4.72145949240790029153e-8, 1.29039866111999149636e-8,
3.5422080787089834182e-9, 9.7594757336403784905e-10,
2.6979510184976065731e-10, 7.480422622550977077e-11,
2.079598176402699913e-11, 5.79533622220841193e-12,
1.61856011449276096e-12, 4.529450993473807e-13,
1.2698603951096606e-13, 3.566117394511206e-14,
1.00301587494091e-14, 2.82515346447219e-15,
7.9680747949792e-16
};
// from 0.7 to 0.9132260271183847
static const G4double aa3=0.9132260271183847;
static const G4int ncheb2=27;
static const G4double cheb2[] =
{ 1.1139496701107756,0.3523967429328067,0.0713849171926623,0.01475818043595387,0.003381255637322462,
0.0008228057599452224,0.00020785506681254216,0.00005390169253706556,0.000014250571923902464,3.823880733161044e-6,
1.0381966089136036e-6,2.8457557457837253e-7,7.86223332179956e-8,2.1866609342508474e-8,6.116186259857143e-9,
1.7191233618437565e-9,4.852755117740807e-10,1.3749966961763457e-10,3.908961987062447e-11,1.1146253766895824e-11,
3.1868887323415814e-12,9.134319791300977e-13,2.6211077371181566e-13,7.588643377757906e-14,2.1528376972619e-14,
6.030906040404772e-15,1.9549163926819867e-15};
// Chebyshev with exp/log scale
// a = -Log[1 - SynFracInt[1]]; b = -Log[1 - SynFracInt[7]];
static const G4double aa4=2.4444485538746025480,aa5=9.3830728608909477079;
static const G4int ncheb3=28;
static const G4double cheb3[] =
{ 1.2292683840435586977,0.160353449247864455879,-0.0353559911947559448721,0.00776901561223573936985,
-0.00165886451971685133259,0.000335719118906954279467,-0.0000617184951079161143187,9.23534039743246708256e-6,
-6.06747198795168022842e-7,-3.07934045961999778094e-7,1.98818772614682367781e-7,-8.13909971567720135413e-8,
2.84298174969641838618e-8,-9.12829766621316063548e-9,2.77713868004820551077e-9,-8.13032767247834023165e-10,
2.31128525568385247392e-10,-6.41796873254200220876e-11,1.74815310473323361543e-11,-4.68653536933392363045e-12,
1.24016595805520752748e-12,-3.24839432979935522159e-13,8.44601465226513952994e-14,-2.18647276044246803998e-14,
5.65407548745690689978e-15,-1.46553625917463067508e-15,3.82059606377570462276e-16,-1.00457896653436912508e-16};
static const G4double aa6=33.122936966163038145;
static const G4int ncheb4=27;
static const G4double cheb4[] =
{1.69342658227676741765,0.0742766400841232319225,-0.019337880608635717358,0.00516065527473364110491,
-0.00139342012990307729473,0.000378549864052022522193,-0.000103167085583785340215,0.0000281543441271412178337,
-7.68409742018258198651e-6,2.09543221890204537392e-6,-5.70493140367526282946e-7,1.54961164548564906446e-7,
-4.19665599629607704794e-8,1.13239680054166507038e-8,-3.04223563379021441863e-9,8.13073745977562957997e-10,
-2.15969415476814981374e-10,5.69472105972525594811e-11,-1.48844799572430829499e-11,3.84901514438304484973e-12,
-9.82222575944247161834e-13,2.46468329208292208183e-13,-6.04953826265982691612e-14,1.44055805710671611984e-14,
-3.28200813577388740722e-15,6.96566359173765367675e-16,-1.294122794852896275e-16};
static constexpr G4double aa3 = 0.9132260271183847;
static constexpr G4int ncheb2 = 27;
static constexpr G4double cheb2[ncheb2] = {
1.1139496701107756, 0.3523967429328067, 0.0713849171926623,
0.01475818043595387, 0.003381255637322462, 0.0008228057599452224,
0.00020785506681254216, 0.00005390169253706556, 0.000014250571923902464,
3.823880733161044e-6, 1.0381966089136036e-6, 2.8457557457837253e-7,
7.86223332179956e-8, 2.1866609342508474e-8, 6.116186259857143e-9,
1.7191233618437565e-9, 4.852755117740807e-10, 1.3749966961763457e-10,
3.908961987062447e-11, 1.1146253766895824e-11, 3.1868887323415814e-12,
9.134319791300977e-13, 2.6211077371181566e-13, 7.588643377757906e-14,
2.1528376972619e-14, 6.030906040404772e-15, 1.9549163926819867e-15
};
// Chebyshev with exp/log scale
// a = -Log[1 - SynFracInt[1]]; b = -Log[1 - SynFracInt[7]];
static constexpr G4double aa4 = 2.4444485538746025480;
static constexpr G4double aa5 = 9.3830728608909477079;
static constexpr G4int ncheb3 = 28;
static constexpr G4double cheb3[ncheb3] = {
1.2292683840435586977, 0.160353449247864455879,
-0.0353559911947559448721, 0.00776901561223573936985,
-0.00165886451971685133259, 0.000335719118906954279467,
-0.0000617184951079161143187, 9.23534039743246708256e-6,
-6.06747198795168022842e-7, -3.07934045961999778094e-7,
1.98818772614682367781e-7, -8.13909971567720135413e-8,
2.84298174969641838618e-8, -9.12829766621316063548e-9,
2.77713868004820551077e-9, -8.13032767247834023165e-10,
2.31128525568385247392e-10, -6.41796873254200220876e-11,
1.74815310473323361543e-11, -4.68653536933392363045e-12,
1.24016595805520752748e-12, -3.24839432979935522159e-13,
8.44601465226513952994e-14, -2.18647276044246803998e-14,
5.65407548745690689978e-15, -1.46553625917463067508e-15,
3.82059606377570462276e-16, -1.00457896653436912508e-16
};
static constexpr G4double aa6 = 33.122936966163038145;
static constexpr G4int ncheb4 = 27;
static constexpr G4double cheb4[ncheb4] = {
1.69342658227676741765, 0.0742766400841232319225,
-0.019337880608635717358, 0.00516065527473364110491,
-0.00139342012990307729473, 0.000378549864052022522193,
-0.000103167085583785340215, 0.0000281543441271412178337,
-7.68409742018258198651e-6, 2.09543221890204537392e-6,
-5.70493140367526282946e-7, 1.54961164548564906446e-7,
-4.19665599629607704794e-8, 1.13239680054166507038e-8,
-3.04223563379021441863e-9, 8.13073745977562957997e-10,
-2.15969415476814981374e-10, 5.69472105972525594811e-11,
-1.48844799572430829499e-11, 3.84901514438304484973e-12,
-9.82222575944247161834e-13, 2.46468329208292208183e-13,
-6.04953826265982691612e-14, 1.44055805710671611984e-14,
-3.28200813577388740722e-15, 6.96566359173765367675e-16,
-1.294122794852896275e-16
};
if(x<aa2) return x*x*x*Chebyshev(aa1,aa2,cheb1,ncheb1,x);
else if(x<aa3) return Chebyshev(aa2,aa3,cheb2,ncheb2,x);
else if(x<1-0.0000841363)
{ G4double y=-G4Log(1-x);
return y*Chebyshev(aa4,aa5,cheb3,ncheb3,y);
if(x < aa2)
return x * x * x * Chebyshev(aa1, aa2, cheb1, ncheb1, x);
else if(x < aa3)
return Chebyshev(aa2, aa3, cheb2, ncheb2, x);
else if(x < 1 - 0.0000841363)
{
G4double y = -G4Log(1 - x);
return y * Chebyshev(aa4, aa5, cheb3, ncheb3, y);
}
else
{ G4double y=-G4Log(1-x);
return y*Chebyshev(aa5,aa6,cheb4,ncheb4,y);
{
G4double y = -G4Log(1 - x);
return y * Chebyshev(aa5, aa6, cheb4, ncheb4, y);
}
}
G4double G4SynchrotronRadiation::GetRandomEnergySR(
G4double gamma, G4double perpB, G4double mass_c2)
G4double G4SynchrotronRadiation::GetRandomEnergySR(G4double gamma,
G4double perpB,
G4double mass_c2)
{
static const G4double fEnergyConst = 1.5*c_light*c_light*eplus*hbar_Planck;
G4double Ecr=fEnergyConst*gamma*gamma*perpB/mass_c2;
static const G4double fEnergyConst =
1.5 * c_light * c_light * eplus * hbar_Planck;
G4double Ecr = fEnergyConst * gamma * gamma * perpB / mass_c2;
if(verboseLevel > 0 && FirstTime1)
{
// mean and rms of photon energy
G4double Emean=8./(15.*std::sqrt(3.))*Ecr;
G4double E_rms=std::sqrt(211./675.)*Ecr;
G4int prec = G4cout.precision();
G4cout << "G4SynchrotronRadiation::GetRandomEnergySR :" << '\n'
<< std::setprecision(4)
<< " Ecr = " << G4BestUnit(Ecr,"Energy") << '\n'
<< " Emean = " << G4BestUnit(Emean,"Energy") << '\n'
<< " E_rms = " << G4BestUnit(E_rms,"Energy") << G4endl;
FirstTime1=false;
G4cout.precision(prec);
{
// mean and rms of photon energy
G4double Emean = 8. / (15. * std::sqrt(3.)) * Ecr;
G4double E_rms = std::sqrt(211. / 675.) * Ecr;
G4int prec = G4cout.precision();
G4cout << "G4SynchrotronRadiation::GetRandomEnergySR :" << '\n'
<< std::setprecision(4) << " Ecr = " << G4BestUnit(Ecr, "Energy")
<< '\n'
<< " Emean = " << G4BestUnit(Emean, "Energy") << '\n'
<< " E_rms = " << G4BestUnit(E_rms, "Energy") << G4endl;
FirstTime1 = false;
G4cout.precision(prec);
}
G4double energySR=Ecr*InvSynFracInt(G4UniformRand());
G4double energySR = Ecr * InvSynFracInt(G4UniformRand());
return energySR;
}
///////////////////////////////////////////////////////////////////////////////
//
//
void
G4SynchrotronRadiation::BuildPhysicsTable(const G4ParticleDefinition& part)
void G4SynchrotronRadiation::BuildPhysicsTable(const G4ParticleDefinition& part)
{
if(0 < verboseLevel && &part==G4Electron::Electron() ) PrintInfoDefinition();
if(0 < verboseLevel && &part == G4Electron::Electron())
ProcessDescription(G4cout);
// same for all particles, print only for one (electron)
}
///////////////////////////////////////////////////////////////////////////////
//
//
void G4SynchrotronRadiation::PrintInfoDefinition()
// not yet called, usually called from BuildPhysicsTable
void G4SynchrotronRadiation::ProcessDescription(std::ostream& out) const
{
G4String comments ="Incoherent Synchrotron Radiation\n";
G4cout << G4endl << GetProcessName() << ": " << comments
<< " good description for long magnets at all energies"
<< G4endl;
out << GetProcessName()
<< ": Incoherent Synchrotron Radiation\n"
"Good description for long magnets at all energies.\n";
}
///////////////////// end of G4SynchrotronRadiation.cc
@@ -23,11 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
//
// History: first implementation,
// 21-5-98 V.Grichine
@@ -35,650 +32,553 @@
// 04.03.05, V.Grichine: get local field interface
// 19-05-06, V.Ivanchenko rename from G4SynchrotronRadiation
//
//
///////////////////////////////////////////////////////////////////////////
#include "G4SynchrotronRadiationInMat.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Integrator.hh"
#include "G4EmProcessSubType.hh"
#include "G4Field.hh"
#include "G4FieldManager.hh"
#include "G4Integrator.hh"
#include "G4PhysicalConstants.hh"
#include "G4PropagatorInField.hh"
#include "G4SystemOfUnits.hh"
////////////////////////////////////////////////////////////////////
//
// Constant for calculation of mean free path
//
const G4double
G4SynchrotronRadiationInMat::fLambdaConst = std::sqrt(3.0)*electron_mass_c2/
(2.5*fine_structure_const*eplus*c_light) ;
/////////////////////////////////////////////////////////////////////
//
// Constant for calculation of characterictic energy
//
const G4double
G4SynchrotronRadiationInMat::fEnergyConst = 1.5*c_light*c_light*eplus*hbar_Planck/
electron_mass_c2 ;
////////////////////////////////////////////////////////////////////
//
// Array of integral probability of synchrotron photons:
//
// the corresponding energy = 0.0001*i*i*(characteristic energy)
//
const G4double
G4SynchrotronRadiationInMat::fIntegralProbabilityOfSR[200] =
{
1.000000e+00, 9.428859e-01, 9.094095e-01, 8.813971e-01, 8.565154e-01,
8.337008e-01, 8.124961e-01, 7.925217e-01, 7.735517e-01, 7.554561e-01,
7.381233e-01, 7.214521e-01, 7.053634e-01, 6.898006e-01, 6.747219e-01,
6.600922e-01, 6.458793e-01, 6.320533e-01, 6.185872e-01, 6.054579e-01,
5.926459e-01, 5.801347e-01, 5.679103e-01, 5.559604e-01, 5.442736e-01,
5.328395e-01, 5.216482e-01, 5.106904e-01, 4.999575e-01, 4.894415e-01,
4.791351e-01, 4.690316e-01, 4.591249e-01, 4.494094e-01, 4.398800e-01,
4.305320e-01, 4.213608e-01, 4.123623e-01, 4.035325e-01, 3.948676e-01,
3.863639e-01, 3.780179e-01, 3.698262e-01, 3.617858e-01, 3.538933e-01,
3.461460e-01, 3.385411e-01, 3.310757e-01, 3.237474e-01, 3.165536e-01,
3.094921e-01, 3.025605e-01, 2.957566e-01, 2.890784e-01, 2.825237e-01,
2.760907e-01, 2.697773e-01, 2.635817e-01, 2.575020e-01, 2.515365e-01,
2.456834e-01, 2.399409e-01, 2.343074e-01, 2.287812e-01, 2.233607e-01,
2.180442e-01, 2.128303e-01, 2.077174e-01, 2.027040e-01, 1.977885e-01,
1.929696e-01, 1.882457e-01, 1.836155e-01, 1.790775e-01, 1.746305e-01,
1.702730e-01, 1.660036e-01, 1.618212e-01, 1.577243e-01, 1.537117e-01,
1.497822e-01, 1.459344e-01, 1.421671e-01, 1.384791e-01, 1.348691e-01,
1.313360e-01, 1.278785e-01, 1.244956e-01, 1.211859e-01, 1.179483e-01,
1.147818e-01, 1.116850e-01, 1.086570e-01, 1.056966e-01, 1.028026e-01,
9.997405e-02, 9.720975e-02, 9.450865e-02, 9.186969e-02, 8.929179e-02,
8.677391e-02, 8.431501e-02, 8.191406e-02, 7.957003e-02, 7.728192e-02,
7.504872e-02, 7.286944e-02, 7.074311e-02, 6.866874e-02, 6.664538e-02,
6.467208e-02, 6.274790e-02, 6.087191e-02, 5.904317e-02, 5.726079e-02,
5.552387e-02, 5.383150e-02, 5.218282e-02, 5.057695e-02, 4.901302e-02,
4.749020e-02, 4.600763e-02, 4.456450e-02, 4.315997e-02, 4.179325e-02,
4.046353e-02, 3.917002e-02, 3.791195e-02, 3.668855e-02, 3.549906e-02,
3.434274e-02, 3.321884e-02, 3.212665e-02, 3.106544e-02, 3.003452e-02,
2.903319e-02, 2.806076e-02, 2.711656e-02, 2.619993e-02, 2.531021e-02,
2.444677e-02, 2.360897e-02, 2.279620e-02, 2.200783e-02, 2.124327e-02,
2.050194e-02, 1.978324e-02, 1.908662e-02, 1.841151e-02, 1.775735e-02,
1.712363e-02, 1.650979e-02, 1.591533e-02, 1.533973e-02, 1.478250e-02,
1.424314e-02, 1.372117e-02, 1.321613e-02, 1.272755e-02, 1.225498e-02,
1.179798e-02, 1.135611e-02, 1.092896e-02, 1.051609e-02, 1.011712e-02,
9.731635e-03, 9.359254e-03, 8.999595e-03, 8.652287e-03, 8.316967e-03,
7.993280e-03, 7.680879e-03, 7.379426e-03, 7.088591e-03, 6.808051e-03,
6.537491e-03, 6.276605e-03, 6.025092e-03, 5.782661e-03, 5.549027e-03,
5.323912e-03, 5.107045e-03, 4.898164e-03, 4.697011e-03, 4.503336e-03,
4.316896e-03, 4.137454e-03, 3.964780e-03, 3.798649e-03, 3.638843e-03,
3.485150e-03, 3.337364e-03, 3.195284e-03, 3.058715e-03, 2.927469e-03,
2.801361e-03, 2.680213e-03, 2.563852e-03, 2.452110e-03, 2.344824e-03
const G4double G4SynchrotronRadiationInMat::fIntegralProbabilityOfSR[200] = {
1.000000e+00, 9.428859e-01, 9.094095e-01, 8.813971e-01, 8.565154e-01,
8.337008e-01, 8.124961e-01, 7.925217e-01, 7.735517e-01, 7.554561e-01,
7.381233e-01, 7.214521e-01, 7.053634e-01, 6.898006e-01, 6.747219e-01,
6.600922e-01, 6.458793e-01, 6.320533e-01, 6.185872e-01, 6.054579e-01,
5.926459e-01, 5.801347e-01, 5.679103e-01, 5.559604e-01, 5.442736e-01,
5.328395e-01, 5.216482e-01, 5.106904e-01, 4.999575e-01, 4.894415e-01,
4.791351e-01, 4.690316e-01, 4.591249e-01, 4.494094e-01, 4.398800e-01,
4.305320e-01, 4.213608e-01, 4.123623e-01, 4.035325e-01, 3.948676e-01,
3.863639e-01, 3.780179e-01, 3.698262e-01, 3.617858e-01, 3.538933e-01,
3.461460e-01, 3.385411e-01, 3.310757e-01, 3.237474e-01, 3.165536e-01,
3.094921e-01, 3.025605e-01, 2.957566e-01, 2.890784e-01, 2.825237e-01,
2.760907e-01, 2.697773e-01, 2.635817e-01, 2.575020e-01, 2.515365e-01,
2.456834e-01, 2.399409e-01, 2.343074e-01, 2.287812e-01, 2.233607e-01,
2.180442e-01, 2.128303e-01, 2.077174e-01, 2.027040e-01, 1.977885e-01,
1.929696e-01, 1.882457e-01, 1.836155e-01, 1.790775e-01, 1.746305e-01,
1.702730e-01, 1.660036e-01, 1.618212e-01, 1.577243e-01, 1.537117e-01,
1.497822e-01, 1.459344e-01, 1.421671e-01, 1.384791e-01, 1.348691e-01,
1.313360e-01, 1.278785e-01, 1.244956e-01, 1.211859e-01, 1.179483e-01,
1.147818e-01, 1.116850e-01, 1.086570e-01, 1.056966e-01, 1.028026e-01,
9.997405e-02, 9.720975e-02, 9.450865e-02, 9.186969e-02, 8.929179e-02,
8.677391e-02, 8.431501e-02, 8.191406e-02, 7.957003e-02, 7.728192e-02,
7.504872e-02, 7.286944e-02, 7.074311e-02, 6.866874e-02, 6.664538e-02,
6.467208e-02, 6.274790e-02, 6.087191e-02, 5.904317e-02, 5.726079e-02,
5.552387e-02, 5.383150e-02, 5.218282e-02, 5.057695e-02, 4.901302e-02,
4.749020e-02, 4.600763e-02, 4.456450e-02, 4.315997e-02, 4.179325e-02,
4.046353e-02, 3.917002e-02, 3.791195e-02, 3.668855e-02, 3.549906e-02,
3.434274e-02, 3.321884e-02, 3.212665e-02, 3.106544e-02, 3.003452e-02,
2.903319e-02, 2.806076e-02, 2.711656e-02, 2.619993e-02, 2.531021e-02,
2.444677e-02, 2.360897e-02, 2.279620e-02, 2.200783e-02, 2.124327e-02,
2.050194e-02, 1.978324e-02, 1.908662e-02, 1.841151e-02, 1.775735e-02,
1.712363e-02, 1.650979e-02, 1.591533e-02, 1.533973e-02, 1.478250e-02,
1.424314e-02, 1.372117e-02, 1.321613e-02, 1.272755e-02, 1.225498e-02,
1.179798e-02, 1.135611e-02, 1.092896e-02, 1.051609e-02, 1.011712e-02,
9.731635e-03, 9.359254e-03, 8.999595e-03, 8.652287e-03, 8.316967e-03,
7.993280e-03, 7.680879e-03, 7.379426e-03, 7.088591e-03, 6.808051e-03,
6.537491e-03, 6.276605e-03, 6.025092e-03, 5.782661e-03, 5.549027e-03,
5.323912e-03, 5.107045e-03, 4.898164e-03, 4.697011e-03, 4.503336e-03,
4.316896e-03, 4.137454e-03, 3.964780e-03, 3.798649e-03, 3.638843e-03,
3.485150e-03, 3.337364e-03, 3.195284e-03, 3.058715e-03, 2.927469e-03,
2.801361e-03, 2.680213e-03, 2.563852e-03, 2.452110e-03, 2.344824e-03
};
///////////////////////////////////////////////////////////////////////
//
// Constructor
//
G4SynchrotronRadiationInMat::G4SynchrotronRadiationInMat(const G4String& processName,
G4ProcessType type):G4VDiscreteProcess (processName, type),
LowestKineticEnergy (10.*keV),
theGamma (G4Gamma::Gamma() ),
theElectron ( G4Electron::Electron() ),
thePositron ( G4Positron::Positron() ),
fAlpha(0.0), fRootNumber(80),
fVerboseLevel( verboseLevel )
///////////////////////////////////////////////////////////////////////
// Constructor
G4SynchrotronRadiationInMat::G4SynchrotronRadiationInMat(
const G4String& processName, G4ProcessType type)
: G4VDiscreteProcess(processName, type)
, theGamma(G4Gamma::Gamma())
, theElectron(G4Electron::Electron())
, thePositron(G4Positron::Positron())
, LowestKineticEnergy(10. * keV)
, fAlpha(0.0)
, fRootNumber(80)
, fVerboseLevel(verboseLevel)
{
G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager();
G4TransportationManager* transportMgr =
G4TransportationManager::GetTransportationManager();
fFieldPropagator = transportMgr->GetPropagatorInField();
SetProcessSubType(fSynchrotronRadiation);
CutInRange = GammaCutInKineticEnergyNow = ElectronCutInKineticEnergyNow =
PositronCutInKineticEnergyNow = ParticleCutInKineticEnergyNow = fKsi =
fPsiGamma = fEta = fOrderAngleK = 0.0;
CutInRange = GammaCutInKineticEnergyNow = ElectronCutInKineticEnergyNow =
PositronCutInKineticEnergyNow = ParticleCutInKineticEnergyNow = fKsi =
fPsiGamma = fEta = fOrderAngleK = 0.0;
}
/////////////////////////////////////////////////////////////////////////
//
// Destructor
//
G4SynchrotronRadiationInMat::~G4SynchrotronRadiationInMat()
{}
G4SynchrotronRadiationInMat::~G4SynchrotronRadiationInMat() {}
G4bool
G4SynchrotronRadiationInMat::IsApplicable( const G4ParticleDefinition& particle )
G4bool G4SynchrotronRadiationInMat::IsApplicable(
const G4ParticleDefinition& particle)
{
return ( ( &particle == (const G4ParticleDefinition *)theElectron ) ||
( &particle == (const G4ParticleDefinition *)thePositron ));
return ((&particle == (const G4ParticleDefinition*) theElectron) ||
(&particle == (const G4ParticleDefinition*) thePositron));
}
G4double G4SynchrotronRadiationInMat::GetLambdaConst()
{
return fLambdaConst;
}
G4double G4SynchrotronRadiationInMat::GetLambdaConst() { return fLambdaConst; }
G4double G4SynchrotronRadiationInMat::GetEnergyConst() { return fEnergyConst; }
G4double G4SynchrotronRadiationInMat::GetEnergyConst()
{
return fEnergyConst;
}
/////////////////////////////// METHODS /////////////////////////////////
//
//
// Production of synchrotron X-ray photon
// GEANT4 internal units.
//
G4double
G4SynchrotronRadiationInMat::GetMeanFreePath( const G4Track& trackData,
G4double,
G4ForceCondition* condition)
// Geant4 internal units.
G4double G4SynchrotronRadiationInMat::GetMeanFreePath(
const G4Track& trackData, G4double, G4ForceCondition* condition)
{
// gives the MeanFreePath in GEANT4 internal units
G4double MeanFreePath;
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
// G4Material* aMaterial = trackData.GetMaterial();
//G4bool isOutRange ;
*condition = NotForced ;
*condition = NotForced;
G4double gamma = aDynamicParticle->GetTotalEnergy()/
aDynamicParticle->GetMass();
G4double gamma =
aDynamicParticle->GetTotalEnergy() / aDynamicParticle->GetMass();
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
G4double KineticEnergy = aDynamicParticle->GetKineticEnergy();
if ( KineticEnergy < LowestKineticEnergy || gamma < 1.0e3 ) MeanFreePath = DBL_MAX;
if(KineticEnergy < LowestKineticEnergy || gamma < 1.0e3)
MeanFreePath = DBL_MAX;
else
{
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4FieldManager* fieldMgr = nullptr;
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr=nullptr;
G4bool fieldExertsForce = false;
if( (particleCharge != 0.0) )
if((particleCharge != 0.0))
{
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
fieldMgr =
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
if ( fieldMgr != nullptr )
if(fieldMgr != nullptr)
{
// If the field manager has no field, there is no field !
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
}
}
if ( fieldExertsForce )
{
pField = fieldMgr->GetDetectorField() ;
G4ThreeVector globPosition = trackData.GetPosition();
if(fieldExertsForce)
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
G4double globPosVec[4], FieldValueVec[6];
globPosVec[0] = globPosition.x();
globPosVec[1] = globPosition.y();
globPosVec[2] = globPosition.z();
globPosVec[3] = trackData.GetGlobalTime();
pField->GetFieldValue( globPosVec, FieldValueVec );
pField->GetFieldValue(globPosVec, FieldValueVec);
FieldValue = G4ThreeVector( FieldValueVec[0],
FieldValueVec[1],
FieldValueVec[2] );
FieldValue =
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
G4double beta = aDynamicParticle->GetTotalMomentum() /
(aDynamicParticle->GetTotalEnergy());
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum) ;
G4double perpB = unitMcrossB.mag() ;
G4double beta = aDynamicParticle->GetTotalMomentum()/
(aDynamicParticle->GetTotalEnergy() );
if( perpB > 0.0 ) MeanFreePath = fLambdaConst*beta/perpB;
else MeanFreePath = DBL_MAX;
if(perpB > 0.0)
MeanFreePath = fLambdaConst * beta / perpB;
else
MeanFreePath = DBL_MAX;
}
else MeanFreePath = DBL_MAX;
else
MeanFreePath = DBL_MAX;
}
if(fVerboseLevel > 0)
{
G4cout<<"G4SynchrotronRadiationInMat::MeanFreePath = "<<MeanFreePath/m<<" m"<<G4endl;
G4cout << "G4SynchrotronRadiationInMat::MeanFreePath = " << MeanFreePath / m
<< " m" << G4endl;
}
return MeanFreePath;
}
return MeanFreePath;
}
////////////////////////////////////////////////////////////////////////////////
//
//
G4VParticleChange*
G4SynchrotronRadiationInMat::PostStepDoIt(const G4Track& trackData,
const G4Step& stepData )
G4VParticleChange* G4SynchrotronRadiationInMat::PostStepDoIt(
const G4Track& trackData, const G4Step& stepData)
{
aParticleChange.Initialize(trackData);
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
G4double gamma = aDynamicParticle->GetTotalEnergy()/
(aDynamicParticle->GetMass() );
G4double gamma =
aDynamicParticle->GetTotalEnergy() / (aDynamicParticle->GetMass());
if(gamma <= 1.0e3 )
if(gamma <= 1.0e3)
{
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
G4ThreeVector FieldValue;
const G4Field* pField = nullptr ;
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4FieldManager* fieldMgr=nullptr;
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr = nullptr;
G4bool fieldExertsForce = false;
if( (particleCharge != 0.0) )
if((particleCharge != 0.0))
{
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
if ( fieldMgr != nullptr )
fieldMgr = fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
if(fieldMgr != nullptr)
{
// If the field manager has no field, there is no field !
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
}
}
if ( fieldExertsForce )
if(fieldExertsForce)
{
pField = fieldMgr->GetDetectorField() ;
G4ThreeVector globPosition = trackData.GetPosition() ;
G4double globPosVec[4], FieldValueVec[6] ;
globPosVec[0] = globPosition.x() ;
globPosVec[1] = globPosition.y() ;
globPosVec[2] = globPosition.z() ;
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[4], FieldValueVec[6];
globPosVec[0] = globPosition.x();
globPosVec[1] = globPosition.y();
globPosVec[2] = globPosition.z();
globPosVec[3] = trackData.GetGlobalTime();
pField->GetFieldValue( globPosVec, FieldValueVec ) ;
FieldValue = G4ThreeVector( FieldValueVec[0],
FieldValueVec[1],
FieldValueVec[2] );
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag() ;
pField->GetFieldValue(globPosVec, FieldValueVec);
FieldValue =
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
if(perpB > 0.0)
{
// M-C of synchrotron photon energy
G4double energyOfSR = GetRandomEnergySR(gamma,perpB);
G4double energyOfSR = GetRandomEnergySR(gamma, perpB);
if(fVerboseLevel > 0)
{
G4cout<<"SR photon energy = "<<energyOfSR/keV<<" keV"<<G4endl;
G4cout << "SR photon energy = " << energyOfSR / keV << " keV" << G4endl;
}
// check against insufficient energy
if( energyOfSR <= 0.0 )
// check against insufficient energy
if(energyOfSR <= 0.0)
{
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
G4ParticleMomentum
particleDirection = aDynamicParticle->GetMomentumDirection();
G4ParticleMomentum particleDirection =
aDynamicParticle->GetMomentumDirection();
// M-C of its direction, simplified dipole busted approach
// G4double Teta = G4UniformRand()/gamma ; // Very roughly
G4double cosTheta, sinTheta, fcos, beta;
do
{
cosTheta = 1. - 2.*G4UniformRand();
fcos = (1 + cosTheta*cosTheta)*0.5;
}
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
while( fcos < G4UniformRand() );
do
{
cosTheta = 1. - 2. * G4UniformRand();
fcos = (1 + cosTheta * cosTheta) * 0.5;
}
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
while(fcos < G4UniformRand());
beta = std::sqrt(1. - 1./(gamma*gamma));
beta = std::sqrt(1. - 1. / (gamma * gamma));
cosTheta = (cosTheta + beta)/(1. + beta*cosTheta);
cosTheta = (cosTheta + beta) / (1. + beta * cosTheta);
if( cosTheta > 1. ) cosTheta = 1.;
if( cosTheta < -1. ) cosTheta = -1.;
if(cosTheta > 1.)
cosTheta = 1.;
if(cosTheta < -1.)
cosTheta = -1.;
sinTheta = std::sqrt(1. - cosTheta*cosTheta );
sinTheta = std::sqrt(1. - cosTheta * cosTheta);
G4double Phi = twopi * G4UniformRand() ;
G4double Phi = twopi * G4UniformRand();
G4double dirx = sinTheta*std::cos(Phi) ,
diry = sinTheta*std::sin(Phi) ,
dirz = cosTheta;
G4double dirx = sinTheta * std::cos(Phi);
G4double diry = sinTheta * std::sin(Phi);
G4double dirz = cosTheta;
G4ThreeVector gammaDirection(dirx, diry, dirz);
gammaDirection.rotateUz(particleDirection);
G4ThreeVector gammaDirection ( dirx, diry, dirz);
gammaDirection.rotateUz(particleDirection);
// polarization of new gamma
// G4double sx = std::cos(Teta)*std::cos(Phi);
// G4double sy = std::cos(Teta)*std::sin(Phi);
// G4double sz = -std::sin(Teta);
G4ThreeVector gammaPolarization = FieldValue.cross(gammaDirection);
gammaPolarization = gammaPolarization.unit();
// (sx, sy, sz);
// gammaPolarization.rotateUz(particleDirection);
gammaPolarization = gammaPolarization.unit();
// create G4DynamicParticle object for the SR photon
G4DynamicParticle* aGamma= new G4DynamicParticle ( G4Gamma::Gamma(),
gammaDirection,
energyOfSR );
aGamma->SetPolarization( gammaPolarization.x(),
gammaPolarization.y(),
gammaPolarization.z() );
G4DynamicParticle* aGamma =
new G4DynamicParticle(G4Gamma::Gamma(), gammaDirection, energyOfSR);
aGamma->SetPolarization(gammaPolarization.x(), gammaPolarization.y(),
gammaPolarization.z());
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(aGamma);
aParticleChange.AddSecondary(aGamma);
// Update the incident particle
G4double newKinEnergy = kineticEnergy - energyOfSR ;
if (newKinEnergy > 0.)
// Update the incident particle
G4double newKinEnergy = kineticEnergy - energyOfSR;
if(newKinEnergy > 0.)
{
aParticleChange.ProposeMomentumDirection( particleDirection );
aParticleChange.ProposeEnergy( newKinEnergy );
aParticleChange.ProposeLocalEnergyDeposit (0.);
}
aParticleChange.ProposeMomentumDirection(particleDirection);
aParticleChange.ProposeEnergy(newKinEnergy);
aParticleChange.ProposeLocalEnergyDeposit(0.);
}
else
{
aParticleChange.ProposeEnergy( 0. );
aParticleChange.ProposeLocalEnergyDeposit (0.);
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
if (charge<0.)
{
aParticleChange.ProposeEnergy(0.);
aParticleChange.ProposeLocalEnergyDeposit(0.);
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
if(charge < 0.)
{
aParticleChange.ProposeTrackStatus(fStopAndKill) ;
}
else
aParticleChange.ProposeTrackStatus(fStopAndKill);
}
else
{
aParticleChange.ProposeTrackStatus(fStopButAlive) ;
}
}
}
aParticleChange.ProposeTrackStatus(fStopButAlive);
}
}
}
else
{
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
}
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
}
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
}
G4double
G4SynchrotronRadiationInMat::GetPhotonEnergy( const G4Track& trackData,
const G4Step& )
G4double G4SynchrotronRadiationInMat::GetPhotonEnergy(const G4Track& trackData,
const G4Step&)
{
G4int i ;
G4double energyOfSR = -1.0 ;
//G4Material* aMaterial=trackData.GetMaterial() ;
G4int i;
G4double energyOfSR = -1.0;
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
G4double gamma = aDynamicParticle->GetTotalEnergy()/
(aDynamicParticle->GetMass() ) ;
G4double gamma =
aDynamicParticle->GetTotalEnergy() / (aDynamicParticle->GetMass());
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
G4ThreeVector FieldValue;
const G4Field* pField = nullptr ;
G4ThreeVector FieldValue;
const G4Field* pField = nullptr;
G4FieldManager* fieldMgr=nullptr;
G4bool fieldExertsForce = false;
G4FieldManager* fieldMgr = nullptr;
G4bool fieldExertsForce = false;
if( (particleCharge != 0.0) )
if((particleCharge != 0.0))
{
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
if ( fieldMgr != nullptr )
fieldMgr = fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
if(fieldMgr != nullptr)
{
// If the field manager has no field, there is no field !
fieldExertsForce = ( fieldMgr->GetDetectorField() != 0 );
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
}
}
if ( fieldExertsForce )
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[3], FieldValueVec[3];
if(fieldExertsForce)
{
pField = fieldMgr->GetDetectorField();
G4ThreeVector globPosition = trackData.GetPosition();
G4double globPosVec[3], FieldValueVec[3];
globPosVec[0] = globPosition.x();
globPosVec[1] = globPosition.y();
globPosVec[2] = globPosition.z();
pField->GetFieldValue( globPosVec, FieldValueVec );
FieldValue = G4ThreeVector( FieldValueVec[0],
FieldValueVec[1],
FieldValueVec[2] );
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum) ;
pField->GetFieldValue(globPosVec, FieldValueVec);
FieldValue =
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
G4double perpB = unitMcrossB.mag();
if( perpB > 0.0 )
if(perpB > 0.0)
{
// M-C of synchrotron photon energy
G4double random = G4UniformRand() ;
for(i=0;i<200;i++)
G4double random = G4UniformRand();
for(i = 0; i < 200; ++i)
{
if(random >= fIntegralProbabilityOfSR[i]) break ;
if(random >= fIntegralProbabilityOfSR[i])
break;
}
energyOfSR = 0.0001*i*i*fEnergyConst*gamma*gamma*perpB ;
energyOfSR = 0.0001 * i * i * fEnergyConst * gamma * gamma * perpB;
// check against insufficient energy
if(energyOfSR <= 0.0)
{
return -1.0 ;
return -1.0;
}
//G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
//G4ParticleMomentum
//particleDirection = aDynamicParticle->GetMomentumDirection();
// Gamma production cut in this material
//G4double
//gammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
// SR photon has energy more than the current material cut
// M-C of its direction
//G4double Teta = G4UniformRand()/gamma ; // Very roughly
//G4double Phi = twopi * G4UniformRand() ;
}
}
else
{
return -1.0 ;
return -1.0;
}
}
return energyOfSR ;
}
return energyOfSR;
}
/////////////////////////////////////////////////////////////////////////////////
//
//
G4double G4SynchrotronRadiationInMat::GetRandomEnergySR(G4double gamma, G4double perpB)
G4double G4SynchrotronRadiationInMat::GetRandomEnergySR(G4double gamma,
G4double perpB)
{
G4int i, iMax;
G4int i;
static constexpr G4int iMax = 200;
G4double energySR, random, position;
iMax = 200;
random = G4UniformRand();
for( i = 0; i < iMax; i++ )
for(i = 0; i < iMax; ++i)
{
if( random >= fIntegralProbabilityOfSR[i] ) break;
if(random >= fIntegralProbabilityOfSR[i])
break;
}
if(i <= 0 ) position = G4UniformRand(); // 0.
else if( i>= iMax) position = G4double(iMax);
else position = i + G4UniformRand(); // -1
//
// it was in initial implementation:
// energyOfSR = 0.0001*i*i*fEnergyConst*gamma*gamma*perpB ;
if(i <= 0)
position = G4UniformRand();
else if(i >= iMax)
position = G4double(iMax);
else
position = i + G4UniformRand();
energySR = 0.0001*position*position*fEnergyConst*gamma*gamma*perpB;
energySR =
0.0001 * position * position * fEnergyConst * gamma * gamma * perpB;
if( energySR < 0. ) energySR = 0.;
if(energySR < 0.)
energySR = 0.;
return energySR;
}
/////////////////////////////////////////////////////////////////////////
//
// return
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt( G4double t)
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt(G4double t)
{
G4double result, hypCos2, hypCos=std::cosh(t);
G4double result, hypCos2, hypCos = std::cosh(t);
hypCos2 = hypCos*hypCos;
result = std::cosh(5.*t/3.)*std::exp(t-fKsi*hypCos); // fKsi > 0. !
hypCos2 = hypCos * hypCos;
result = std::cosh(5. * t / 3.) * std::exp(t - fKsi * hypCos); // fKsi > 0. !
result /= hypCos2;
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// return the probability to emit SR photon with relative energy
// energy/energy_c >= ksi
// for ksi <= 0. P = 1., however the method works for ksi > 0 only!
G4double G4SynchrotronRadiationInMat::GetIntProbSR( G4double ksi)
G4double G4SynchrotronRadiationInMat::GetIntProbSR(G4double ksi)
{
if (ksi <= 0.) return 1.0;
fKsi = ksi; // should be > 0. !
if(ksi <= 0.)
return 1.0;
fKsi = ksi; // should be > 0. !
G4int n;
G4double result, a;
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
G4Integrator<G4SynchrotronRadiationInMat,
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
integral;
result = integral.Laguerre(this,
&G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt, a, n);
result = integral.Laguerre(
this, &G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt, a, n);
result *= 3./5./pi;
result *= 3. / 5. / pi;
return result;
}
/////////////////////////////////////////////////////////////////////////
//
// return an auxiliary function for K_5/3 integral representation
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy( G4double t)
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy(G4double t)
{
G4double result, hypCos=std::cosh(t);
result = std::cosh(5.*t/3.)*std::exp(t - fKsi*hypCos); // fKsi > 0. !
G4double result, hypCos = std::cosh(t);
result = std::cosh(5. * t / 3.) * std::exp(t - fKsi * hypCos); // fKsi > 0. !
result /= hypCos;
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// return the probability to emit SR photon energy with relative energy
// energy/energy_c >= ksi
// for ksi <= 0. P = 1., however the method works for ksi > 0 only!
G4double G4SynchrotronRadiationInMat::GetEnergyProbSR( G4double ksi)
G4double G4SynchrotronRadiationInMat::GetEnergyProbSR(G4double ksi)
{
if (ksi <= 0.) return 1.0;
fKsi = ksi; // should be > 0. !
if(ksi <= 0.)
return 1.0;
fKsi = ksi; // should be > 0. !
G4int n;
G4double result, a;
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
G4Integrator<G4SynchrotronRadiationInMat,
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
integral;
result = integral.Laguerre(this,
&G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy, a, n);
result = integral.Laguerre(
this, &G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy, a, n);
result *= 9.*std::sqrt(3.)*ksi/8./pi;
result *= 9. * std::sqrt(3.) * ksi / 8. / pi;
return result;
}
/////////////////////////////////////////////////////////////////////////////
//
//
G4double G4SynchrotronRadiationInMat::GetIntegrandForAngleK( G4double t)
G4double G4SynchrotronRadiationInMat::GetIntegrandForAngleK(G4double t)
{
G4double result, hypCos=std::cosh(t);
result = std::cosh(fOrderAngleK*t)*std::exp(t - fEta*hypCos); // fEta > 0. !
G4double result, hypCos = std::cosh(t);
result =
std::cosh(fOrderAngleK * t) * std::exp(t - fEta * hypCos); // fEta > 0. !
result /= hypCos;
return result;
}
//////////////////////////////////////////////////////////////////////////
//
// Return K 1/3 or 2/3 for angular distribution
G4double G4SynchrotronRadiationInMat::GetAngleK( G4double eta)
G4double G4SynchrotronRadiationInMat::GetAngleK(G4double eta)
{
fEta = eta; // should be > 0. !
fEta = eta; // should be > 0. !
G4int n;
G4double result, a;
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
a = fAlpha; // always = 0.
n = fRootNumber; // around default = 80
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
G4Integrator<G4SynchrotronRadiationInMat,
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
integral;
result = integral.Laguerre(this,
&G4SynchrotronRadiationInMat::GetIntegrandForAngleK, a, n);
result = integral.Laguerre(
this, &G4SynchrotronRadiationInMat::GetIntegrandForAngleK, a, n);
return result;
}
/////////////////////////////////////////////////////////////////////////
//
// Relative angle diff distribution for given fKsi, which is set externally
G4double G4SynchrotronRadiationInMat::GetAngleNumberAtGammaKsi( G4double gpsi)
G4double G4SynchrotronRadiationInMat::GetAngleNumberAtGammaKsi(G4double gpsi)
{
G4double result, funK, funK2, gpsi2 = gpsi*gpsi;
G4double result, funK, funK2, gpsi2 = gpsi * gpsi;
fPsiGamma = gpsi;
fEta = 0.5*fKsi*(1. + gpsi2)*std::sqrt(1. + gpsi2);
fOrderAngleK = 1./3.;
funK = GetAngleK(fEta);
funK2 = funK*funK;
fPsiGamma = gpsi;
fEta = 0.5 * fKsi * (1. + gpsi2) * std::sqrt(1. + gpsi2);
result = gpsi2*funK2/(1. + gpsi2);
fOrderAngleK = 1. / 3.;
funK = GetAngleK(fEta);
funK2 = funK * funK;
fOrderAngleK = 2./3.;
funK = GetAngleK(fEta);
funK2 = funK*funK;
result = gpsi2 * funK2 / (1. + gpsi2);
fOrderAngleK = 2. / 3.;
funK = GetAngleK(fEta);
funK2 = funK * funK;
result += funK2;
result *= (1. + gpsi2) * fKsi;
result += funK2;
result *= (1. + gpsi2)*fKsi;
return result;
}
///////////////////// end of G4SynchrotronRadiationInMat.cc
@@ -23,11 +23,9 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// G4TransitionRadiation class -- implementation file
// GEANT 4 class implementation file --- Copyright CERN 1995
// CERN Geneva Switzerland
// For information related to this code, please, contact
// CERN, CN Division, ASD Group
@@ -36,195 +34,174 @@
// 2nd version 16.12.97 V. Grichine
// 3rd version 28.07.05, P.Gumplinger add G4ProcessType to constructor
#include <cmath>
//#include <cmath>
#include "G4TransitionRadiation.hh"
#include "G4Material.hh"
#include "G4EmProcessSubType.hh"
// Local constants
const G4int G4TransitionRadiation::fSympsonNumber = 100 ;
const G4int G4TransitionRadiation::fGammaNumber = 15 ;
const G4int G4TransitionRadiation::fPointNumber = 100 ;
///////////////////////////////////////////////////////////////////////
//
// Constructor for selected couple of materials
//
G4TransitionRadiation::
G4TransitionRadiation( const G4String& processName, G4ProcessType type )
G4TransitionRadiation::G4TransitionRadiation(const G4String& processName,
G4ProcessType type)
: G4VDiscreteProcess(processName, type)
{
SetProcessSubType(fTransitionRadiation);
fMatIndex1 = fMatIndex2 = 0;
fGamma = fEnergy = fVarAngle = fMinEnergy = fMaxEnergy = fMaxTheta = fSigma1 = fSigma2 = 0.0;
fGamma = fEnergy = fVarAngle = fMinEnergy = fMaxEnergy = fMaxTheta = 0.0;
fSigma1 = fSigma2 = 0.0;
}
//////////////////////////////////////////////////////////////////////
//
// Destructor
//
G4TransitionRadiation::~G4TransitionRadiation() {}
G4TransitionRadiation::~G4TransitionRadiation()
{}
G4bool
G4TransitionRadiation::IsApplicable(const G4ParticleDefinition& aParticleType)
void G4TransitionRadiation::ProcessDescription(std::ostream& out) const
{
return ( aParticleType.GetPDGCharge() != 0.0 );
out << "Base class for simulation of x-ray transition radiation.\n";
}
G4double G4TransitionRadiation::GetMeanFreePath(const G4Track&,
G4double,
G4ForceCondition* condition)
G4bool G4TransitionRadiation::IsApplicable(
const G4ParticleDefinition& aParticleType)
{
return (aParticleType.GetPDGCharge() != 0.0);
}
G4double G4TransitionRadiation::GetMeanFreePath(const G4Track&, G4double,
G4ForceCondition* condition)
{
*condition = Forced;
return DBL_MAX; // so TR doesn't limit mean free path
return DBL_MAX; // so TR doesn't limit mean free path
}
G4VParticleChange* G4TransitionRadiation::PostStepDoIt(const G4Track&,
const G4Step&)
const G4Step&)
{
ClearNumberOfInteractionLengthLeft();
return &aParticleChange;
}
///////////////////////////////////////////////////////////////////
//
// Sympson integral of TR spectral-angle density over energy between
// the limits energy 1 and energy2 at fixed varAngle = 1 - std::cos(Theta)
G4double
G4TransitionRadiation::IntegralOverEnergy( G4double energy1,
G4double energy2,
G4double varAngle ) const
G4double G4TransitionRadiation::IntegralOverEnergy(G4double energy1,
G4double energy2,
G4double varAngle) const
{
G4int i ;
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
h = 0.5*(energy2 - energy1)/fSympsonNumber ;
for(i=1;i<fSympsonNumber;i++)
G4int i;
G4double h, sumEven = 0.0, sumOdd = 0.0;
h = 0.5 * (energy2 - energy1) / fSympsonNumber;
for(i = 1; i < fSympsonNumber; i++)
{
sumEven += SpectralAngleTRdensity(energy1 + 2*i*h,varAngle) ;
sumOdd += SpectralAngleTRdensity(energy1 + (2*i - 1)*h,varAngle) ;
sumEven += SpectralAngleTRdensity(energy1 + 2 * i * h, varAngle);
sumOdd += SpectralAngleTRdensity(energy1 + (2 * i - 1) * h, varAngle);
}
sumOdd += SpectralAngleTRdensity(energy1 + (2*fSympsonNumber - 1)*h,varAngle) ;
return h*( SpectralAngleTRdensity(energy1,varAngle)
+ SpectralAngleTRdensity(energy2,varAngle)
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
sumOdd +=
SpectralAngleTRdensity(energy1 + (2 * fSympsonNumber - 1) * h, varAngle);
return h *
(SpectralAngleTRdensity(energy1, varAngle) +
SpectralAngleTRdensity(energy2, varAngle) + 4.0 * sumOdd +
2.0 * sumEven) /
3.0;
}
///////////////////////////////////////////////////////////////////
//
// Sympson integral of TR spectral-angle density over energy between
// the limits varAngle1 and varAngle2 at fixed energy
G4double
G4TransitionRadiation::IntegralOverAngle( G4double energy,
G4double varAngle1,
G4double varAngle2 ) const
G4double G4TransitionRadiation::IntegralOverAngle(G4double energy,
G4double varAngle1,
G4double varAngle2) const
{
G4int i ;
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
h = 0.5*(varAngle2 - varAngle1)/fSympsonNumber ;
for(i=1;i<fSympsonNumber;i++)
G4int i;
G4double h, sumEven = 0.0, sumOdd = 0.0;
h = 0.5 * (varAngle2 - varAngle1) / fSympsonNumber;
for(i = 1; i < fSympsonNumber; ++i)
{
sumEven += SpectralAngleTRdensity(energy,varAngle1 + 2*i*h) ;
sumOdd += SpectralAngleTRdensity(energy,varAngle1 + (2*i - 1)*h) ;
sumEven += SpectralAngleTRdensity(energy, varAngle1 + 2 * i * h);
sumOdd += SpectralAngleTRdensity(energy, varAngle1 + (2 * i - 1) * h);
}
sumOdd += SpectralAngleTRdensity(energy,varAngle1 + (2*fSympsonNumber - 1)*h) ;
sumOdd +=
SpectralAngleTRdensity(energy, varAngle1 + (2 * fSympsonNumber - 1) * h);
return h*( SpectralAngleTRdensity(energy,varAngle1)
+ SpectralAngleTRdensity(energy,varAngle2)
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
return h *
(SpectralAngleTRdensity(energy, varAngle1) +
SpectralAngleTRdensity(energy, varAngle2) + 4.0 * sumOdd +
2.0 * sumEven) /
3.0;
}
///////////////////////////////////////////////////////////////////
//
// The number of transition radiation photons generated in the
// angle interval between varAngle1 and varAngle2
//
G4double G4TransitionRadiation::
AngleIntegralDistribution( G4double varAngle1,
G4double varAngle2 ) const
G4double G4TransitionRadiation::AngleIntegralDistribution(
G4double varAngle1, G4double varAngle2) const
{
G4int i ;
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
h = 0.5*(varAngle2 - varAngle1)/fSympsonNumber ;
for(i=1;i<fSympsonNumber;i++)
G4int i;
G4double h, sumEven = 0.0, sumOdd = 0.0;
h = 0.5 * (varAngle2 - varAngle1) / fSympsonNumber;
for(i = 1; i < fSympsonNumber; ++i)
{
sumEven += IntegralOverEnergy(fMinEnergy,
fMinEnergy +0.3*(fMaxEnergy-fMinEnergy),
varAngle1 + 2*i*h)
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
fMaxEnergy,
varAngle1 + 2*i*h);
sumOdd += IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
varAngle1 + (2*i - 1)*h)
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
fMaxEnergy,
varAngle1 + (2*i - 1)*h) ;
sumEven += IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
varAngle1 + 2 * i * h) +
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
fMaxEnergy, varAngle1 + 2 * i * h);
sumOdd += IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
varAngle1 + (2 * i - 1) * h) +
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
fMaxEnergy, varAngle1 + (2 * i - 1) * h);
}
sumOdd += IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
varAngle1 + (2*fSympsonNumber - 1)*h)
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
fMaxEnergy,
varAngle1 + (2*fSympsonNumber - 1)*h) ;
sumOdd +=
IntegralOverEnergy(fMinEnergy, fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
varAngle1 + (2 * fSympsonNumber - 1) * h) +
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy), fMaxEnergy,
varAngle1 + (2 * fSympsonNumber - 1) * h);
return h*(IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
varAngle1)
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
fMaxEnergy,
varAngle1)
+ IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
varAngle2)
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
fMaxEnergy,
varAngle2)
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
return h *
(IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
varAngle1) +
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
fMaxEnergy, varAngle1) +
IntegralOverEnergy(fMinEnergy,
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
varAngle2) +
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
fMaxEnergy, varAngle2) +
4.0 * sumOdd + 2.0 * sumEven) /
3.0;
}
///////////////////////////////////////////////////////////////////
//
// The number of transition radiation photons, generated in the
// energy interval between energy1 and energy2
//
G4double G4TransitionRadiation::
EnergyIntegralDistribution( G4double energy1,
G4double energy2 ) const
G4double G4TransitionRadiation::EnergyIntegralDistribution(
G4double energy1, G4double energy2) const
{
G4int i ;
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
h = 0.5*(energy2 - energy1)/fSympsonNumber ;
for(i=1;i<fSympsonNumber;i++)
G4int i;
G4double h, sumEven = 0.0, sumOdd = 0.0;
h = 0.5 * (energy2 - energy1) / fSympsonNumber;
for(i = 1; i < fSympsonNumber; ++i)
{
sumEven += IntegralOverAngle(energy1 + 2*i*h,0.0,0.01*fMaxTheta )
+ IntegralOverAngle(energy1 + 2*i*h,0.01*fMaxTheta,fMaxTheta);
sumOdd += IntegralOverAngle(energy1 + (2*i - 1)*h,0.0,0.01*fMaxTheta)
+ IntegralOverAngle(energy1 + (2*i - 1)*h,0.01*fMaxTheta,fMaxTheta) ;
sumEven +=
IntegralOverAngle(energy1 + 2 * i * h, 0.0, 0.01 * fMaxTheta) +
IntegralOverAngle(energy1 + 2 * i * h, 0.01 * fMaxTheta, fMaxTheta);
sumOdd +=
IntegralOverAngle(energy1 + (2 * i - 1) * h, 0.0, 0.01 * fMaxTheta) +
IntegralOverAngle(energy1 + (2 * i - 1) * h, 0.01 * fMaxTheta, fMaxTheta);
}
sumOdd += IntegralOverAngle(energy1 + (2*fSympsonNumber - 1)*h,
0.0,0.01*fMaxTheta)
+ IntegralOverAngle(energy1 + (2*fSympsonNumber - 1)*h,
0.01*fMaxTheta,fMaxTheta) ;
sumOdd += IntegralOverAngle(energy1 + (2 * fSympsonNumber - 1) * h, 0.0,
0.01 * fMaxTheta) +
IntegralOverAngle(energy1 + (2 * fSympsonNumber - 1) * h,
0.01 * fMaxTheta, fMaxTheta);
return h*(IntegralOverAngle(energy1,0.0,0.01*fMaxTheta)
+ IntegralOverAngle(energy1,0.01*fMaxTheta,fMaxTheta)
+ IntegralOverAngle(energy2,0.0,0.01*fMaxTheta)
+ IntegralOverAngle(energy2,0.01*fMaxTheta,fMaxTheta)
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
return h *
(IntegralOverAngle(energy1, 0.0, 0.01 * fMaxTheta) +
IntegralOverAngle(energy1, 0.01 * fMaxTheta, fMaxTheta) +
IntegralOverAngle(energy2, 0.0, 0.01 * fMaxTheta) +
IntegralOverAngle(energy2, 0.01 * fMaxTheta, fMaxTheta) +
4.0 * sumOdd + 2.0 * sumEven) /
3.0;
}
// end of G4TransitionRadiation implementation file --------------------------
@@ -23,215 +23,128 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
#include <complex>
#include "G4TransparentRegXTRadiator.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
#include "G4Integrator.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4TransparentRegXTRadiator::G4TransparentRegXTRadiator(G4LogicalVolume *anEnvelope,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
G4TransparentRegXTRadiator::G4TransparentRegXTRadiator(
G4LogicalVolume* anEnvelope, G4Material* foilMat, G4Material* gasMat,
G4double a, G4double b, G4int n, const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
if(verboseLevel > 0)
G4cout<<"Regular transparent X-ray TR radiator EM process is called"<<G4endl;
G4cout << "Regular transparent X-ray TR radiator EM process is called"
<< G4endl;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fAlphaPlate = 10000;
fAlphaGas = 1000;
// BuildTable();
}
///////////////////////////////////////////////////////////////////////////
G4TransparentRegXTRadiator::~G4TransparentRegXTRadiator() {}
G4TransparentRegXTRadiator::~G4TransparentRegXTRadiator()
///////////////////////////////////////////////////////////////////////////
void G4TransparentRegXTRadiator::ProcessDescription(std::ostream& out) const
{
;
out << "Simulation of forward X-ray transition radiation generated by\n"
"relativistic charged particles crossing the interface between\n"
"two materials.\n";
}
///////////////////////////////////////////////////////////////////////////
//
//
G4double G4TransparentRegXTRadiator::SpectralXTRdEdx(G4double energy)
{
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k /*, aMa, bMb ,sigma*/;
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
G4int k, kMax, kMin;
//aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
//bMb = fGasThick*GetGasLinearPhotoAbs(energy);
//sigma = aMa + bMb;
cofPHC = 4*pi*hbarc;
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
cof1 = fPlateThick*tmp;
cof2 = fGasThick*tmp;
cofPHC = 4. * pi * hbarc;
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
cof1 = fPlateThick * tmp;
cof2 = fGasThick * tmp;
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
cofMin /= cofPHC;
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
// else kMin = 1;
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
kMin = G4int(cofMin);
if (cofMin > kMin) kMin++;
if(cofMin > kMin)
kMin++;
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
// tmp /= cofPHC;
// kMax = G4int(tmp);
// if(kMax < 0) kMax = 0;
// kMax += kMin;
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
// tmp /= fGamma;
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
kMax = kMin + 49;
if(verboseLevel > 2)
{
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
}
for( k = kMin; k <= kMax; k++ )
{
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
if( k == kMin && kMin == G4int(cofMin) )
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
}
for(k = kMin; k <= kMax; ++k)
{
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
if(k == kMin && kMin == G4int(cofMin))
{
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum +=
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
else
{
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
if(verboseLevel > 2)
{
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
// <<"; sum = "<<sum<<G4endl;
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
<<" "<<sum<<G4endl;
}
{
G4cout << k << " " << theta2k << " "
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
<< " " << sum << G4endl;
}
}
result = 4.*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
// fPlateNumber;
result *= fPlateNumber; // *std::exp(-0.5*fPlateNumber*sigma);
// +1-std::exp(-0.5*fPlateNumber*sigma);
/*
fEnergy = energy;
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.0,0.3*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.6*fMaxThetaTR,fMaxThetaTR) ;
result += tmp;
*/
result = 4. * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
result *= fPlateNumber;
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4TransparentRegXTRadiator::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in corresponding material.
G4double G4TransparentRegXTRadiator::GetStackFactor(G4double energy,
G4double gamma,
G4double varAngle)
{
/*
G4double result, Za, Zb, Ma, Mb, sigma;
Za = GetPlateFormationZone(energy,gamma,varAngle);
Zb = GetGasFormationZone(energy,gamma,varAngle);
Ma = GetPlateLinearPhotoAbs(energy);
Mb = GetGasLinearPhotoAbs(energy);
sigma = Ma*fPlateThick + Mb*fGasThick;
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
sigma = aMa * fPlateThick + bMb * fGasThick;
Qa = std::exp(-0.5 * aMa);
Qb = std::exp(-0.5 * bMb);
Q = Qa * Qb;
G4complex Ha = std::pow(Ca,-fAlphaPlate);
G4complex Hb = std::pow(Cb,-fAlphaGas);
G4complex H = Ha*Hb;
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
* G4double(fPlateNumber) ;
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) ;
// *(1.0 - std::pow(H,fPlateNumber)) ;
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
// G4complex R = F2*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
*/
// numerically unstable result
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
sigma = aMa*fPlateThick + bMb*fGasThick;
Qa = std::exp(-0.5*aMa);
Qb = std::exp(-0.5*bMb);
Q = Qa*Qb;
G4complex Ha( Qa*std::cos(aZa), -Qa*std::sin(aZa) );
G4complex Hb( Qb*std::cos(bZb), -Qb*std::sin(bZb) );
G4complex H = Ha*Hb;
G4complex Ha(Qa * std::cos(aZa), -Qa * std::sin(aZa));
G4complex Hb(Qb * std::cos(bZb), -Qb * std::sin(bZb));
G4complex H = Ha * Hb;
G4complex Hs = conj(H);
D = 1.0 /( (1 - Q)*(1 - Q) +
4*Q*std::sin(0.5*(aZa + bZb))*std::sin(0.5*(aZa + bZb)) );
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
* G4double(fPlateNumber)*D;
G4complex F2 = (1.0 - Ha)*(1.0 - Ha)*Hb*(1.0 - Hs)*(1.0 - Hs)
// * (1.0 - std::pow(H,fPlateNumber)) * D*D;
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) * D*D;
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
D = 1.0 / ((1 - Q) * (1 - Q) +
4 * Q * std::sin(0.5 * (aZa + bZb)) * std::sin(0.5 * (aZa + bZb)));
G4complex F1 =
(1.0 - Ha) * (1.0 - Hb) * (1.0 - Hs) * G4double(fPlateNumber) * D;
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb * (1.0 - Hs) * (1.0 - Hs) *
(1.0 - std::exp(-0.5 * fPlateNumber * sigma)) * D * D;
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
result = 2.0 * std::real(R);
return result;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -23,36 +23,32 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// G4VTransitionRadiation class -- implementation file
// GEANT 4 class implementation file --- Copyright CERN 1995
// CERN Geneva Switzerland
// History:
// 29.02.04 V.Ivanchenko create
// 28.07.05, P.Gumplinger add G4ProcessType to constructor
#include "G4VTransitionRadiation.hh"
#include "G4ParticleDefinition.hh"
#include "G4VTRModel.hh"
#include "G4Material.hh"
#include "G4Region.hh"
#include "G4TransportationManager.hh"
#include "G4EmProcessSubType.hh"
#include "G4LossTableManager.hh"
#include "G4Material.hh"
#include "G4ParticleDefinition.hh"
#include "G4Region.hh"
#include "G4TransportationManager.hh"
#include "G4VTRModel.hh"
///////////////////////////////////////////////////////////////////////
G4VTransitionRadiation::G4VTransitionRadiation( const G4String& processName,
G4ProcessType type )
: G4VDiscreteProcess(processName, type),
region(nullptr),
model(nullptr),
nSteps(0),
gammaMin(100.),
cosDThetaMax(std::cos(0.1))
G4VTransitionRadiation::G4VTransitionRadiation(const G4String& processName,
G4ProcessType type)
: G4VDiscreteProcess(processName, type)
, region(nullptr)
, model(nullptr)
, gammaMin(100.)
, cosDThetaMax(std::cos(0.1))
, nSteps(0)
{
SetProcessSubType(fTransitionRadiation);
Clear();
@@ -61,15 +57,21 @@ G4VTransitionRadiation::G4VTransitionRadiation( const G4String& processName,
}
///////////////////////////////////////////////////////////////////////
G4VTransitionRadiation::~G4VTransitionRadiation()
{
Clear();
theManager->DeRegister(this);
}
///////////////////////////////////////////////////////////////////////
void G4VTransitionRadiation::ProcessDescription(std::ostream& out) const
{
out << "Generic process of transition radiation.\n";
if(model)
model->PrintInfo();
}
///////////////////////////////////////////////////////////////////////
void G4VTransitionRadiation::Clear()
{
materials.clear();
@@ -79,112 +81,102 @@ void G4VTransitionRadiation::Clear()
}
///////////////////////////////////////////////////////////////////////
G4VParticleChange* G4VTransitionRadiation::PostStepDoIt(
const G4Track& track,
const G4Step& step)
G4VParticleChange* G4VTransitionRadiation::PostStepDoIt(const G4Track& track,
const G4Step& step)
{
// Fill temporary vectors
const G4Material* material = track.GetMaterial();
G4double length = step.GetStepLength();
G4ThreeVector direction = track.GetMomentumDirection();
if(nSteps == 0) {
G4double length = step.GetStepLength();
G4ThreeVector direction = track.GetMomentumDirection();
if(nSteps == 0)
{
nSteps = 1;
materials.push_back(material);
steps.push_back(length);
const G4StepPoint* point = step.GetPreStepPoint();
startingPosition = point->GetPosition();
startingDirection = point->GetMomentumDirection();
G4bool valid = true;
startingPosition = point->GetPosition();
startingDirection = point->GetMomentumDirection();
G4bool valid = true;
G4ThreeVector n = G4TransportationManager::GetTransportationManager()
->GetNavigatorForTracking()->GetLocalExitNormal(&valid);
if(valid) normals.push_back(n);
else normals.push_back(direction);
} else {
if(material == materials[nSteps-1]) {
steps[nSteps-1] += length;
} else {
nSteps++;
->GetNavigatorForTracking()
->GetLocalExitNormal(&valid);
if(valid)
normals.push_back(n);
else
normals.push_back(direction);
}
else
{
if(material == materials[nSteps - 1])
{
steps[nSteps - 1] += length;
}
else
{
++nSteps;
materials.push_back(material);
steps.push_back(length);
G4bool valid = true;
G4bool valid = true;
G4ThreeVector n = G4TransportationManager::GetTransportationManager()
->GetNavigatorForTracking()->GetLocalExitNormal(&valid);
if(valid) normals.push_back(n);
else normals.push_back(direction);
->GetNavigatorForTracking()
->GetLocalExitNormal(&valid);
if(valid)
normals.push_back(n);
else
normals.push_back(direction);
}
}
// Check POstStepPoint condition
// Check PostStepPoint condition
if(track.GetTrackStatus() == fStopAndKill ||
track.GetVolume()->GetLogicalVolume()->GetRegion() != region ||
startingDirection.x()*direction.x() +
startingDirection.y()*direction.y() +
startingDirection.z()*direction.z() < cosDThetaMax)
startingDirection.x() * direction.x() +
startingDirection.y() * direction.y() +
startingDirection.z() * direction.z() <
cosDThetaMax)
{
if(model) {
model->GenerateSecondaries(*pParticleChange, materials, steps,
normals, startingPosition, track);
}
Clear();
if(model)
{
model->GenerateSecondaries(*pParticleChange, materials, steps, normals,
startingPosition, track);
}
Clear();
}
return pParticleChange;
}
///////////////////////////////////////////////////////////////////////
G4bool G4VTransitionRadiation::IsApplicable(
const G4ParticleDefinition& aParticle)
const G4ParticleDefinition& aParticle)
{
return ( aParticle.GetPDGCharge() != 0.0 );
return (aParticle.GetPDGCharge() != 0.0);
}
///////////////////////////////////////////////////////////////////////
void G4VTransitionRadiation::SetRegion(const G4Region* reg)
{
region = reg;
}
void G4VTransitionRadiation::SetRegion(const G4Region* reg) { region = reg; }
///////////////////////////////////////////////////////////////////////
void G4VTransitionRadiation::SetModel(G4VTRModel* mod)
{
model = mod;
}
void G4VTransitionRadiation::SetModel(G4VTRModel* mod) { model = mod; }
///////////////////////////////////////////////////////////////////////
void G4VTransitionRadiation::PrintInfoDefinition()
G4double G4VTransitionRadiation::GetMeanFreePath(const G4Track& track, G4double,
G4ForceCondition* condition)
{
if(model) model->PrintInfo();
}
///////////////////////////////////////////////////////////////////////
G4double G4VTransitionRadiation::GetMeanFreePath(
const G4Track& track, G4double,
G4ForceCondition* condition)
{
if(nSteps > 0) {
if(nSteps > 0)
{
*condition = StronglyForced;
} else {
}
else
{
*condition = NotForced;
if(track.GetKineticEnergy()/track.GetDefinition()->GetPDGMass() + 1.0 > gammaMin &&
track.GetVolume()->GetLogicalVolume()->GetRegion() == region) {
*condition = StronglyForced;
if(track.GetKineticEnergy() / track.GetDefinition()->GetPDGMass() + 1.0 >
gammaMin &&
track.GetVolume()->GetLogicalVolume()->GetRegion() == region)
{
*condition = StronglyForced;
}
}
return DBL_MAX; // so TR doesn't limit mean free path
return DBL_MAX; // so TR doesn't limit mean free path
}
///////////////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
@@ -23,113 +23,84 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
#include <complex>
#include "G4XTRGammaRadModel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
using namespace std;
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4XTRGammaRadModel::G4XTRGammaRadModel(G4LogicalVolume* anEnvelope,
G4double alphaPlate,
G4double alphaGas,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
G4double alphaPlate, G4double alphaGas,
G4Material* foilMat, G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
G4cout<<"Gamma distributed X-ray TR radiator model is called"<<G4endl ;
G4cout << "Gamma distributed X-ray TR radiator model is called" << G4endl;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fAlphaPlate = alphaPlate ;
fAlphaGas = alphaGas ;
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
fAlphaPlate = alphaPlate;
fAlphaGas = alphaGas;
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
<< G4endl;
fExitFlux = true;
// BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4XTRGammaRadModel::~G4XTRGammaRadModel() {}
G4XTRGammaRadModel::~G4XTRGammaRadModel()
void G4XTRGammaRadModel::ProcessDescription(std::ostream& out) const
{
;
out << "Rough model describing X-ray transition radiation. Thicknesses of "
"plates\n"
"and gas gaps are distributed according to gamma distributions.\n";
}
///////////////////////////////////////////////////////////////////////////
//
// Rough approximation for radiator interference factor for the case of
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4XTRGammaRadModel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
G4double G4XTRGammaRadModel::GetStackFactor(G4double energy, G4double gamma,
G4double varAngle)
{
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb ;
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb;
Ma = GetPlateLinearPhotoAbs(energy) ;
Mb = GetGasLinearPhotoAbs(energy) ;
Za = GetPlateFormationZone(energy, gamma, varAngle);
Zb = GetGasFormationZone(energy, gamma, varAngle);
Qa = ( 1.0 + fPlateThick*Ma/fAlphaPlate ) ;
Qa = std::pow(Qa,-fAlphaPlate) ;
Qb = ( 1.0 + fGasThick*Mb/fAlphaGas ) ;
Qb = std::pow(Qb,-fAlphaGas) ;
Q = Qa*Qb ;
Ma = GetPlateLinearPhotoAbs(energy);
Mb = GetGasLinearPhotoAbs(energy);
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate) ;
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas) ;
Qa = (1.0 + fPlateThick * Ma / fAlphaPlate);
Qa = std::pow(Qa, -fAlphaPlate);
Qb = (1.0 + fGasThick * Mb / fAlphaGas);
Qb = std::pow(Qb, -fAlphaGas);
Q = Qa * Qb;
G4complex Ha = std::pow(Ca,-fAlphaPlate) ;
G4complex Hb = std::pow(Cb,-fAlphaGas) ;
G4complex H = Ha*Hb ;
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
fPlateThick / Za / fAlphaPlate);
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
fGasThick / Zb / fAlphaGas);
G4complex F1 = ( 0.5*(1+Qa)*(1.0+H) - Ha - Qa*Hb )/(1.0-H) ;
G4complex Ha = std::pow(Ca, -fAlphaPlate);
G4complex Hb = std::pow(Cb, -fAlphaGas);
G4complex H = Ha * Hb;
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb/(1.0-H)/(Q-H) ;
G4complex F1 = (0.5 * (1 + Qa) * (1.0 + H) - Ha - Qa * Hb) / (1.0 - H);
F2 *= std::pow(Q,G4double(fPlateNumber)) - std::pow(H,fPlateNumber) ;
G4complex F2 = (1.0 - Ha) * (Qa - Ha) * Hb / (1.0 - H) / (Q - H);
result = ( 1. - std::pow(Q,G4double(fPlateNumber)) )/( 1. - Q ) ;
F2 *= std::pow(Q, G4double(fPlateNumber)) - std::pow(H, fPlateNumber);
G4complex stack = result*F1;
stack += F2;
stack *= 2.0*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = (1. - std::pow(Q, G4double(fPlateNumber))) / (1. - Q);
result = std::real(stack);
G4complex stack = result * F1;
stack += F2;
stack *= 2.0 * OneInterfaceXTRdEdx(energy, gamma, varAngle);
// result *= 2.0*std::real(F1);
// result += 2.0*std::real(F2);
result = std::real(stack);
return result ;
return result;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -23,216 +23,148 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
#include <complex>
#include "G4XTRRegularRadModel.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
using namespace std;
#include "G4PhysicalConstants.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4XTRRegularRadModel::G4XTRRegularRadModel(G4LogicalVolume *anEnvelope,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
G4XTRRegularRadModel::G4XTRRegularRadModel(G4LogicalVolume* anEnvelope,
G4Material* foilMat,
G4Material* gasMat, G4double a,
G4double b, G4int n,
const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
G4cout<<" XTR Regular discrete radiator model is called"<<G4endl ;
G4cout << " XTR Regular discrete radiator model is called" << G4endl;
fExitFlux = true;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
// BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4XTRRegularRadModel::~G4XTRRegularRadModel() {}
G4XTRRegularRadModel::~G4XTRRegularRadModel()
///////////////////////////////////////////////////////////////////////////
void G4XTRRegularRadModel::ProcessDescription(std::ostream& out) const
{
;
out << "Describes X-ray transition radiation with thickness of gaps and "
"plates\n"
"fixed.\n";
}
///////////////////////////////////////////////////////////////////////////
//
//
G4double G4XTRRegularRadModel::SpectralXTRdEdx(G4double energy)
{
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
G4double aMa, bMb ,sigma, dump;
static constexpr G4double cofPHC = 4. * pi * hbarc;
G4double result, sum = 0., tmp, cof1, cof2, cofMin, theta2, theta2k;
G4double aMa, bMb, sigma, dump;
G4int k, kMax, kMin;
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
sigma = 0.5*(aMa + bMb);
dump = std::exp(-fPlateNumber*sigma);
if(verboseLevel > 2) G4cout<<" dump = "<<dump<<G4endl;
cofPHC = 4*pi*hbarc;
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
cof1 = fPlateThick*tmp;
cof2 = fGasThick*tmp;
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
sigma = 0.5 * (aMa + bMb);
dump = std::exp(-fPlateNumber * sigma);
if(verboseLevel > 2)
G4cout << " dump = " << dump << G4endl;
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
cof1 = fPlateThick * tmp;
cof2 = fGasThick * tmp;
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
cofMin /= cofPHC;
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
// else kMin = 1;
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
kMin = G4int(cofMin);
if (cofMin > kMin) kMin++;
if(cofMin > kMin)
kMin++;
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
// tmp /= cofPHC;
// kMax = G4int(tmp);
// if(kMax < 0) kMax = 0;
// kMax += kMin;
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
// tmp /= fGamma;
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
kMax = kMin + 49;
if(verboseLevel > 2)
{
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
}
for( k = kMin; k <= kMax; k++ )
{
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
if( k == kMin && kMin == G4int(cofMin) )
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
}
for(k = kMin; k <= kMax; ++k)
{
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
if(k == kMin && kMin == G4int(cofMin))
{
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum +=
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
else
{
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
if(verboseLevel > 2)
{
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
// <<"; sum = "<<sum<<G4endl;
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
<<" "<<sum<<G4endl;
}
{
G4cout << k << " " << theta2k << " "
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
<< " " << sum << G4endl;
}
}
result = 2*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
// fPlateNumber;
result *= dump*( -1 + dump + 2*fPlateNumber );
/*
fEnergy = energy;
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.0,0.3*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
0.6*fMaxThetaTR,fMaxThetaTR) ;
result += tmp;
*/
result = 2 * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
result *= dump * (-1 + dump + 2 * fPlateNumber);
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4XTRRegularRadModel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in corresponding material.
G4double G4XTRRegularRadModel::GetStackFactor(G4double energy, G4double gamma,
G4double varAngle)
{
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, I2 ;
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle) ;
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle) ;
G4double aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
G4double bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy) ;
bMb = fGasThick*GetGasLinearPhotoAbs(energy) ;
G4double aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
G4double bMb = fGasThick * GetGasLinearPhotoAbs(energy);
Qa = std::exp(-aMa) ;
Qb = std::exp(-bMb) ;
Q = Qa*Qb ;
G4double Qa = std::exp(-aMa);
G4double Qb = std::exp(-bMb);
G4double Q = Qa * Qb;
// G4complex Ca(1.0+0.5*fPlateThick*Ma,fPlateThick/Za) ;
// G4complex Cb(1.0+0.5*fGasThick*Mb,fGasThick/Zb) ;
G4complex Ha(std::exp(-0.5 * aMa) * std::cos(aZa),
-std::exp(-0.5 * aMa) * std::sin(aZa));
G4complex Ha( std::exp(-0.5*aMa)*std::cos(aZa),
-std::exp(-0.5*aMa)*std::sin(aZa) ) ;
G4complex Hb( std::exp(-0.5*bMb)*std::cos(bZb),
-std::exp(-0.5*bMb)*std::sin(bZb) ) ;
G4complex Hb(std::exp(-0.5 * bMb) * std::cos(bZb),
-std::exp(-0.5 * bMb) * std::sin(bZb));
G4complex H = Ha*Hb ;
G4complex H = Ha * Hb;
G4complex Hs = std::conj(H);
G4complex Hs = std::conj(H) ;
G4complex F2 = (1.0 - Ha) * (Qa - Ha) * Hb * (1.0 - Hs) * (Q - Hs);
F2 *= std::pow(Q, G4double(fPlateNumber)) - std::pow(H, fPlateNumber);
// G4complex F1 = ( 0.5*(1+Qa)*(1+H) - Ha - Qa*Hb )/(1-H) ;
G4double result = (1. - std::pow(Q, G4double(fPlateNumber))) / (1. - Q);
result *= (1. - Qa) * (1. + Qa - 2. * std::sqrt(Qa) * std::cos(aZa));
result /= (1. - std::sqrt(Q)) * (1. - std::sqrt(Q)) +
4. * std::sqrt(Q) * std::sin(0.5 * (aZa + bZb)) *
std::sin(0.5 * (aZa + bZb));
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb*(1.0-Hs)*(Q-Hs) ;
G4double I2 = 1.;
I2 /= (1. - std::sqrt(Q)) * (1. - std::sqrt(Q)) +
4. * std::sqrt(Q) * std::sin(0.5 * (aZa + bZb)) *
std::sin(0.5 * (aZa + bZb));
F2 *= std::pow(Q,G4double(fPlateNumber)) - std::pow(H,fPlateNumber) ;
I2 /= Q * ((std::sqrt(Q) - std::cos(aZa + bZb)) *
(std::sqrt(Q) - std::cos(aZa + bZb)) +
std::sin(aZa + bZb) * std::sin(aZa + bZb));
result = ( 1. - std::pow(Q,G4double(fPlateNumber)) )/( 1. - Q ) ;
G4complex stack = 2. * I2 * F2;
stack += result;
stack *= OneInterfaceXTRdEdx(energy, gamma, varAngle);
result *= (1. - Qa)*(1. + Qa - 2.*std::sqrt(Qa)*std::cos(aZa)) ;
result /= (1. - std::sqrt(Q))*(1. - std::sqrt(Q)) +
4.*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) ;
I2 = 1.; // 2.0*std::real(F2) ;
I2 /= (1. - std::sqrt(Q))*(1. - std::sqrt(Q)) +
4.*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) ;
I2 /= Q*( (std::sqrt(Q)-std::cos(aZa+bZb))*(std::sqrt(Q)-std::cos(aZa+bZb)) +
std::sin(aZa+bZb)*std::sin(aZa+bZb) ) ;
G4complex stack = 2.*I2*F2;
stack += result;
stack *= OneInterfaceXTRdEdx(energy,gamma,varAngle);
// result += I2 ;
result = std::real(stack);
return result ;
return std::real(stack);
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -23,51 +23,40 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
#include <complex>
#include "G4XTRTransparentRegRadModel.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
#include "G4Integrator.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4XTRTransparentRegRadModel::G4XTRTransparentRegRadModel(G4LogicalVolume *anEnvelope,
G4Material* foilMat,G4Material* gasMat,
G4double a, G4double b, G4int n,
const G4String& processName) :
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
G4XTRTransparentRegRadModel::G4XTRTransparentRegRadModel(
G4LogicalVolume* anEnvelope, G4Material* foilMat, G4Material* gasMat,
G4double a, G4double b, G4int n, const G4String& processName)
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
{
G4cout<<"Regular transparent X-ray TR radiator EM process is called"<<G4endl;
G4cout << "Regular transparent X-ray TR radiator EM process is called"
<< G4endl;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fExitFlux = true;
fAlphaPlate = 10000;
fAlphaGas = 1000;
// BuildTable();
}
///////////////////////////////////////////////////////////////////////////
G4XTRTransparentRegRadModel::~G4XTRTransparentRegRadModel() {}
G4XTRTransparentRegRadModel::~G4XTRTransparentRegRadModel()
///////////////////////////////////////////////////////////////////////////
void G4XTRTransparentRegRadModel::ProcessDescription(std::ostream& out) const
{
;
out << "Process describing radiator of X-ray transition radiation.\n";
}
///////////////////////////////////////////////////////////////////////////
//
//
G4double G4XTRTransparentRegRadModel::SpectralXTRdEdx(G4double energy)
{
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC,aMa, bMb, sigma;
static constexpr G4double cofPHC = 4. * pi * hbarc;
G4double result, sum = 0., tmp, cof1, cof2, cofMin, aMa, bMb, sigma;
G4int k, kMax, kMin;
aMa = GetPlateLinearPhotoAbs(energy);
@@ -82,133 +71,71 @@ G4double G4XTRTransparentRegRadModel::SpectralXTRdEdx(G4double energy)
bMb *= fGasThick;
sigma = aMa + bMb;
cofPHC = 4.*pi*hbarc;
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
cof1 = fPlateThick*tmp;
cof2 = fGasThick*tmp;
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
cof1 = fPlateThick * tmp;
cof2 = fGasThick * tmp;
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
cofMin /= cofPHC;
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
// else kMin = 1;
kMin = G4int(cofMin);
if (cofMin > kMin) kMin++;
if(cofMin > kMin)
kMin++;
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
// tmp /= cofPHC;
// kMax = G4int(tmp);
// if(kMax < 0) kMax = 0;
// kMax += kMin;
kMax = kMin + 19;
kMax = kMin + 19; // 5; // 9; // kMin + G4int(tmp);
// tmp /= fGamma;
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
// G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
for( k = kMin; k <= kMax; k++ )
for(k = kMin; k <= kMax; k++)
{
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
if( k == kMin && kMin == G4int(cofMin) )
if(k == kMin && kMin == G4int(cofMin))
{
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum +=
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
else
{
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
}
// G4cout<<"k = "<<k<<"; sum = "<<sum<<G4endl;
}
result = 4.*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
result *= ( 1. - std::exp(-fPlateNumber*sigma) )/( 1. - std::exp(-sigma) );
result = 4. * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
result *= (1. - std::exp(-fPlateNumber * sigma)) / (1. - std::exp(-sigma));
return result;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4XTRTransparentRegRadModel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in corresponding material.
G4double G4XTRTransparentRegRadModel::GetStackFactor(G4double energy,
G4double gamma,
G4double varAngle)
{
/*
G4double result, Za, Zb, Ma, Mb, sigma;
Za = GetPlateFormationZone(energy,gamma,varAngle);
Zb = GetGasFormationZone(energy,gamma,varAngle);
Ma = GetPlateLinearPhotoAbs(energy);
Mb = GetGasLinearPhotoAbs(energy);
sigma = Ma*fPlateThick + Mb*fGasThick;
G4double aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
G4double bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
G4double aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
G4double bMb = fGasThick * GetGasLinearPhotoAbs(energy);
G4double sigma = aMa * fPlateThick + bMb * fGasThick;
G4double Qa = std::exp(-0.5 * aMa);
G4double Qb = std::exp(-0.5 * bMb);
G4double Q = Qa * Qb;
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
G4complex Ha = std::pow(Ca,-fAlphaPlate);
G4complex Hb = std::pow(Cb,-fAlphaGas);
G4complex H = Ha*Hb;
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
* G4double(fPlateNumber) ;
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) ;
// *(1.0 - std::pow(H,fPlateNumber)) ;
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
// G4complex R = F2*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
*/
// numerically unstable result
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
sigma = aMa*fPlateThick + bMb*fGasThick;
Qa = std::exp(-0.5*aMa);
Qb = std::exp(-0.5*bMb);
Q = Qa*Qb;
G4complex Ha( Qa*std::cos(aZa), -Qa*std::sin(aZa) );
G4complex Hb( Qb*std::cos(bZb), -Qb*std::sin(bZb) );
G4complex H = Ha*Hb;
G4complex Ha(Qa * std::cos(aZa), -Qa * std::sin(aZa));
G4complex Hb(Qb * std::cos(bZb), -Qb * std::sin(bZb));
G4complex H = Ha * Hb;
G4complex Hs = conj(H);
D = 1.0 /( (1. - Q)*(1. - Q) +
4.*Q*std::sin(0.5*(aZa + bZb))*std::sin(0.5*(aZa + bZb)) );
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
* G4double(fPlateNumber)*D;
G4complex F2 = (1.0 - Ha)*(1.0 - Ha)*Hb*(1.0 - Hs)*(1.0 - Hs)
// * (1.0 - std::pow(H,fPlateNumber)) * D*D;
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) * D*D;
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
result = 2.0*std::real(R);
return result;
G4double D =
1.0 / ((1. - Q) * (1. - Q) +
4. * Q * std::sin(0.5 * (aZa + bZb)) * std::sin(0.5 * (aZa + bZb)));
G4complex F1 =
(1.0 - Ha) * (1.0 - Hb) * (1.0 - Hs) * G4double(fPlateNumber) * D;
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb * (1.0 - Hs) * (1.0 - Hs) *
(1.0 - std::exp(-0.5 * fPlateNumber * sigma)) * D * D;
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
return 2.0 * std::real(R);
}
//
//
////////////////////////////////////////////////////////////////////////////