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 : G4empolar
# Package: Geant4.src.G4processes.G4electromagnetic.G4empolar
#
# 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()
@@ -16,14 +16,48 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
15 May 21: V.Ivanchenko (empolar-V10-07-06)
- G4PolarizedAnnihilation - updated use of the spline flag
10 May 21: V.Ivanchenko (empolar-V10-07-05)
- G4PolarizedCompton - updated use of the spline flag
16 April 21: B.Morgan (empolar-V10-07-04)
- Migrate build to modular CMake API
24 April 21: V.Ivanchenko (empolar-V10-07-03)
- G4PolarizedIonisationBhabhaXS - removed incorrect G4Exception;
10 April 21: V.Ivanchenko (empolar-V10-07-02)
- G4PolarizedBremsstrahlung - removed variable shadowing
31 March 21: V.Ivanchenko (empolar-V10-07-01)
- G4PolarizedAnnihilation, G4ePolarizedIonisation - improve
initialisation of assymetry tables
16 February 21: D.Sawkey (empolar-V10-07-00)
- all files. Major cleaning for version 11.
- name classes in logical manner
- improve comments
- add ProcessDescription
- order #includes; remove unused
- disable copy and assignment operators with 'delete'
- increase C++11 keyword usage, especially override, explicit
- rename (most) class variables to start with f
- make SCRN arrays the correct size
- use constexpr for numbers
- apply clang-format style
- use G4ExceptionDescription
- avoid implicit conversions between G4StokesVector and G4ThreeVector
01 April 18: V.Ivanchenko (empolar-V10-04-02)
- G4PolarizedCompton, G4PolarizedPhotoElectricEffect,
- G4PolarizedCompton, G4PolarizedPhotoElectricEffect,
G4PolarizedGammaConversion, G4ePolarizedBremsstrahlung,
G4ePolarizedIonisation - cleanup process classes, moved virtual
methods to source, removed unused headers and methods
01 April 18: V.Ivanchenko (empolar-V10-04-01)
- G4PolarizedAnnihilationModel - implemented sampling of final
- G4PolarizedAnnihilationModel - implemented sampling of final
state AtRest
12 February 18: V.Ivanchenko (empolar-V10-04-00)
@@ -35,7 +69,7 @@ committal in the CVS repository !
make coherent model initialisation
1 Jun 16: D.Sawkey (empolar-V10-02-04)
- G4PolarizationManager: C++11 range-based for loop;
- G4PolarizationManager: C++11 range-based for loop;
- G4PolarizationManager, G4ePolarizedBremsstrahlungModel: nullptr
26 May 16: D.Sawkey (empolar-V10-02-03)
@@ -63,10 +97,10 @@ committal in the CVS repository !
06 October 15: V.Ivanchenko (empolar-V10-01-01)
- G4PolarizedCompton, G4ePolarizedIonisation, G4eplusPolarizedAnnihilation
- changed initialisation taking into account MT mode, added
method ComputeSaturationFactor used in mean free path and
step limit corrections, removed PreparePhysicsTable method (use
one from the base class), fixed computation of the value of number
of interaction lengths left which is responsible for the
method ComputeSaturationFactor used in mean free path and
step limit corrections, removed PreparePhysicsTable method (use
one from the base class), fixed computation of the value of number
of interaction lengths left which is responsible for the
problem #1698
- G4PolarizedComptonModel - revised do/while loop in sampling of
gamma scattering angle
@@ -75,7 +109,7 @@ committal in the CVS repository !
- Added comments to do/while and while loops
22 October 13: V.Ivanchenko (empolar-V10-00-03)
- G4PolarizedCompton, G4PolarizedGammaConversion,
- G4PolarizedCompton, G4PolarizedGammaConversion,
G4PolarizedPhotoElectricEffect, G4ePolarizedBremsstrahlung,
G4ePolarizedIonisation - use G4EmParameters
@@ -85,7 +119,7 @@ committal in the CVS repository !
08 July 13: V.Ivanchenko (empolar-V10-00-01)
- G4PolarizedCompton, G4PolarizedComptonModel - added startFromNull option
as for standard Compton process and add the same low-energy
as for standard Compton process and add the same low-energy
threshold to create secondary particle
26 May 13: V.Ivanchenko (empolar-V10-00-00)
@@ -106,7 +140,7 @@ committal in the CVS repository !
28 October 13: V.Ivanchenko (empolar-V09-06-03)
28 October 13: V.Ivanchenko (empolar-V09-06-02)
28 October 13: V.Ivanchenko (empolar-V09-06-01)
- G4ePolarizedBremsstrahlungModel - substitute G4eBremsstrahlungModel
- G4ePolarizedBremsstrahlungModel - substitute G4eBremsstrahlungModel
by G4SeltzerBergerModel
25 February 13: V.Ivanchenko (empolar-V09-06-00)
@@ -114,7 +148,7 @@ committal in the CVS repository !
gammaPol0, electronPol1, epsilon
20 October 12: V.Ivanchenko (empolar-V09-05-02)
- G4PolarizedPhotoElectricEffect, G4PolarizedPEEffectModel - substitute
- G4PolarizedPhotoElectricEffect, G4PolarizedPEEffectModel - substitute
methods Model(), SetModel() by EmModel(), SetEmModel()
11 July 12: G.Cosmo (empolar-V09-05-01)
@@ -125,11 +159,11 @@ committal in the CVS repository !
- Fixed shadowing
11 November 11: V.Ivanchenko (empolar-V09-04-04)
- G4ePolarizedBremsstrahlung - fixed problem provoked by the tag
- G4ePolarizedBremsstrahlung - fixed problem provoked by the tag
of standard
10 November 11: V.Ivanchenko (empolar-V09-04-03)
- G4PolarizedCompton, G4ePolarizedIonisation,
- G4PolarizedCompton, G4ePolarizedIonisation,
G4PolarizedMollerBhabhaModel, G4eplusPolarizedAnnihilation - fixed
initialisation problems reported by the Coverity tool
@@ -143,22 +177,22 @@ committal in the CVS repository !
- G4ePolarizedIonisation - do not use obsolete MinCutEnergy
12 November 10: A.Schaelicke (empolar-V09-03-02)
- Resolved: Warning messages of Coverity
- Resolved: Warning messages of Coverity
3 September 10: G.Cosmo (empolar-V09-03-01)
3 September 10: G.Cosmo (empolar-V09-03-01)
- Fixed signature to G4VPolarizedCrossSection::TotalXSection() in source file.
16 June 10: A.Schaelicke (empolar-V09-03-00)
- Bug fix in G4ePolarizedIonisation.cc
(used default vector size of G4VEnergyLossProcess,
(used default vector size of G4VEnergyLossProcess,
avoid size mismatch in G4LossTableBuilder::BuildDEDXTable)
12 November 09: A.Schaelicke (empolar-V09-02-01)
- Bug fix in G4PolarizationHelper::GetSpinInPRF
- Bug fix in G4PolarizationHelper::GetSpinInPRF
(wrong normalization of y component)
- Bug fix in G4PolarizedAnnihilationModel::PostStepDoIt
(wrong treatment in error check)
- Bug fix in G4StokesVector::RotateAz
(wrong treatment in error check)
- Bug fix in G4StokesVector::RotateAz
(wrong usage of vector product)
12 April 09: V.Ivanchenko (empolar-V09-02-00)
@@ -170,8 +204,8 @@ G4PolarizedAnnihilationModel - simplified initialisation
01 November 07: A.Schaelicke
- Bug fix in G4PolarizedAnnihilationCrossSection
error in calculation of polarisation dependent total cross section
(wrong interactionLength for positrons in applications where,
particle and media are polarised)
(wrong interactionLength for positrons in applications where,
particle and media are polarised)
- more general Cross section frame work:
G4PolarizedAnnihilationCrossSection
G4PolarizedBhabhaCrossSection
@@ -182,12 +216,12 @@ G4PolarizedAnnihilationModel - simplified initialisation
G4PolarizedPairProductionCrossSection
G4VPolarizedCrossSection
G4ePolarizedBremsstrahlungModel
(removed dependencies to models; now cross sections can be used
(removed dependencies to models; now cross sections can be used
independent of any model, e.g. in a cross section calculator class)
- add polarized photo electric effect:
G4PolarizationHelper
(new method GetRandomFrame, used when interaction frame is not
well defined by outgoing particles)
well defined by outgoing particles)
G4PolarizedPEEffectCrossSection
(based on McMaster, Rev.Mod.Phys. 33 (1961) 8)
G4PolarizedPEEffectModel
@@ -206,25 +240,25 @@ G4eplusPolarizedAnnihilation - enabled AtRest
G4eplusPolarizedAnnihilation renamed local variable "particle" to
avoid "shadow" Warning on SUN CC
- G4PolarizedAnnihilationModel
copied Initialise() method from G4eeToTwoGammaModel provide a
copied Initialise() method from G4eeToTwoGammaModel provide a
ParticleChangeForGamma object, this avoids "shadow" Warning on SUNCC
and reduces overhead in SampleSecondaries()
11 June 07: V.Ivanchenko (empolar-V08-03-02)
- (A.Schaelicke) G4PolarizedCompton, G4ePolarizedIonisation,
G4eplusPolarizedAnnihilation added method
PostStepGetPhysicalInteractionLength in order to provide
simulation of polarized target; the fix is required because of design
- (A.Schaelicke) G4PolarizedCompton, G4ePolarizedIonisation,
G4eplusPolarizedAnnihilation added method
PostStepGetPhysicalInteractionLength in order to provide
simulation of polarized target; the fix is required because of design
change in utils
25 May 07: V.Ivanchenko (empolar-V08-03-01)
- G4PolarizedCompton - fix compilation warning and incorrect usage of
- G4PolarizedCompton - fix compilation warning and incorrect usage of
G4PhysicsVector
23 May 07: V.Ivanchenko (empolar-V08-03-00)
- In all processes inherit from G4VEnergyLossProcess or G4VEmProcess
- In all processes inherit from G4VEnergyLossProcess or G4VEmProcess
remove method SecondaryPostStep;
- G4VEmModel - changed interface of SampleSecondary method, it become
- G4VEmModel - changed interface of SampleSecondary method, it become
void, extra parameter std::vector<G4DynamicParticle*>*, all
classes using or inhereting this interface are modified.
@@ -255,7 +289,7 @@ G4eplusPolarizedAnnihilation - enabled AtRest
to other polarized processes)
- G4PolarizedBhabhaCrossSection and G4PolarizedMollerCrossSection :
new cross section calculation to make polarization vector conform to
other polarized processes
other polarized processes
29 Sept 06: G.Cosmo (empolar-V08-01-01)
- Fixed for usage of std namespace and porting on WIN32-VC platform.
@@ -23,18 +23,13 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizationHelper
//
// Author: Andreas Schaelicke
//
// Creation date: 12.08.2006
//
// Class Description:
//
// Provides some basic polarization transformation routines.
#ifndef G4PolarizationHelper_h
@@ -42,17 +37,17 @@
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
class G4PolarizationHelper
{
public:
static G4ThreeVector GetFrame(const G4ThreeVector&, const G4ThreeVector&);
static G4ThreeVector GetParticleFrameX(const G4ThreeVector&);
static G4ThreeVector GetParticleFrameY(const G4ThreeVector&);
static G4ThreeVector GetRandomFrame(const G4ThreeVector&);
class G4PolarizationHelper {
public:
static G4ThreeVector GetFrame(const G4ThreeVector &, const G4ThreeVector &);
static G4ThreeVector GetParticleFrameX(const G4ThreeVector &);
static G4ThreeVector GetParticleFrameY(const G4ThreeVector &);
static G4ThreeVector GetRandomFrame(const G4ThreeVector &);
static G4ThreeVector GetSpinInPRF(const G4ThreeVector &uZ,const G4ThreeVector &spin);
static G4ThreeVector GetSpinInPRF(const G4ThreeVector& uZ,
const G4ThreeVector& spin);
static void TestPolarizationTransformations();
static void TestInteractionFrame();
@@ -23,52 +23,46 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class header file
//
// Geant44 Class header file
//
// File name: G4PolarizationManager
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
// 12-08-06 Helper routines are moved to G4PolarizationHelper
//
// Class Description:
//
// Provides polarization information for logical volumes, and some basic
// transformation routines.
// Provides polarization information for logical volumes
#ifndef G4PolarizationManager_h
#define G4PolarizationManager_h 1
#include "globals.hh"
#include <vector>
#include "G4StokesVector.hh"
#include "G4ThreeVector.hh"
#include <vector>
#include <map>
class G4LogicalVolume;
class G4PolarizationMessenger;
typedef std::map<G4LogicalVolume*,G4ThreeVector> PolarizationMap;
typedef std::map<G4LogicalVolume*, G4ThreeVector> PolarizationMap;
class G4PolarizationManager {
public:
virtual ~G4PolarizationManager();
class G4PolarizationManager
{
public:
~G4PolarizationManager();
static G4PolarizationManager* GetInstance();
static void Dispose();
void ListVolumes();
inline void Clean();
void SetVolumePolarization(G4LogicalVolume* lVol, const G4ThreeVector & pol);
void SetVolumePolarization(const G4String & lVolName, const G4ThreeVector & pol);
void SetVolumePolarization(G4LogicalVolume* lVol, const G4ThreeVector& pol);
void SetVolumePolarization(const G4String& lVolName,
const G4ThreeVector& pol);
inline const G4ThreeVector & GetVolumePolarization(G4LogicalVolume* lVol) const;
inline const G4StokesVector GetVolumePolarization(
G4LogicalVolume* lVol) const;
inline bool IsPolarized(G4LogicalVolume* lVol) const;
inline void SetVerbose(G4int val);
@@ -77,54 +71,61 @@ public:
inline void SetActivated(G4bool val);
inline bool IsActivated() const;
private:
G4PolarizationManager& operator=(const G4PolarizationManager& right) = delete;
G4PolarizationManager(const G4PolarizationManager&) = delete;
private:
G4PolarizationManager();
static G4ThreadLocal G4PolarizationManager* fInstance;
G4ThreeVector zeroPolarization;
PolarizationMap volumePolarizations;
G4PolarizationMessenger * messenger;
G4PolarizationMessenger* fMessenger;
G4int verboseLevel;
G4bool activated;
PolarizationMap fVolumePolarizations;
static G4ThreadLocal G4PolarizationManager* instance;
G4int fVerboseLevel;
G4bool fActivated;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline const G4ThreeVector & G4PolarizationManager::GetVolumePolarization(G4LogicalVolume* lVol) const
inline const G4StokesVector G4PolarizationManager::GetVolumePolarization(
G4LogicalVolume* lVol) const
{
if (!activated) return zeroPolarization;
PolarizationMap::const_iterator cit=volumePolarizations.find(lVol);
if (cit!=volumePolarizations.end()) return cit->second;
return zeroPolarization;
if(!fActivated)
return G4StokesVector::ZERO;
PolarizationMap::const_iterator cit = fVolumePolarizations.find(lVol);
if(cit != fVolumePolarizations.end())
{
const G4StokesVector vec = G4StokesVector(cit->second);
return vec;
}
return G4StokesVector::ZERO;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline bool G4PolarizationManager::IsPolarized(G4LogicalVolume* lVol) const
{
if (!activated) return false;
PolarizationMap::const_iterator cit=volumePolarizations.find(lVol);
return (cit!=volumePolarizations.end());
if(!fActivated)
return false;
PolarizationMap::const_iterator cit = fVolumePolarizations.find(lVol);
return (cit != fVolumePolarizations.end());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4PolarizationManager::SetVerbose(G4int val) { verboseLevel = val; }
inline G4int G4PolarizationManager::GetVerbose() const { return verboseLevel; }
inline void G4PolarizationManager::SetVerbose(G4int val)
{
fVerboseLevel = val;
}
inline G4int G4PolarizationManager::GetVerbose() const { return fVerboseLevel; }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4PolarizationManager::SetActivated(G4bool val) { activated = val; }
inline bool G4PolarizationManager::IsActivated() const { return activated; }
inline void G4PolarizationManager::SetActivated(G4bool val)
{
fActivated = val;
}
inline bool G4PolarizationManager::IsActivated() const { return fActivated; }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4PolarizationManager::Clean() { volumePolarizations.clear(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline void G4PolarizationManager::Clean() { fVolumePolarizations.clear(); }
#endif
@@ -25,66 +25,59 @@
//
// -------------------------------------------------------------------
//
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizationMessenger
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
//
// Class Description:
//
// Provides access to general polarization information and to
// polarization for logical volumes through macro files.
//
// Provides access to general polarization information and to
// polarization for logical volumes through macro files.
#ifndef G4PolarizationMessenger_h
#define G4PolarizationMessenger_h 1
class G4PolarizationManager;
class G4UIdirectory;
class G4UIcmdWithoutParameter;
class G4UIcmdWithAString;
class G4UIcmdWithAnInteger;
class G4UIcmdWithABool;
class G4UIcommand;
#include "G4UImessenger.hh"
#include "globals.hh"
#include "G4UImessenger.hh"
class G4PolarizationMessenger: public G4UImessenger
class G4PolarizationManager;
class G4UIcmdWithABool;
class G4UIcmdWithAnInteger;
class G4UIcmdWithAString;
class G4UIcmdWithoutParameter;
class G4UIcommand;
class G4UIdirectory;
class G4PolarizationMessenger : public G4UImessenger
{
public:
explicit G4PolarizationMessenger(G4PolarizationManager* runMgr);
~G4PolarizationMessenger();
public:
explicit G4PolarizationMessenger(G4PolarizationManager* runMgr);
~G4PolarizationMessenger() override;
public:
void SetNewValue(G4UIcommand * command,G4String newValues) override;
G4String GetCurrentValue(G4UIcommand * command) override;
private:
G4PolarizationManager * polarizationManager;
private: //commands
G4UIdirectory * polarizationDirectory;
void SetNewValue(G4UIcommand* command, G4String newValues) override;
G4String GetCurrentValue(G4UIcommand* command) override;
G4UIdirectory * managerDirectory;
G4UIcmdWithAnInteger * verboseCmd;
G4UIcmdWithABool * optActivateCmd;
G4UIdirectory * volumeDirectory;
G4UIcmdWithoutParameter * printVolumeListCmd;
G4UIcommand * setPolarizationCmd;
G4PolarizationManager* polarizationManager;
G4UIdirectory * testDirectory;
G4UIcmdWithoutParameter * testPolarizationTransformationCmd;
G4UIcmdWithoutParameter * testInteractionFrameCmd;
G4PolarizationMessenger& operator=(const G4PolarizationMessenger& right) =
delete;
G4PolarizationMessenger(const G4PolarizationMessenger&) = delete;
private:
G4UIdirectory* polarizationDirectory;
G4UIdirectory* managerDirectory;
G4UIcmdWithAnInteger* verboseCmd;
G4UIcmdWithABool* optActivateCmd;
G4UIdirectory* volumeDirectory;
G4UIcmdWithoutParameter* printVolumeListCmd;
G4UIcommand* setPolarizationCmd;
G4UIdirectory* testDirectory;
G4UIcmdWithoutParameter* testPolarizationTransformationCmd;
G4UIcmdWithoutParameter* testInteractionFrameCmd;
};
#endif
@@ -23,90 +23,68 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
// Geant4 Class header file
//
// File name: G4PolarizedAnnihilation
//
// File name: G4eplusPolarizedAnnihilation
//
// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
//
// Creation date: 02.07.2006
//
// Modifications:
// 26-07-06 modified cross section (P. Starovoitov)
// 21-08-06 interface updated (A. Schaelicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
//
// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
//
// Class Description:
// Polarized process of e+ annihilation into 2 gammas
//
// Polarized process of e+ annihilation into 2 gammas
//
// -------------------------------------------------------------------
//
#ifndef G4eplusPolarizedAnnihilation_h
#define G4eplusPolarizedAnnihilation_h 1
#ifndef G4PolarizedAnnihilation_h
#define G4PolarizedAnnihilation_h 1
#include "globals.hh"
#include "G4eplusAnnihilation.hh"
#include "G4Positron.hh"
#include "G4VEmModel.hh"
class G4PolarizedAnnihilationModel;
class G4eplusPolarizedAnnihilation : public G4eplusAnnihilation
class G4PolarizedAnnihilation : public G4eplusAnnihilation
{
public:
explicit G4PolarizedAnnihilation(const G4String& name = "pol-annihil");
public:
virtual ~G4PolarizedAnnihilation() override;
explicit G4eplusPolarizedAnnihilation(const G4String& name = "pol-annihil");
virtual ~G4eplusPolarizedAnnihilation();
// Print out of the class parameters
virtual void PrintInfo() override;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
virtual G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
G4double previousStepSize,
G4ForceCondition* condition) override;
virtual G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition) override;
virtual void BuildPhysicsTable(const G4ParticleDefinition&) override;
private:
G4PolarizedAnnihilation& operator=(const G4PolarizedAnnihilation& right) =
delete;
G4PolarizedAnnihilation(const G4PolarizedAnnihilation&) = delete;
private:
void CleanTables();
void BuildAsymmetryTables(const G4ParticleDefinition& part);
G4double ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle,
G4double cut,
G4double &tasm);
G4double ComputeAsymmetry(G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle, G4double cut,
G4double& tasm);
G4double ComputeSaturationFactor(const G4Track& aTrack);
G4eplusPolarizedAnnihilation& operator=(const G4eplusPolarizedAnnihilation &right);
G4eplusPolarizedAnnihilation(const G4eplusPolarizedAnnihilation& );
G4PolarizedAnnihilationModel* fEmModel;
G4bool isInitialised;
// for polarization:
G4PolarizedAnnihilationModel* emModel;
G4ThreeVector theTargetPolarization;
G4PhysicsTable* theAsymmetryTable; // table for cross section assym.
G4PhysicsTable* theTransverseAsymmetryTable; // table for transverse cross section assym.
// table for cross section asymmetry
G4PhysicsTable* fAsymmetryTable;
// table for transverse cross section asymmetry
G4PhysicsTable* fTransverseAsymmetryTable;
};
#endif
@@ -23,122 +23,112 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizedAnnihilationModel
//
// Author: Andreas Schaelicke and Pavel Starovoitov
//
// Creation date: 01.05.2005
//
// Modifications:
// 18-07-06 use newly calculated cross sections (P. Starovoitov)
// 21-08-06 update interface to geant4.8.1 (A. Schaelicke)
// 10-07-07 copied Initialise() method from G4eeToTwoGammaModel to provide a
// ParticleChangeForGamma object (A. Schaelicke)
//
//
// Class Description:
// Implementation of polarized gamma Annihilation scattering on free electron
//
// Implementation of polarized gamma Annihilation scattering on free electron
//
// -------------------------------------------------------------------
//
#ifndef G4PolarizedAnnihilationModel_h
#define G4PolarizedAnnihilationModel_h 1
#include "globals.hh"
#include "G4eeToTwoGammaModel.hh"
#include "G4ThreeVector.hh"
#include "G4StokesVector.hh"
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4ParticleChangeForGamma;
class G4PolarizedAnnihilationCrossSection;
class G4ParticleDefinition;
class G4PolarizedAnnihilationXS;
class G4PolarizedAnnihilationModel : public G4eeToTwoGammaModel
{
public:
explicit G4PolarizedAnnihilationModel(
const G4ParticleDefinition* p = nullptr,
const G4String& nam = "Polarized-Annihilation");
public:
virtual ~G4PolarizedAnnihilationModel() override;
explicit G4PolarizedAnnihilationModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "Polarized-Annihilation");
virtual void Initialise(const G4ParticleDefinition*,
const G4DataVector&) override;
virtual ~G4PolarizedAnnihilationModel();
virtual G4double ComputeCrossSectionPerElectron(G4double kinEnergy) override;
virtual void Initialise(const G4ParticleDefinition*,
const G4DataVector&) final;
virtual G4double
ComputeCrossSectionPerElectron(G4double kinEnergy) final;
void ComputeAsymmetriesPerElectron(G4double gammaEnergy,
G4double & valueX,
G4double & valueA,
G4double & valueT);
void ComputeAsymmetriesPerElectron(G4double gammaEnergy, G4double& valueX,
G4double& valueA, G4double& valueT);
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) final;
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) final;
// polarized routines
inline void SetTargetPolarization(const G4ThreeVector & pTarget);
inline void SetBeamPolarization(const G4ThreeVector & pBeam);
inline const G4ThreeVector & GetTargetPolarization() const;
inline const G4ThreeVector & GetBeamPolarization() const;
inline const G4ThreeVector & GetFinalGamma1Polarization() const;
inline const G4ThreeVector & GetFinalGamma2Polarization() const;
// polarized routines
inline void SetTargetPolarization(const G4ThreeVector& pTarget);
inline void SetBeamPolarization(const G4ThreeVector& pBeam);
inline const G4ThreeVector& GetTargetPolarization() const;
inline const G4ThreeVector& GetBeamPolarization() const;
inline const G4ThreeVector& GetFinalGamma1Polarization() const;
inline const G4ThreeVector& GetFinalGamma2Polarization() const;
private:
G4PolarizedAnnihilationModel& operator =(
const G4PolarizedAnnihilationModel& right) = delete;
G4PolarizedAnnihilationModel(const G4PolarizedAnnihilationModel&) = delete;
// hide assignment operator
G4PolarizedAnnihilationModel &
operator=(const G4PolarizedAnnihilationModel &right) = delete;
G4PolarizedAnnihilationModel(const G4PolarizedAnnihilationModel&) = delete;
private:
G4PolarizedAnnihilationXS* fCrossSectionCalculator;
G4ParticleChangeForGamma* fParticleChange;
G4PolarizedAnnihilationCrossSection * crossSectionCalculator;
// incomming
G4StokesVector theBeamPolarization; // positron
G4StokesVector theTargetPolarization; // electron
// incoming
G4StokesVector fBeamPolarization; // positron
G4StokesVector fTargetPolarization; // electron
// outgoing
G4StokesVector finalGamma1Polarization;
G4StokesVector finalGamma2Polarization;
G4StokesVector fFinalGamma1Polarization;
G4StokesVector fFinalGamma2Polarization;
G4int verboseLevel;
G4ParticleChangeForGamma* gParticleChange;
G4int fVerboseLevel;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4PolarizedAnnihilationModel::SetTargetPolarization(const G4ThreeVector & pTarget)
inline void G4PolarizedAnnihilationModel::SetTargetPolarization(
const G4ThreeVector& pTarget)
{
theTargetPolarization = pTarget;
fTargetPolarization = G4StokesVector(pTarget);
}
inline void G4PolarizedAnnihilationModel::SetBeamPolarization(const G4ThreeVector & pBeam)
inline void G4PolarizedAnnihilationModel::SetBeamPolarization(
const G4ThreeVector& pBeam)
{
theBeamPolarization = pBeam;
fBeamPolarization = G4StokesVector(pBeam);
}
inline const G4ThreeVector & G4PolarizedAnnihilationModel::GetTargetPolarization() const
inline const G4ThreeVector&
G4PolarizedAnnihilationModel::GetTargetPolarization() const
{
return theTargetPolarization;
return fTargetPolarization;
}
inline const G4ThreeVector & G4PolarizedAnnihilationModel::GetBeamPolarization() const
inline const G4ThreeVector& G4PolarizedAnnihilationModel::GetBeamPolarization()
const
{
return theBeamPolarization;
return fBeamPolarization;
}
inline const G4ThreeVector & G4PolarizedAnnihilationModel::GetFinalGamma1Polarization() const
inline const G4ThreeVector&
G4PolarizedAnnihilationModel::GetFinalGamma1Polarization() const
{
return finalGamma1Polarization;
return fFinalGamma1Polarization;
}
inline const G4ThreeVector & G4PolarizedAnnihilationModel::GetFinalGamma2Polarization() const
inline const G4ThreeVector&
G4PolarizedAnnihilationModel::GetFinalGamma2Polarization() const
{
return finalGamma2Polarization;
return fFinalGamma2Polarization;
}
#endif
@@ -24,78 +24,83 @@
// ********************************************************************
//
// -------------------------------------------------------------------
// -------------------------------------------------------------------
//
// GEANT4 Class file
// Geant4 Class file
//
//
// File name: PolarizedAnnihilationCrossSection
// File name: G4PolarizedAnnihilationXS
//
// Author: Andreas Schaelicke and Pavel Starovoitov
//
// Creation date: 22.03.2006
//
// Modifications:
// 15.10.07 introduced a more general framework for cross sections
//
// Class Description:
// * calculates the differential cross section (ME squared,
// without phase space) incoming positron (along positive z direction)
// annihilations with an electron at rest
// * phi denotes the angle between the scattering plane and
// X axis of incoming partice reference frame (PRF)
//
#ifndef G4PolarizedAnnihilationCrossSection_h
#define G4PolarizedAnnihilationCrossSection_h 1
// * calculates the differential cross section (ME squared,
// without phase space) incoming positron (along positive z direction)
// annihilations with an electron at rest
// * phi denotes the angle between the scattering plane and
// X axis of incoming partice reference frame (PRF)
#ifndef G4PolarizedAnnihilationXS_h
#define G4PolarizedAnnihilationXS_h 1
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedAnnihilationCrossSection : public G4VPolarizedCrossSection
class G4PolarizedAnnihilationXS : public G4VPolarizedXS
{
public:
G4PolarizedAnnihilationCrossSection();
virtual ~G4PolarizedAnnihilationCrossSection();
public:
virtual void Initialize(G4double eps, G4double gamma, G4double phi,
const G4StokesVector & p0,const G4StokesVector & p1,
G4int flag=0) override;
public:
G4PolarizedAnnihilationXS();
virtual ~G4PolarizedAnnihilationXS() override;
G4double DiceEpsilon();
virtual G4double XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3) override;
virtual G4double TotalXSection(G4double xmin, G4double xmax,
G4double y,
const G4StokesVector & pol0,
const G4StokesVector & pol1) override;
virtual void Initialize(G4double eps, G4double gamma, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
G4double DiceEpsilon();
virtual G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
virtual G4double TotalXSection(G4double xmin, G4double xmax, G4double y,
const G4StokesVector& pol0,
const G4StokesVector& pol1) override;
// return expected mean polarisation
G4StokesVector GetPol2() override;
G4StokesVector GetPol3() override;
virtual G4StokesVector GetPol2() override;
virtual G4StokesVector GetPol3() override;
virtual G4double GetXmin(G4double y) override; // minimal energy fraction in TotalXSection
virtual G4double GetXmax(G4double y) override; // maximal energy fraction in TotalXSection
// minimal energy fraction in TotalXSection
virtual G4double GetXmin(G4double y) override;
// maximal energy fraction in TotalXSection
virtual G4double GetXmax(G4double y) override;
G4double getVar(G4int );
G4double getVar(G4int);
// test routine
void getCoeff();
private:
G4PolarizedAnnihilationXS& operator=(const G4PolarizedAnnihilationXS& right) =
delete;
G4PolarizedAnnihilationXS(const G4PolarizedAnnihilationXS&) = delete;
private:
void TotalXS();
void DefineCoefficients(const G4StokesVector & pol0,
const G4StokesVector & pol1);
void DefineCoefficients(const G4StokesVector& pol0,
const G4StokesVector& pol1);
static constexpr G4double re2 =
CLHEP::classic_electr_radius * CLHEP::classic_electr_radius;
G4double polxx, polyy, polzz, polxz, polzx, polxy, polyx, polyz, polzy;
G4double re2, diffXSFactor, totalXSFactor;
// - unpolarised + part depending on the polarization of the initial pair
G4double phi0;
// - part depending on the polarization of the final positron
G4ThreeVector phi2;
G4ThreeVector fPhi2;
// - part depending on the polarization of the final electron
G4ThreeVector phi3;
G4double dice;
G4double polXS, unpXS;
G4ThreeVector fPhi3;
G4double polxx, polyy, polzz, polxz, polzx, polxy, polyx, polyz, polzy;
// - unpolarised + part depending on the polarization of the initial pair
G4double fPhi0;
G4double fDice;
G4double fPolXS, fUnpXS;
G4double ISPxx, ISPyy, ISPzz, ISPnd;
};
#endif
@@ -23,41 +23,43 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
// Geant4 Class header file
//
//
// File name: G4ePolarizedBremsstrahlung
// File name: G4PolarizedBremsstrahlung
//
// Author: Karim Laihem based on code by Michel Maire
//
// Creation date: 01.05.2005
//
// Modifications:
// 21-08-06 Modified to work in g4.8.1 framework (A.Schaelicke)
//
// Class Description:
//
// polarized version of G4eBremsstrahlung
// polarized version of G4eBremsstrahlung
#ifndef G4ePolarizedBremsstrahlung_h
#define G4ePolarizedBremsstrahlung_h 1
#ifndef G4PolarizedBremsstrahlung_h
#define G4PolarizedBremsstrahlung_h 1
#include "globals.hh"
#include "G4eBremsstrahlung.hh"
class G4ePolarizedBremsstrahlung : public G4eBremsstrahlung
class G4ParticleDefinition;
class G4PolarizedBremsstrahlung : public G4eBremsstrahlung
{
public:
explicit G4PolarizedBremsstrahlung(const G4String& name = "pol-eBrem");
virtual ~G4PolarizedBremsstrahlung() override;
public:
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
explicit G4ePolarizedBremsstrahlung(const G4String& name = "pol-eBrem");
G4PolarizedBremsstrahlung& operator=(const G4PolarizedBremsstrahlung& right) =
delete;
G4PolarizedBremsstrahlung(const G4PolarizedBremsstrahlung&) = delete;
protected:
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
const G4ParticleDefinition*) override;
protected:
virtual void InitialiseEnergyLossProcess(
const G4ParticleDefinition*, const G4ParticleDefinition*) override;
private:
G4bool isInitialised = false;
};
#endif
@@ -23,71 +23,62 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
// Geant4 Class header file
//
//
// File name: G4ePolarizedBremsstrahlungModel
// File name: G4PolarizedBremsstrahlungModel
//
// Author: Karim Laihem based on code by Michel Maire
//
// Creation date: 01.05.2005
//
// Modifications:
// 21-08-06 Modified to work in g4.8.1 framework (A.Schaelicke)
//
// Class Description:
//
// Implementation of energy loss for gamma emission by polarized
// Implementation of energy loss for gamma emission by polarized
// electrons and positrons
// -------------------------------------------------------------------
//
#ifndef G4ePolarizedBremsstrahlungModel_h
#define G4ePolarizedBremsstrahlungModel_h 1
#ifndef G4PolarizedBremsstrahlungModel_h
#define G4PolarizedBremsstrahlungModel_h 1
#include "G4SeltzerBergerModel.hh"
class G4DataVector;
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4ParticleDefinition;
class G4VPolarizedXS;
class G4VPolarizedCrossSection;
class G4ePolarizedBremsstrahlungModel : public G4SeltzerBergerModel
class G4PolarizedBremsstrahlungModel : public G4SeltzerBergerModel
{
public:
explicit G4PolarizedBremsstrahlungModel(
const G4ParticleDefinition* p = nullptr, const G4String& nam = "PolBrem");
public:
virtual ~G4PolarizedBremsstrahlungModel() override;
explicit G4ePolarizedBremsstrahlungModel(const G4ParticleDefinition* p=nullptr,
const G4String& nam = "PolBrem");
virtual ~G4ePolarizedBremsstrahlungModel();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
virtual void Initialise(const G4ParticleDefinition*,
const G4DataVector&) override;
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) override;
inline const G4Element* SelectedAtom();
protected:
G4VPolarizedCrossSection* crossSectionCalculator;
G4PolarizedBremsstrahlungModel& operator=(
const G4PolarizedBremsstrahlungModel& right) = delete;
G4PolarizedBremsstrahlungModel(const G4PolarizedBremsstrahlungModel&) =
delete;
private:
G4VPolarizedXS* fCrossSectionCalculator;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4Element* G4ePolarizedBremsstrahlungModel::SelectedAtom()
inline const G4Element* G4PolarizedBremsstrahlungModel::SelectedAtom()
{
return GetCurrentElement();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,56 +23,49 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedBremsstrahlungCrossSection
// File name: G4PolarizedBremsstrahlungXS
//
// Author: Karim Laihem and Andreas Schaelicke
//
// Creation date: 15.05.2005
//
// Modifications:
// 15.10.07 introduced a more general framework for cross sections (AS)
//
// Class Description:
// determine the polarization of the final state
// in a Bremsstrahlung scattering process employing the differential
// determine the polarization of the final state
// in a bremsstrahlung scattering process employing the differential
// cross section by Olsen and Maximon
//
#ifndef G4PolarizedBremsstrahlungCrossSection_h
#define G4PolarizedBremsstrahlungCrossSection_h 1
#ifndef G4PolarizedBremsstrahlungXS_h
#define G4PolarizedBremsstrahlungXS_h 1
#include "globals.hh"
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedBremsstrahlungCrossSection : public G4VPolarizedCrossSection
class G4PolarizedBremsstrahlungXS : public G4VPolarizedXS
{
public:
G4PolarizedBremsstrahlungCrossSection();
virtual void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector & p0,
const G4StokesVector & p1,
G4int flag=0) override;
virtual G4double XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3) override;
G4PolarizedBremsstrahlungXS();
~G4PolarizedBremsstrahlungXS() override;
void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
// return expected mean polarisation
G4StokesVector GetPol2() override; // electron/positron
G4StokesVector GetPol3() override; // photon
G4PolarizedBremsstrahlungXS& operator =(
const G4PolarizedBremsstrahlungXS& right) = delete;
G4PolarizedBremsstrahlungXS(const G4PolarizedBremsstrahlungXS&) = delete;
private:
static G4double SCRN[2][19]; // screening function lookup table
G4StokesVector theFinalLeptonPolarization;
G4StokesVector theFinalGammaPolarization;
void InitializeMe();
static G4bool scrnInitialized;
static G4double SCRN [3][20]; // screening function lookup table;
G4StokesVector fFinalLeptonPolarization;
G4StokesVector fFinalGammaPolarization;
};
#endif
@@ -25,114 +25,85 @@
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizedCompton
//
// Author: Andreas Schaelicke
// based on code by Michel Maire / Vladimir IVANTCHENKO
//
// Class description
//
// modified version respecting media and beam polarization
// using the stokes formalism
//
// Creation date: 01.05.2005
//
// Modifications:
//
// 01-01-05, include polarization description (A.Stahl)
// 01-01-05, create asymmetry table and determine interactionlength (A.Stahl)
// 01-05-05, update handling of media polarization (A.Schalicke)
// 01-05-05, update polarized differential cross section (A.Schalicke)
// 26-07-06, cross section recalculated (P.Starovoitov)
// 09-08-06, make it work under current geant4 release (A.Schalicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
// polarized version of Compton scattering
//
// -----------------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef PolarizedComptonScattering_h
#define PolarizedComptonScattering_h 1
#include "globals.hh"
#include "G4VEmProcess.hh"
#include "G4Gamma.hh"
#include "G4VEmProcess.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4ParticleDefinition;
class G4MaterialCutsCouple;
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4ParticleDefinition;
class G4PolarizedComptonModel;
class G4PolarizedCompton : public G4VEmProcess
{
public: // with description
public:
explicit G4PolarizedCompton(const G4String& processName = "pol-compt",
G4ProcessType type = fElectromagnetic);
explicit G4PolarizedCompton(const G4String& processName ="pol-compt",
G4ProcessType type = fElectromagnetic);
virtual ~G4PolarizedCompton() override;
virtual ~G4PolarizedCompton();
// true for Gamma only.
// true for Gamma only.
virtual G4bool IsApplicable(const G4ParticleDefinition&) override;
// Print few lines of informations about the process: validity range,
virtual void PrintInfo() override;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
void SetModel(const G4String& name);
protected:
G4PolarizedCompton& operator=(const G4PolarizedCompton& right) = delete;
G4PolarizedCompton(const G4PolarizedCompton&) = delete;
protected:
virtual void InitialiseProcess(const G4ParticleDefinition*) override;
// added for polarization treatment of polarized media:
virtual void BuildPhysicsTable(const G4ParticleDefinition&) override;
virtual G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition) override;
virtual G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition) override;
virtual G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
private:
const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition) override;
private:
static G4PhysicsTable* theAsymmetryTable; // table for crosssection asymmetry
void CleanTable();
void BuildAsymmetryTable(const G4ParticleDefinition& part);
G4double ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle,
G4double cut,
G4double & tAsymmetry);
G4double ComputeAsymmetry(G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle, G4double cut,
G4double& tAsymmetry);
G4double ComputeSaturationFactor(const G4Track& aTrack);
G4PolarizedCompton& operator=(const G4PolarizedCompton &right) = delete;
G4PolarizedCompton(const G4PolarizedCompton& ) = delete;
G4bool buildAsymmetryTable;
G4bool useAsymmetryTable;
G4bool isInitialised;
G4int mType;
G4PolarizedComptonModel* fEmModel;
// added for polarization treatment:
G4PolarizedComptonModel* emModel;
static G4PhysicsTable* theAsymmetryTable; // table for crosssection assymmetry
G4ThreeVector targetPolarization;
G4int fType;
G4bool fBuildAsymmetryTable;
G4bool fUseAsymmetryTable;
G4bool fIsInitialised;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,114 +23,108 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizedComptonModel
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
// 18-07-06 use newly calculated cross sections (P. Starovoitov)
// 21-08-05 update interface (A. Schaelicke)
//
//
// Class Description:
//
// Implementation of polarized gamma Compton scattering on free electron
//
// -------------------------------------------------------------------
//
// Implementation of polarized gamma Compton scattering on free electron
#ifndef G4PolarizedComptonModel_h
#define G4PolarizedComptonModel_h 1
#include "globals.hh"
#include "G4KleinNishinaCompton.hh"
#include "G4StokesVector.hh"
#include "G4ThreeVector.hh"
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4ParticleDefinition;
class G4ParticleChangeForGamma;
class G4PolarizedComptonCrossSection;
class G4VPolarizedXS;
class G4PolarizedComptonModel : public G4KleinNishinaCompton
{
public:
public:
explicit G4PolarizedComptonModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "Polarized-Compton");
const G4String& nam = "Polarized-Compton");
virtual G4double ComputeCrossSectionPerAtom(
const G4ParticleDefinition*,
G4double kinEnergy,
G4double Z,
G4double A,
G4double cut,
G4double emax) override;
virtual ~G4PolarizedComptonModel() override;
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
G4double kinEnergy, G4double Z,
G4double A, G4double cut,
G4double emax) override;
G4double ComputeAsymmetryPerAtom(G4double gammaEnergy, G4double Z);
virtual ~G4PolarizedComptonModel();
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) override;
// polarized routines
inline void SetTargetPolarization(const G4ThreeVector & pTarget);
inline void SetBeamPolarization(const G4ThreeVector & pBeam);
inline const G4ThreeVector & GetTargetPolarization() const;
inline const G4ThreeVector & GetBeamPolarization() const;
inline const G4ThreeVector & GetFinalGammaPolarization() const;
inline const G4ThreeVector & GetFinalElectronPolarization() const;
private:
void PrintWarning(const G4DynamicParticle*, G4int, G4double grej,
G4double onecos, G4double phi, const G4String) const;
// polarized routines
inline void SetTargetPolarization(const G4ThreeVector& pTarget);
inline void SetBeamPolarization(const G4ThreeVector& pBeam);
inline const G4ThreeVector& GetTargetPolarization() const;
inline const G4ThreeVector& GetBeamPolarization() const;
inline const G4ThreeVector& GetFinalGammaPolarization() const;
inline const G4ThreeVector& GetFinalElectronPolarization() const;
// hide assignment operator
G4PolarizedComptonModel & operator=(const G4PolarizedComptonModel &right) = delete;
G4PolarizedComptonModel(const G4PolarizedComptonModel&) = delete;
G4PolarizedComptonModel& operator=(const G4PolarizedComptonModel& right) =
delete;
G4PolarizedComptonModel(const G4PolarizedComptonModel&) = delete;
G4PolarizedComptonCrossSection * crossSectionCalculator;
// incomming
G4StokesVector theBeamPolarization; // photon
G4StokesVector theTargetPolarization; // electron
private:
void PrintWarning(const G4DynamicParticle*, G4int, G4double grej,
G4double onecos, G4double phi, const G4String) const;
static constexpr G4int fLoopLim = 10000;
G4VPolarizedXS* fCrossSectionCalculator;
// incoming
G4StokesVector fBeamPolarization; // photon
G4StokesVector fTargetPolarization; // electron
// outgoing
G4StokesVector finalGammaPolarization;
G4StokesVector fFinalGammaPolarization;
G4StokesVector finalElectronPolarization;
G4int verboseLevel;
G4int fVerboseLevel;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline void G4PolarizedComptonModel::SetTargetPolarization(const G4ThreeVector & pTarget)
inline void G4PolarizedComptonModel::SetTargetPolarization(
const G4ThreeVector& pTarget)
{
theTargetPolarization = pTarget;
fTargetPolarization = G4StokesVector(pTarget);
}
inline void G4PolarizedComptonModel::SetBeamPolarization(const G4ThreeVector & pBeam)
inline void G4PolarizedComptonModel::SetBeamPolarization(
const G4ThreeVector& pBeam)
{
theBeamPolarization = pBeam;
fBeamPolarization = G4StokesVector(pBeam);
}
inline const G4ThreeVector & G4PolarizedComptonModel::GetTargetPolarization() const
inline const G4ThreeVector& G4PolarizedComptonModel::GetTargetPolarization()
const
{
return theTargetPolarization;
return fTargetPolarization;
}
inline const G4ThreeVector & G4PolarizedComptonModel::GetBeamPolarization() const
inline const G4ThreeVector& G4PolarizedComptonModel::GetBeamPolarization() const
{
return theBeamPolarization;
return fBeamPolarization;
}
inline const G4ThreeVector & G4PolarizedComptonModel::GetFinalGammaPolarization() const
inline const G4ThreeVector& G4PolarizedComptonModel::GetFinalGammaPolarization()
const
{
return finalGammaPolarization;
return fFinalGammaPolarization;
}
inline const G4ThreeVector & G4PolarizedComptonModel::GetFinalElectronPolarization() const
inline const G4ThreeVector&
G4PolarizedComptonModel::GetFinalElectronPolarization() const
{
return finalElectronPolarization;
}
@@ -23,89 +23,81 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedComptonCrossSection
// File name: G4PolarizedComptonXS
//
// Author: Andreas Schaelicke
//
// Creation date: 15.05.2005
//
// Modifications:
// 18-07-06 use newly calculated cross sections (P. Starovoitov)
// 21-08-06 update interface to geant4.8.1 (A. Schaelicke)
// 15-10-07 introduced a more general framework for cross sections (AS)
//
//
// Class Description:
// determine the polarization of the final state
// in a Compton scattering process employing the differential
// determine the polarization of the final state
// in a Compton scattering process employing the differential
// cross section by F.W.Lipps & H.A.Tolhoek
// ( Physica 20 (1954) 395 )
//
#ifndef G4PolarizedComptonCrossSection_h
#define G4PolarizedComptonCrossSection_h 1
#ifndef G4PolarizedComptonXS_h
#define G4PolarizedComptonXS_h 1
#include "globals.hh"
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedComptonCrossSection : public G4VPolarizedCrossSection
class G4PolarizedComptonXS : public G4VPolarizedXS
{
public:
G4PolarizedComptonCrossSection();
virtual ~G4PolarizedComptonCrossSection();
public:
// prepares the ingredients for the calculation of a polarization
public:
G4PolarizedComptonXS();
~G4PolarizedComptonXS() override;
// prepares the ingredients for the calculation of a polarization
// dependent differential cross section
// the kinematics is fixed (X - incoming photon energy in units of electron mass,
// eps - outgoing photon energy in unit of incoming photon energy,
// the kinematics is fixed (X - incoming photon energy in units of electron
// mass, eps - outgoing photon energy in unit of incoming photon energy,
// and polarization of the incoming particles fixed (p0, p1)
// a flag specifies the extent to which polarization is taken
// into account
virtual void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector & p0,
const G4StokesVector & p1,
G4int flag=0) override;
// a flag specifies the extent to which polarization is taken into account
void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
// returns the differential cross section for a given polarisation state
// of the final state particles to be used in the calculation of the
// polarization transfer
// the calculation has to be initialised by calling Initialize()
// prior to the first call of this function (see above)
G4double XSection(const G4StokesVector & pol2,const G4StokesVector & pol3) override;
// polarization transfer the calculation has to be initialised by calling
// Initialize() prior to the first call of this function (see above)
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
// total cross section
G4double TotalXSection(G4double xmin, G4double xmax, G4double y,
const G4StokesVector & pol0,const G4StokesVector & pol1) override;
const G4StokesVector& pol0,
const G4StokesVector& pol1) override;
public:
// return expected mean polarisation
G4StokesVector GetPol2() override;
G4StokesVector GetPol3() override;
private:
void DefineCoefficients(const G4StokesVector & pol0,
const G4StokesVector & pol1);
// states if an incoming or outgoing particle is polarized
G4bool gammaPol2, electronPol3;
// these variables store the information necessary to evaluate the
// differential cross section for arbitrary final state
G4PolarizedComptonXS& operator=(const G4PolarizedComptonXS& right) = delete;
G4PolarizedComptonXS(const G4PolarizedComptonXS&) = delete;
private:
void DefineCoefficients(const G4StokesVector& pol0,
const G4StokesVector& pol1);
static constexpr G4double re2 =
CLHEP::classic_electr_radius * CLHEP::classic_electr_radius *
(4. * CLHEP::pi / CLHEP::hbarc) * (4. * CLHEP::pi / CLHEP::hbarc);
// these variables store the information necessary to evaluate the
// differential cross section for arbitrary final state
// polarizations (used in XSection):
// - polarization independent part
G4double phi0;
// - part depending on the polarization of the final photon
G4ThreeVector phi2;
G4ThreeVector fPhi2;
// - part depending on the polarization of the final electron
G4ThreeVector phi3;
G4ThreeVector fPhi3;
// - polarization independent part
G4double fPhi0;
// - product of polarizations of initial particles
G4double polxx, polyy, polzz, polxz, polzx, polyz, polzy, polxy, polyx;
G4double diffXSFactor, totalXSFactor, re2;
G4double polXS, unpXS;
// G4double diffXSFactor, totalXSFactor;
G4double fPolXS, fUnpXS;
};
#endif
@@ -23,25 +23,15 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// -------------------------------------------------------------------
//
//
// File name: G4PolarizedGammaConversion
//
// Author: Karim Laihem based on code by Michel Maire
//
// Creation date: 01.05.2005
//
// Modifications:
// 21-08-06 Modified to work in g4.8.1 framework (A.Schaelicke)
//
// Class Description:
//
// polarized version of G4GammaConversion
// polarized version of G4GammaConversion
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4PolarizedGammaConversion_h
@@ -49,9 +39,6 @@
#include "globals.hh"
#include "G4VEmProcess.hh"
#include "G4Gamma.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4ParticleDefinition;
class G4VEmModel;
@@ -61,34 +48,27 @@ class G4DynamicParticle;
class G4PolarizedGammaConversion : public G4VEmProcess
{
public: // with description
public:
explicit G4PolarizedGammaConversion(const G4String& processName = "pol-conv",
G4ProcessType type = fElectromagnetic);
explicit G4PolarizedGammaConversion(const G4String& processName ="pol-conv",
G4ProcessType type = fElectromagnetic);
virtual ~G4PolarizedGammaConversion();
virtual ~G4PolarizedGammaConversion() override;
// true for Gamma only.
G4bool IsApplicable(const G4ParticleDefinition&) override;
// Print few lines of informations about the process: validity range,
virtual void PrintInfo() override;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
protected:
G4PolarizedGammaConversion& operator=(
const G4PolarizedGammaConversion& right) = delete;
G4PolarizedGammaConversion(const G4PolarizedGammaConversion&) = delete;
protected:
virtual void InitialiseProcess(const G4ParticleDefinition*) override;
private:
// hide assignment operator as private
G4PolarizedGammaConversion&
operator=(const G4PolarizedGammaConversion &right) = delete;
G4PolarizedGammaConversion(const G4PolarizedGammaConversion& ) = delete;
G4bool isInitialised;
private:
G4bool fIsInitialised;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,71 +23,62 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
// Geant4 Class header file
//
// File name: G4PolarizedGammaConversionModel
//
// Author: Karim Laihem
//
// Creation date: 19.04.2005
//
// Modifications:
// 21-08-06 Modified to work in g4.8.1 framework (A.Schaelicke)
//
// Class Description:
//
// Implementation of gamma conversion to e+e- in the field of a nucleus
// including polarization transfer
// Implementation of gamma conversion to e+e- in the field of a nucleus
// including polarization transfer
// -------------------------------------------------------------------
//
#ifndef G4PolarizedGammaConversionModel_h
#define G4PolarizedGammaConversionModel_h 1
#include "G4BetheHeitlerModel.hh"
#include "G4PhysicsTable.hh"
class G4DynamicParticle;
class G4Element;
class G4MaterialCutsCouple;
class G4ParticleChangeForGamma;
class G4VPolarizedCrossSection;
class G4ParticleDefinition;
class G4PolarizedGammaConversionXS;
class G4PolarizedGammaConversionModel : public G4BetheHeitlerModel
{
public:
explicit G4PolarizedGammaConversionModel(
const G4ParticleDefinition* p = nullptr, const G4String& nam = "polConv");
public:
virtual ~G4PolarizedGammaConversionModel() override;
explicit G4PolarizedGammaConversionModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "polConv");
virtual ~G4PolarizedGammaConversionModel();
virtual void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
virtual void Initialise(const G4ParticleDefinition*,
const G4DataVector&) override;
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) override;
inline const G4Element* SelectedAtom();
protected:
G4VPolarizedCrossSection* crossSectionCalculator;
G4PolarizedGammaConversionModel& operator=(
const G4PolarizedGammaConversionModel& right) = delete;
G4PolarizedGammaConversionModel(const G4PolarizedGammaConversionModel&) =
delete;
private:
G4PolarizedGammaConversionXS* fCrossSectionCalculator;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline const G4Element* G4PolarizedGammaConversionModel::SelectedAtom()
{
return GetCurrentElement();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -23,55 +23,44 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedPairProductionCrossSection
// File name: G4PolarizedGammaConversionXS
//
// Author: Karim Laihem
//
// Creation date: 15.05.2005
//
// Modifications:
// 20-08-06 updated interface to geant4.8.1 (A.Schaelicke)
// 15-10-07 introduced a more general framework for cross sections (AS)
//
// Class Description:
// determine the polarization of the final state
// in a Bremsstrahlung scattering process employing the differential
// cross section by Olsen and Maximon
//
#ifndef G4PolarizedPairProductionCrossSection_h
#define G4PolarizedPairProductionCrossSection_h 1
#ifndef G4PolarizedGammaConversionXS_h
#define G4PolarizedGammaConversionXS_h 1
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedPairProductionCrossSection : public G4VPolarizedCrossSection
class G4PolarizedGammaConversionXS : public G4VPolarizedXS
{
public:
G4PolarizedPairProductionCrossSection();
virtual void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector & p0,
const G4StokesVector & p1,
G4int flag=0) override;
virtual G4double XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3) override;
G4PolarizedGammaConversionXS();
~G4PolarizedGammaConversionXS() override;
void Initialize(G4double eps, G4double X, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
// return expected mean polarisation
G4StokesVector GetPol2() override; // electron/positron
G4StokesVector GetPol3() override; // photon
G4PolarizedGammaConversionXS& operator =(
const G4PolarizedGammaConversionXS& right) = delete;
G4PolarizedGammaConversionXS(const G4PolarizedGammaConversionXS&) = delete;
private:
static G4double SCRN[2][19]; // screening function lookup table
G4StokesVector theFinalElectronPolarization;
G4StokesVector theFinalPositronPolarization;
void InitializeMe();
static G4bool scrnInitialized;
static G4double SCRN [3][20]; // screening function lookup table;
G4StokesVector fFinalElectronPolarization;
G4StokesVector fFinalPositronPolarization;
};
#endif
@@ -25,109 +25,81 @@
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
// Geant4 Class header file
//
//
// File name: G4ePolarizedIonisation
// File name: G4PolarizedIonisation
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
//
// Creation date: 10.11.2005
//
// Modifications:
//
// 10-11-05, include polarization description (A.Schaelicke)
// , create asymmetry table and determine interactionlength
// , update polarized differential cross section
//
// 20-08-06, modified interface (A.Schaelicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
//
// Class Description:
//
// polarized version of G4eIonisation
// polarized version of G4eIonisation
// ----------------------------------------------------------------------------
// -------------------------------------------------------------------
//
#ifndef G4ePolarizedIonisation_h
#define G4ePolarizedIonisation_h 1
#ifndef G4PolarizedIonisation_h
#define G4PolarizedIonisation_h 1
#include "globals.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
class G4Material;
class G4MaterialCutsCouple;
class G4ParticleDefinition;
class G4PhysicsTable;
class G4VEmFluctuationModel;
class G4PolarizedMollerBhabhaModel;
class G4PolarizedIonisationModel;
class G4Track;
class G4ePolarizedIonisation : public G4VEnergyLossProcess
class G4PolarizedIonisation : public G4VEnergyLossProcess
{
public:
explicit G4PolarizedIonisation(const G4String& name = "pol-eIoni");
public:
explicit G4ePolarizedIonisation(const G4String& name = "pol-eIoni");
virtual ~G4ePolarizedIonisation();
virtual ~G4PolarizedIonisation() override;
virtual G4bool IsApplicable(const G4ParticleDefinition& p) override;
// Print out of the class parameters
virtual void PrintInfo() override;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
protected:
G4PolarizedIonisation& operator=(const G4PolarizedIonisation& right) = delete;
G4PolarizedIonisation(const G4PolarizedIonisation&) = delete;
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition*,
const G4ParticleDefinition*) override;
protected:
virtual void InitialiseEnergyLossProcess(
const G4ParticleDefinition*, const G4ParticleDefinition*) override;
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition*,
const G4Material*, G4double cut) override;
// for polarization
virtual G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition) override;
virtual G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition) override;
G4double previousStepSize,
G4ForceCondition* condition) override;
virtual void BuildPhysicsTable(const G4ParticleDefinition&) override;
private:
private:
void CleanTables();
void BuildAsymmetryTables(const G4ParticleDefinition& part);
G4double ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle,
G4double cut,
G4double &tasm);
G4double ComputeAsymmetry(G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& particle, G4double cut,
G4double& tasm);
G4double ComputeSaturationFactor(const G4Track& aTrack);
G4ePolarizedIonisation &
operator=(const G4ePolarizedIonisation &right) = delete;
G4ePolarizedIonisation(const G4ePolarizedIonisation&) = delete;
G4VEmFluctuationModel* fFlucModel;
G4PolarizedIonisationModel* fEmModel;
G4ParticleDefinition* theElectron;
G4VEmFluctuationModel* flucModel;
G4PolarizedMollerBhabhaModel* emModel;
G4PhysicsTable* fAsymmetryTable;
G4PhysicsTable* fTransverseAsymmetryTable;
G4bool isElectron;
G4bool isInitialised;
// for polarization:
G4ThreeVector theTargetPolarization;
G4PhysicsTable* theAsymmetryTable;
G4PhysicsTable* theTransverseAsymmetryTable;
G4bool fIsElectron;
G4bool fIsInitialised;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,54 +23,57 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedBhabhaCrossSection
// File name: G4PolarizedIonisationBhabhaXS
//
// Author: Andreas Schaelicke and Pavel Starovoitov
//
// Creation date: 12.01.2006
//
// Modifications:
// 16-01-06 included cross section as calculated by P.Starovoitov
//
// Class Description:
// * calculates the differential cross section (ME squared, without phase space)
// incomming positron (along positive z direction) scatters at an electron at rest
// * phi denotes the angle between the scattering plane and the incoming PRF X-axis
// * calculates the differential cross section (ME squared, without phase
// space)
// * incoming positron (along positive z direction) scatters at an electron at
// rest
// * phi denotes the angle between the scattering plane and the incoming PRF
// X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
//
#ifndef G4PolarizedBhabhaCrossSection_h
#define G4PolarizedBhabhaCrossSection_h 1
#ifndef G4PolarizedIonisationBhabhaXS_h
#define G4PolarizedIonisationBhabhaXS_h 1
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedBhabhaCrossSection : public G4VPolarizedCrossSection
class G4PolarizedIonisationBhabhaXS : public G4VPolarizedXS
{
public:
G4PolarizedBhabhaCrossSection();
virtual ~G4PolarizedBhabhaCrossSection();
public:
void Initialize(G4double x, G4double y, G4double phi,
const G4StokesVector & p0,const G4StokesVector & p1,
G4int flag=0) override;
public:
G4PolarizedIonisationBhabhaXS();
~G4PolarizedIonisationBhabhaXS() override;
G4double XSection(const G4StokesVector & pol2,const G4StokesVector & pol3) override;
void Initialize(G4double x, G4double y, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
G4double TotalXSection(G4double xmin, G4double xmax, G4double y,
const G4StokesVector & pol0,
const G4StokesVector & pol1) override;
const G4StokesVector& pol0,
const G4StokesVector& pol1) override;
// return expected mean polarisation
G4StokesVector GetPol2() override;
G4StokesVector GetPol3() override;
private:
G4double phi0;
// - part depending on the polarization of the final positron
G4ThreeVector phi2;
// - part depending on the polarization of the final electron
G4ThreeVector phi3;
G4PolarizedIonisationBhabhaXS& operator =(
const G4PolarizedIonisationBhabhaXS& right) = delete;
G4PolarizedIonisationBhabhaXS(const G4PolarizedIonisationBhabhaXS&) = delete;
private:
// - part depending on the polarization of the final positron
G4ThreeVector fPhi2;
// - part depending on the polarization of the final electron
G4ThreeVector fPhi3;
G4double fPhi0;
};
#endif
@@ -25,96 +25,77 @@
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
// Geant4 Class header file
//
//
// File name: G4PolarizedMollerBhabhaModel
// File name: G4PolarizedIonisationModel
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
//
// Creation date: 10.11.2005
//
// Modifications:
//
// 20-08-05, modified interface (A.Schaelicke)
//
//
// Class Description:
//
// Physics implementation of polarized Bhabha/Moller scattering
// Physics implementation of polarized Bhabha/Moller scattering
//
// -------------------------------------------------------------------
//
#ifndef G4PolarizedMollerBhabhaModel_h
#define G4PolarizedMollerBhabhaModel_h 1
#ifndef G4PolarizedIonisationModel_h
#define G4PolarizedIonisationModel_h 1
#include "G4VEmModel.hh"
#include "globals.hh"
#include "G4MollerBhabhaModel.hh"
#include "G4StokesVector.hh"
#include "G4ThreeVector.hh"
class G4VPolarizedCrossSection;
class G4DynamicParticle;
class G4MaterialCutsCouple;
class G4ParticleDefinition;
class G4VPolarizedXS;
class G4PolarizedMollerBhabhaModel : public G4MollerBhabhaModel
class G4PolarizedIonisationModel : public G4MollerBhabhaModel
{
public:
explicit G4PolarizedIonisationModel(
const G4ParticleDefinition* p = nullptr,
const G4String& nam = "PolarizedMollerBhabha");
public:
virtual ~G4PolarizedIonisationModel() override;
explicit G4PolarizedMollerBhabhaModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "PolarizedMollerBhabha");
virtual ~G4PolarizedMollerBhabhaModel();
virtual G4double ComputeCrossSectionPerElectron(
const G4ParticleDefinition*,
G4double kinEnergy,
G4double cut,
G4double emax) override;
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition*,
G4double kinEnergy,
G4double cut,
G4double emax) override;
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) override;
G4PolarizedIonisationModel(G4PolarizedIonisationModel&) = delete;
G4PolarizedIonisationModel& operator=(
const G4PolarizedIonisationModel& right) = delete;
// polarization access routines (may go if using a modified ParticleChange)
void SetTargetPolarization(const G4ThreeVector & pTarget)
void SetTargetPolarization(const G4ThreeVector& pTarget)
{
theTargetPolarization = pTarget;
fTargetPolarization = G4StokesVector(pTarget);
}
void SetBeamPolarization(const G4ThreeVector & pBeam)
void SetBeamPolarization(const G4ThreeVector& pBeam)
{
theBeamPolarization = pBeam;
fBeamPolarization = G4StokesVector(pBeam);
}
const G4StokesVector & GetTargetPolarization()
{
return theTargetPolarization;
}
const G4StokesVector & GetBeamPolarization()
{
return theBeamPolarization;
}
const G4StokesVector & GetFinalElectronPolarization()
const G4StokesVector& GetTargetPolarization() { return fTargetPolarization; }
const G4StokesVector& GetBeamPolarization() { return fBeamPolarization; }
const G4StokesVector& GetFinalElectronPolarization()
{
return fElectronPolarization;
}
const G4StokesVector & GetFinalPositronPolarization()
const G4StokesVector& GetFinalPositronPolarization()
{
return fPositronPolarization;
}
private:
// copy constructor and hide assignment operator
G4PolarizedMollerBhabhaModel(G4PolarizedMollerBhabhaModel &) = delete;
G4PolarizedMollerBhabhaModel &
operator=(const G4PolarizedMollerBhabhaModel &right) = delete;
private:
G4VPolarizedXS* fCrossSectionCalculator;
G4StokesVector theBeamPolarization;
G4StokesVector theTargetPolarization;
G4VPolarizedCrossSection * crossSectionCalculator;
G4StokesVector fBeamPolarization;
G4StokesVector fTargetPolarization;
G4StokesVector fPositronPolarization;
G4StokesVector fElectronPolarization;
@@ -23,54 +23,57 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedMollerCrossSection
// File name: G4PolarizedIonisationMollerXS
//
// Author: Andreas Schaelicke
//
// Creation date: 12.01.2006
//
// Modifications:
// 16-01-06 included cross section as calculated by P.Starovoitov
//
// Class Description:
// * calculates the differential cross section
// incomming electron (along positive z direction) scatters at an electron at rest
// incoming electron (along positive z direction) scatters at an electron at
// rest
// * phi denotes the angle between the scattering plane (defined by the
// outgoing electron) and X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
//
#ifndef G4PolarizedMollerCrossSection_h
#define G4PolarizedMollerCrossSection_h 1
#ifndef G4PolarizedIonisationMollerXS_h
#define G4PolarizedIonisationMollerXS_h 1
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedMollerCrossSection : public G4VPolarizedCrossSection
class G4PolarizedIonisationMollerXS : public G4VPolarizedXS
{
public:
G4PolarizedMollerCrossSection();
virtual ~G4PolarizedMollerCrossSection();
public:
void Initialize(G4double x, G4double y, G4double phi,
const G4StokesVector & p0,const G4StokesVector & p1,
G4int flag=0) override;
public:
G4PolarizedIonisationMollerXS();
~G4PolarizedIonisationMollerXS() override;
void Initialize(G4double x, G4double y, G4double phi,
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) override;
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
G4double XSection(const G4StokesVector & pol2,const G4StokesVector & pol3) override;
G4double TotalXSection(G4double xmin, G4double xmax, G4double y,
const G4StokesVector & pol0,const G4StokesVector & pol1) override;
const G4StokesVector& pol0,
const G4StokesVector& pol1) override;
// return expected mean polarisation
G4StokesVector GetPol2() override;
G4StokesVector GetPol3() override;
private:
G4double phi0;
// - part depending on the polarization of the final electron P1
G4ThreeVector phi2;
// - part depending on the polarization of the final electron P2
G4ThreeVector phi3;
G4PolarizedIonisationMollerXS& operator =(
const G4PolarizedIonisationMollerXS& right) = delete;
G4PolarizedIonisationMollerXS(const G4PolarizedIonisationMollerXS&) = delete;
private:
// - part depending on the polarization of the final photon
G4ThreeVector fPhi2;
// - part depending on the polarization of the final electron
G4ThreeVector fPhi3;
G4double fPhi0;
};
#endif
@@ -1,109 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
//
// File name: G4PolarizedPEEffectModel
//
// Author: Andreas Schaelicke & Karim Laihem
//
// Creation date: 22.02.2007
//
// Modifications:
// 02.08.2007 : adapt to design change in version 4.9 (AS)
//
//
// Class Description:
//
// Implementation of polarization transfer in Photoelectric Effect
//
// -------------------------------------------------------------------
//
#ifdef NOIONIZATIONAS
#define G4PolarizedPEEffectModel_h 1
#endif
#ifndef G4PolarizedPEEffectModel_h
#define G4PolarizedPEEffectModel_h 1
#include "G4PEEffectFluoModel.hh"
#include "G4StokesVector.hh"
class G4PolarizedPEEffectCrossSection;
class G4PolarizedPEEffectModel : public G4PEEffectFluoModel
{
public:
explicit G4PolarizedPEEffectModel(const G4ParticleDefinition* p = nullptr,
const G4String& nam = "Polarized-PhotoElectric");
void Initialise(const G4ParticleDefinition* pd,
const G4DataVector& dv) override;
virtual ~G4PolarizedPEEffectModel();
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double tmin,
G4double maxEnergy) override;
// polarized routines
/*
inline void SetTargetPolarization(const G4ThreeVector & pTarget);
inline void SetBeamPolarization(const G4ThreeVector & pBeam);
inline const G4ThreeVector & GetTargetPolarization() const;
inline const G4ThreeVector & GetBeamPolarization() const;
inline const G4ThreeVector & GetFinalGammaPolarization() const;
inline const G4ThreeVector & GetFinalElectronPolarization() const;
*/
private:
// hide assignment operator
G4PolarizedPEEffectModel &
operator=(const G4PolarizedPEEffectModel &right) = delete;
G4PolarizedPEEffectModel(const G4PolarizedPEEffectModel&) = delete;
G4PolarizedPEEffectCrossSection * crossSectionCalculator;
// incomming
G4StokesVector theBeamPolarization; // photon
// outgoing
G4StokesVector finalElectronPolarization;
G4int verboseLevel;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//------------------ G4PolarizedPhotoElectricEffect physics process
// by Michel Maire
//
// -----------------------------------------------------------------------------
#ifndef G4PolarizedPhotoElectric
# define G4PolarizedPhotoElectric_h 1
# include "globals.hh"
# include "G4VEmProcess.hh"
class G4ParticleDefinition;
class G4PolarizedPhotoElectric : public G4VEmProcess
{
public:
explicit G4PolarizedPhotoElectric(const G4String& processName = "pol-phot",
G4ProcessType type = fElectromagnetic);
virtual ~G4PolarizedPhotoElectric() override;
// true for Gamma only.
G4bool IsApplicable(const G4ParticleDefinition&) override;
virtual void ProcessDescription(std::ostream&) const override;
virtual void DumpInfo() const override { ProcessDescription(G4cout); };
protected:
void InitialiseProcess(const G4ParticleDefinition*) override;
private:
G4bool fIsInitialised;
};
#endif
@@ -1,102 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
//------------------ G4PolarizedPhotoElectricEffect physics process ------------------
// by Michel Maire, 24 May 1996
//
// 12-06-96, Added SelectRandomAtom() method and new data member
// for cumulative total cross section, by M.Maire
// 21-06-96, SetCuts implementation, M.Maire
// 17-09-96, Dynamic array PartialSumSigma
// split ComputeBindingEnergy(), M.Maire
// 08-01-97, crossection table + meanfreepath table, M.Maire
// 13-03-97, adapted for the new physics scheme, M.Maire
// 13-08-98, new methods SetBining() PrintInfo()
// 17-11-98, use table of atomic shells in PostStepDoIt, mma
// 06-01-99, Sandia crossSection below 50 keV, V.Grichine mma
// 03-08-01, new methods Store/Retrieve PhysicsTable (mma)
// 06-08-01, BuildThePhysicsTable() called from constructor (mma)
// 19-09-01, come back to previous process name "phot"
// 20-09-01, DoIt: fminimalEnergy = 1*eV (mma)
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
// 10-01-02, moved few function from icc to cc
// 17-04-02, Keep only Sandia crossSections. Remove BuildPhysicsTables.
// Simplify public interface (mma)
// 29-04-02, Generate theta angle of the photoelectron from Sauter-Gavrila
// distribution (mma)
// 13-08-04, suppress icc file; make public ComputeCrossSectionPerAtom() (mma)
// 21-04-05, Redesign - use G4VEmProcess interface (V.Ivanchenko)
// 02-05-05, move ParticleChange actions in model (mma)
// 04-05-05, Make class to be default (V.Ivanchenko)
// 09-08-06, add SetModel(G4VEmModel*) (mma)
// 12-09-06, move SetModel(G4VEmModel*) in G4VEmProcess (mma)
// -----------------------------------------------------------------------------
// class description
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4PolarizedPhotoElectricEffect_h
#define G4PolarizedPhotoElectricEffect_h 1
#include "globals.hh"
#include "G4VEmProcess.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4ParticleDefinition;
class G4PolarizedPhotoElectricEffect : public G4VEmProcess
{
public: // with description
explicit G4PolarizedPhotoElectricEffect(const G4String& processName ="pol-phot",
G4ProcessType type = fElectromagnetic);
virtual ~G4PolarizedPhotoElectricEffect();
// true for Gamma only.
G4bool IsApplicable(const G4ParticleDefinition&) override;
// Print few lines of informations about the process: validity range,
void PrintInfo() override;
protected:
void InitialiseProcess(const G4ParticleDefinition*) override;
private:
G4bool isInitialised;
};
#endif
@@ -0,0 +1,74 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class header file
//
// File name: G4PolarizedPhotoElectricModel
//
// Author: Andreas Schaelicke & Karim Laihem
//
// Class Description:
// Implementation of polarization transfer in Photoelectric Effect
//
// -------------------------------------------------------------------
#ifndef G4PolarizedPhotoElectricModel_h
#define G4PolarizedPhotoElectricModel_h 1
#include "G4PEEffectFluoModel.hh"
#include "G4StokesVector.hh"
class G4PolarizedPhotoElectricXS;
class G4PolarizedPhotoElectricModel : public G4PEEffectFluoModel
{
public:
explicit G4PolarizedPhotoElectricModel(
const G4ParticleDefinition* p = nullptr,
const G4String& nam = "Polarized-PhotoElectric");
virtual ~G4PolarizedPhotoElectricModel() override;
void Initialise(const G4ParticleDefinition* pd,
const G4DataVector& dv) override;
virtual void SampleSecondaries(std::vector<G4DynamicParticle*>*,
const G4MaterialCutsCouple*,
const G4DynamicParticle*, G4double tmin,
G4double maxEnergy) override;
G4PolarizedPhotoElectricModel& operator=(
const G4PolarizedPhotoElectricModel& right) = delete;
G4PolarizedPhotoElectricModel(const G4PolarizedPhotoElectricModel&) = delete;
private:
G4PolarizedPhotoElectricXS* fCrossSectionCalculator;
G4int fVerboseLevel;
};
#endif
@@ -23,50 +23,42 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// GEANT4 Class file
//
//
// File name: G4PolarizedPEEffectCrossSection
// File name: G4PolarizedPhotoElectricXS
//
// Author: Andreas Schaelicke
//
// Creation date: 15.03.2007
//
// Modifications:
//
//
// Class Description:
//
#ifndef G4PolarizedPEEffectCrossSection_h
#define G4PolarizedPEEffectCrossSection_h 1
#ifndef G4PolarizedPhotoElectricXS_h
#define G4PolarizedPhotoElectricXS_h 1
#include "G4StokesVector.hh"
#include "G4VPolarizedCrossSection.hh"
//#include "RotationMatrix.hh"
#include "G4VPolarizedXS.hh"
class G4PolarizedPEEffectCrossSection : public G4VPolarizedCrossSection
class G4PolarizedPhotoElectricXS : public G4VPolarizedXS
{
public:
G4PolarizedPEEffectCrossSection();
virtual ~G4PolarizedPEEffectCrossSection();
public:
virtual void Initialize(G4double aGammaE, G4double aLept0E, G4double sintheta,
const G4StokesVector & beamPol,
const G4StokesVector & ,
G4int flag=0) override;
public:
G4PolarizedPhotoElectricXS();
~G4PolarizedPhotoElectricXS() override;
G4double XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3) override;
void Initialize(G4double aGammaE, G4double aLept0E, G4double sintheta,
const G4StokesVector& beamPol, const G4StokesVector&,
G4int flag = 0) override;
G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) override;
public:
// return expected mean polarisation
G4StokesVector GetPol2() override;
G4StokesVector GetPol3() override;
private:
G4StokesVector theFinalElectronPolarization;
G4PolarizedPhotoElectricXS& operator=(
const G4PolarizedPhotoElectricXS& right) = delete;
G4PolarizedPhotoElectricXS(const G4PolarizedPhotoElectricXS&) = delete;
private:
G4StokesVector fFinalElectronPolarization;
};
#endif
@@ -23,29 +23,18 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class header file
// Geant4 Class header file
//
// File name: G4StokesVector
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
// 27-07-06 added some test routines (P.Starovoitov)
// 25-08-06 modified name of test routines (A.Schaelicke)
//
// Class Description:
//
// Provides Stokesvector representation employed in implementation of
// polarized processes.
//
// aim:
// Provides Stokesvector representation employed in implementation of
// polarized processes.
// - store three components of a stokesvector
// - distinguish between boson or fermion state (different transformations)
// - provide unique definition of reference frame (cf. G4PolarizationHelper)
//
#ifndef G4StokesVector_h
#define G4StokesVector_h 1
@@ -53,48 +42,40 @@
#include "G4ThreeVector.hh"
#include "G4RotationMatrix.hh"
class G4StokesVector: public G4ThreeVector
class G4StokesVector : public G4ThreeVector
{
public:
// standard vectors:
static const G4StokesVector ZERO;
static const G4StokesVector P1;
static const G4StokesVector P2;
static const G4StokesVector P3;
static const G4StokesVector M1;
static const G4StokesVector M2;
static const G4StokesVector M3;
public:
G4StokesVector();
G4StokesVector(const G4ThreeVector & v);
explicit G4StokesVector(const G4ThreeVector& v);
~G4StokesVector() = default;
G4bool IsZero() const;
G4bool IsZero() const;
inline G4double p1() const { return x(); }
inline G4double p2() const { return y(); }
inline G4double p3() const { return z(); }
inline G4double Transverse() const { return perp(); }
inline G4double Transverse() const { return perp(); }
inline G4ThreeVector PolSqr() const {
return G4ThreeVector(x()*x(),y()*y(),z()*z());
inline G4ThreeVector PolSqr() const
{
return G4ThreeVector(x() * x(), y() * y(), z() * z());
}
inline G4ThreeVector PolSqrt() const {
return G4ThreeVector(std::sqrt(x()),std::sqrt(y()),std::sqrt(z()));
inline G4ThreeVector PolSqrt() const
{
return G4ThreeVector(std::sqrt(x()), std::sqrt(y()), std::sqrt(z()));
}
G4ThreeVector PolError(const G4StokesVector & sum2, long n);
G4ThreeVector PolError(const G4StokesVector& sum2, long n);
// Ratio of 3-vectors.
G4ThreeVector PolDiv( const G4StokesVector & );
G4ThreeVector PolDiv(const G4StokesVector&);
inline void SetPhoton() { isPhoton=true; }
inline void SetPhoton() { fIsPhoton = true; }
void RotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection);
void InvRotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection);
void RotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection);
void InvRotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection);
void RotateAz(G4double cosphi, G4double sinphi);
G4double GetBeta();
@@ -104,9 +85,18 @@ public:
void DiceP3();
void FlipP3();
private:
G4bool isPhoton;
// standard vectors:
static const G4StokesVector ZERO;
static const G4StokesVector P1;
static const G4StokesVector P2;
static const G4StokesVector P3;
static const G4StokesVector M1;
static const G4StokesVector M2;
static const G4StokesVector M3;
private:
G4bool fIsPhoton;
};
#endif
@@ -23,74 +23,72 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// File name: G4VPolarizedCrossSection
// File name: G4VPolarizedXS
//
// Author: Andreas Schaelicke
//
// Creation date: 15.05.2005
//
// Modifications:
//
// Class Description:
// (pure virtual) interface class
// (virtual) interface class
//
// provides readable but efficient routines to determine
// provides readable but efficient routines to determine
// polarization for the final state of a given process
// empoying the differential cross section
//
#ifndef G4VPolarizedCrossSection_h
#define G4VPolarizedCrossSection_h 1
#ifndef G4VPolarizedXS_h
#define G4VPolarizedXS_h 1
#include "G4StokesVector.hh"
class G4VPolarizedCrossSection
class G4VPolarizedXS
{
public:
G4VPolarizedCrossSection();
virtual ~G4VPolarizedCrossSection();
public:
G4VPolarizedXS();
virtual ~G4VPolarizedXS();
public:
virtual void Initialize(G4double, G4double, G4double,
const G4StokesVector & p0,const G4StokesVector & p1,
G4int flag=0);
virtual G4double XSection(const G4StokesVector & pol2,const G4StokesVector & pol3) = 0;
const G4StokesVector& p0, const G4StokesVector& p1,
G4int flag = 0) = 0;
virtual G4double XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3) = 0;
virtual G4double TotalXSection(G4double xmin, G4double xmax, G4double y,
const G4StokesVector & pol0,
const G4StokesVector & pol1);
const G4StokesVector& pol0,
const G4StokesVector& pol1);
// return expected mean polarisation
virtual G4StokesVector GetPol2();
virtual G4StokesVector GetPol3();
// return basic kinematics properties
// minimal gamma value in TotalXSection
inline G4double GetYmin() {return fYmin; }
inline G4double GetYmin() { return fYmin; }
// minimal energy fraction in TotalXSection
virtual G4double GetXmin(G4double y);
// maximal energy fraction in TotalXSection
// maximal energy fraction in TotalXSection
virtual G4double GetXmax(G4double y);
// return appropriate distribute polarisation states;
// void DicePolarization();
// G4StokesVector DicedPol2();
// G4StokesVector DicedPol3();
inline void SetMaterial(G4double A, G4double Z, G4double coul)
{ theA=A; theZ=Z; fCoul=coul; }
protected:
inline void SetMaterial(G4double A, G4double Z, G4double coul)
{
fA = A;
fZ = Z;
fCoul = coul;
}
G4VPolarizedXS& operator=(const G4VPolarizedXS& right) = delete;
G4VPolarizedXS(const G4VPolarizedXS&) = delete;
protected:
// define kinematics properties
inline void SetXmin(G4double xmin) { fXmin=xmin;}
inline void SetXmax(G4double xmax) { fXmax=xmax;}
inline void SetYmin(G4double ymin) { fYmin=ymin;}
inline void SetXmin(G4double xmin) { fXmin = xmin; }
inline void SetXmax(G4double xmax) { fXmax = xmax; }
inline void SetYmin(G4double ymin) { fYmin = ymin; }
// kinematic properties
G4double fXmin, fXmax, fYmin;
// material properties
G4double theA, theZ;
G4double fA, fZ;
G4double fCoul;
};
#endif
@@ -1,100 +1,69 @@
#------------------------------------------------------------------------------
# sources.cmake
# Module : G4empolar
# Package: Geant4.src.G4processes.G4electromagnetic.G4empolar
#
# 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
#
#
#------------------------------------------------------------------------------
# - G4empolar module build definition
#
# Define the Geant4 Module.
#
GEANT4_DEFINE_MODULE(NAME G4empolar
HEADERS
G4PolarizationHelper.hh
G4PolarizationManager.hh
G4PolarizationMessenger.hh
G4PolarizedAnnihilationCrossSection.hh
G4PolarizedAnnihilationModel.hh
G4PolarizedBhabhaCrossSection.hh
G4PolarizedBremsstrahlungCrossSection.hh
G4PolarizedCompton.hh
G4PolarizedComptonCrossSection.hh
G4PolarizedComptonModel.hh
G4PolarizedGammaConversion.hh
G4PolarizedGammaConversionModel.hh
G4PolarizedMollerBhabhaModel.hh
G4PolarizedMollerCrossSection.hh
G4PolarizedPEEffectCrossSection.hh
G4PolarizedPEEffectModel.hh
G4PolarizedPairProductionCrossSection.hh
G4PolarizedPhotoElectricEffect.hh
G4StokesVector.hh
G4VPolarizedCrossSection.hh
G4ePolarizedBremsstrahlung.hh
G4ePolarizedBremsstrahlungModel.hh
G4ePolarizedIonisation.hh
G4eplusPolarizedAnnihilation.hh
SOURCES
G4PolarizationHelper.cc
G4PolarizationManager.cc
G4PolarizationMessenger.cc
G4PolarizedAnnihilationCrossSection.cc
G4PolarizedAnnihilationModel.cc
G4PolarizedBhabhaCrossSection.cc
G4PolarizedBremsstrahlungCrossSection.cc
G4PolarizedCompton.cc
G4PolarizedComptonCrossSection.cc
G4PolarizedComptonModel.cc
G4PolarizedGammaConversion.cc
G4PolarizedGammaConversionModel.cc
G4PolarizedMollerBhabhaModel.cc
G4PolarizedMollerCrossSection.cc
G4PolarizedPEEffectCrossSection.cc
G4PolarizedPEEffectModel.cc
G4PolarizedPairProductionCrossSection.cc
G4PolarizedPhotoElectricEffect.cc
G4StokesVector.cc
G4VPolarizedCrossSection.cc
G4ePolarizedBremsstrahlung.cc
G4ePolarizedBremsstrahlungModel.cc
G4ePolarizedIonisation.cc
G4eplusPolarizedAnnihilation.cc
GRANULAR_DEPENDENCIES
G4baryons
G4bosons
G4cuts
G4emstandard
G4emutils
G4geometrymng
G4globman
G4hepnumerics
G4intercoms
G4ions
G4leptons
G4materials
G4mesons
G4partman
G4procman
G4track
G4volumes
GLOBAL_DEPENDENCIES
G4geometry
G4global
G4intercoms
G4materials
G4particles
G4track
LINK_LIBRARIES
)
# List any source specific properties here
geant4_add_module(G4empolar
PUBLIC_HEADERS
G4PolarizationHelper.hh
G4PolarizationManager.hh
G4PolarizationMessenger.hh
G4PolarizedAnnihilation.hh
G4PolarizedAnnihilationXS.hh
G4PolarizedAnnihilationModel.hh
G4PolarizedBremsstrahlung.hh
G4PolarizedBremsstrahlungModel.hh
G4PolarizedBremsstrahlungXS.hh
G4PolarizedCompton.hh
G4PolarizedComptonXS.hh
G4PolarizedComptonModel.hh
G4PolarizedGammaConversion.hh
G4PolarizedGammaConversionModel.hh
G4PolarizedGammaConversionXS.hh
G4PolarizedIonisation.hh
G4PolarizedIonisationBhabhaXS.hh
G4PolarizedIonisationModel.hh
G4PolarizedIonisationMollerXS.hh
G4PolarizedPhotoElectricXS.hh
G4PolarizedPhotoElectricModel.hh
G4PolarizedPhotoElectric.hh
G4StokesVector.hh
G4VPolarizedXS.hh
SOURCES
G4PolarizationHelper.cc
G4PolarizationManager.cc
G4PolarizationMessenger.cc
G4PolarizedAnnihilation.cc
G4PolarizedAnnihilationXS.cc
G4PolarizedAnnihilationModel.cc
G4PolarizedBremsstrahlung.cc
G4PolarizedBremsstrahlungModel.cc
G4PolarizedBremsstrahlungXS.cc
G4PolarizedCompton.cc
G4PolarizedComptonXS.cc
G4PolarizedComptonModel.cc
G4PolarizedGammaConversion.cc
G4PolarizedGammaConversionModel.cc
G4PolarizedGammaConversionXS.cc
G4PolarizedIonisation.cc
G4PolarizedIonisationBhabhaXS.cc
G4PolarizedIonisationModel.cc
G4PolarizedIonisationMollerXS.cc
G4PolarizedPhotoElectricXS.cc
G4PolarizedPhotoElectricModel.cc
G4PolarizedPhotoElectric.cc
G4StokesVector.cc
G4VPolarizedXS.cc)
geant4_module_link_libraries(G4empolar
PUBLIC
G4bosons
G4emstandard
G4emutils
G4globman
G4intercoms
PRIVATE
G4cuts
G4geometrymng
G4heprandom
G4leptons
G4partman
G4track)
@@ -23,144 +23,142 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4PolarizationHelper
//
// Author: Andreas Schaelicke
//
// Creation date: 12.08.2006
//
// Modifications:
//
// Class Description:
//
// Provides some basic polarization transformation routines.
//
// Provides some basic polarization transformation routines.
#include "G4PolarizationHelper.hh"
#include "G4PhysicalConstants.hh"
#include "G4StokesVector.hh"
#include "Randomize.hh"
G4ThreeVector G4PolarizationHelper::GetFrame(const G4ThreeVector & mom1, const G4ThreeVector & mom2)
G4ThreeVector G4PolarizationHelper::GetFrame(const G4ThreeVector& mom1,
const G4ThreeVector& mom2)
{
G4ThreeVector normal = (mom1.cross(mom2)).unit();
return normal;
// return 1./normal.mag()*normal;
}
G4ThreeVector G4PolarizationHelper::GetParticleFrameY(const G4ThreeVector &uZ)
G4ThreeVector G4PolarizationHelper::GetParticleFrameY(const G4ThreeVector& uZ)
{
// compare also G4ThreeVector::rotateUz()
if (uZ.x()==0. && uZ.y()==0.) {
return G4ThreeVector(0.,1.,0.);
if(uZ.x() == 0. && uZ.y() == 0.)
{
return G4ThreeVector(0., 1., 0.);
}
G4double invPerp = 1./std::sqrt(sqr(uZ.x())+sqr(uZ.y()));
return G4ThreeVector(-uZ.y()*invPerp,uZ.x()*invPerp,0);
G4double invPerp = 1. / std::sqrt(sqr(uZ.x()) + sqr(uZ.y()));
return G4ThreeVector(-uZ.y() * invPerp, uZ.x() * invPerp, 0);
}
G4ThreeVector G4PolarizationHelper::GetParticleFrameX(const G4ThreeVector &uZ)
G4ThreeVector G4PolarizationHelper::GetParticleFrameX(const G4ThreeVector& uZ)
{
// compare also G4ThreeVector::rotateUz()
if (uZ.x()==0. && uZ.y()==0.) {
if (uZ.z()>=0.) return G4ThreeVector(1.,0.,0.);
return G4ThreeVector(-1.,0.,0.);
if(uZ.x() == 0. && uZ.y() == 0.)
{
if(uZ.z() >= 0.)
return G4ThreeVector(1., 0., 0.);
return G4ThreeVector(-1., 0., 0.);
}
G4double perp = std::sqrt(sqr(uZ.x())+sqr(uZ.y()));
G4double invPerp = uZ.z()/perp;
return G4ThreeVector(uZ.x()*invPerp,uZ.y()*invPerp,-perp);
G4double perp = std::sqrt(sqr(uZ.x()) + sqr(uZ.y()));
G4double invPerp = uZ.z() / perp;
return G4ThreeVector(uZ.x() * invPerp, uZ.y() * invPerp, -perp);
}
G4ThreeVector G4PolarizationHelper::GetRandomFrame(const G4ThreeVector & mom1)
G4ThreeVector G4PolarizationHelper::GetRandomFrame(const G4ThreeVector& mom1)
{
G4double phi =2.*pi*G4UniformRand();
G4ThreeVector normal = std::cos(phi)*GetParticleFrameX(mom1)
+ std::sin(phi)*G4PolarizationHelper::GetParticleFrameY(mom1);
G4double phi = 2. * pi * G4UniformRand();
G4ThreeVector normal =
std::cos(phi) * GetParticleFrameX(mom1) +
std::sin(phi) * G4PolarizationHelper::GetParticleFrameY(mom1);
return normal;
}
G4ThreeVector G4PolarizationHelper::GetSpinInPRF(const G4ThreeVector &uZ, const G4ThreeVector & spin)
G4ThreeVector G4PolarizationHelper::GetSpinInPRF(const G4ThreeVector& uZ,
const G4ThreeVector& spin)
{
// compare also G4ThreeVector::rotateUz()
if (uZ.x()==0. && uZ.y()==0.) {
if (uZ.z()>=0.) return spin;
return G4ThreeVector(-spin.x(),spin.y(),-spin.z());
if(uZ.x() == 0. && uZ.y() == 0.)
{
if(uZ.z() >= 0.)
return spin;
return G4ThreeVector(-spin.x(), spin.y(), -spin.z());
}
G4double perp = std::sqrt(sqr(uZ.x())+sqr(uZ.y()));
G4double invPerp = 1./perp;
G4double perp = std::sqrt(sqr(uZ.x()) + sqr(uZ.y()));
G4double invPerp = 1. / perp;
G4ThreeVector uX(uZ.x()*uZ.z()*invPerp,uZ.y()*uZ.z()*invPerp,-perp);
G4ThreeVector uY(-uZ.y()*invPerp,uZ.x()*invPerp,0);
return G4ThreeVector(spin*uX,spin*uY,spin*uZ);
G4ThreeVector uX(uZ.x() * uZ.z() * invPerp, uZ.y() * uZ.z() * invPerp, -perp);
G4ThreeVector uY(-uZ.y() * invPerp, uZ.x() * invPerp, 0);
return G4ThreeVector(spin * uX, spin * uY, spin * uZ);
}
void G4PolarizationHelper::TestPolarizationTransformations()
{
G4double theta=0.;
G4cout<<"========================================\n\n";
for (G4int i=0; i<=10; ++i) {
theta=pi*i/10.;
G4ThreeVector zAxis = G4ThreeVector(std::sin(theta),0.,std::cos(theta));
if (i==5) zAxis = G4ThreeVector(1.,0.,0.);
if (i==10) zAxis = G4ThreeVector(0.,0.,-1.);
G4double theta = 0.;
G4cout << "========================================\n\n";
for(G4int i = 0; i <= 10; ++i)
{
theta = pi * i / 10.;
G4ThreeVector zAxis = G4ThreeVector(std::sin(theta), 0., std::cos(theta));
if(i == 5)
zAxis = G4ThreeVector(1., 0., 0.);
if(i == 10)
zAxis = G4ThreeVector(0., 0., -1.);
G4ThreeVector yAxis = GetParticleFrameY(zAxis);
G4cout<<zAxis<<" "<<zAxis.mag()<<"\n";
G4cout<<yAxis<<" "<<yAxis.mag()<<"\n";
G4cout << zAxis << " " << zAxis.mag() << "\n";
G4cout << yAxis << " " << yAxis.mag() << "\n";
G4ThreeVector xAxis = yAxis.cross(zAxis);
G4cout<<xAxis<<" "<<xAxis.mag()<<"\n\n";
G4cout << xAxis << " " << xAxis.mag() << "\n\n";
}
G4cout<<"========================================\n\n";
G4cout << "========================================\n\n";
for (G4int i=0; i<=10; ++i) {
theta=pi*i/10.;
G4ThreeVector zAxis = G4ThreeVector(0.,std::sin(theta),std::cos(theta));
if (i==5) zAxis = G4ThreeVector(0.,1.,0.);
if (i==10) zAxis = G4ThreeVector(0.,0.,-1.);
for(G4int i = 0; i <= 10; ++i)
{
theta = pi * i / 10.;
G4ThreeVector zAxis = G4ThreeVector(0., std::sin(theta), std::cos(theta));
if(i == 5)
zAxis = G4ThreeVector(0., 1., 0.);
if(i == 10)
zAxis = G4ThreeVector(0., 0., -1.);
G4ThreeVector yAxis = GetParticleFrameY(zAxis);
G4cout<<zAxis<<" "<<zAxis.mag()<<"\n";
G4cout<<yAxis<<" "<<yAxis.mag()<<"\n";
G4cout << zAxis << " " << zAxis.mag() << "\n";
G4cout << yAxis << " " << yAxis.mag() << "\n";
G4ThreeVector xAxis = yAxis.cross(zAxis);
G4cout<<xAxis<<" "<<xAxis.mag()<<"\n\n";
G4cout << xAxis << " " << xAxis.mag() << "\n\n";
G4cout<<"spat : "<<xAxis*yAxis.cross(zAxis)<<"\n\n";
G4cout << "spat : " << xAxis * yAxis.cross(zAxis) << "\n\n";
}
G4cout<<"========================================\n\n";
G4cout << "========================================\n\n";
}
void G4PolarizationHelper::TestInteractionFrame()
{
// check transformation procedure for polarisation transfer
// check transformation procedure for polarisation transfer
// calculation in scattering processes
// a) transfer target polarisation in beam particle reference frame (PRF)
// b) calc correct asymmetry w.r.t. scattering plane
// c) determine incomming polarisation in interaction frame (IF)
// c) determine incoming polarisation in interaction frame (IF)
// d) transfer outgoing polarisation from IF to PRF
G4cout<<"========================================\n\n";
G4cout << "========================================\n\n";
G4double theta=0.;
G4double theta = 0.;
G4ThreeVector dir0=G4ThreeVector(0.,0.,1.);
G4ThreeVector dir2=G4ThreeVector(std::sin(theta),0.,std::cos(theta));
G4ThreeVector dir0 = G4ThreeVector(0., 0., 1.);
G4ThreeVector dir2 = G4ThreeVector(std::sin(theta), 0., std::cos(theta));
G4StokesVector pol0=G4ThreeVector(0.,0.,1.);
G4StokesVector pol1=G4ThreeVector(0.,0.,1.);
G4StokesVector pol0 = G4StokesVector::P3;
G4StokesVector pol1 = G4StokesVector::P3;
pol1.rotateUz(dir0);
G4cout<<"========================================\n\n";
G4cout << "========================================\n\n";
}
@@ -23,88 +23,89 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4PolarizationManager
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
//
// Class Description:
//
// Provides polarization information for logical volumes, and some basic
// transformation routines.
//
// Provides polarization information for logical volumes, and some basic
// transformation routines.
#include "G4PolarizationManager.hh"
#include "G4LogicalVolume.hh"
#include "G4PolarizationMessenger.hh"
#include "G4StokesVector.hh"
#include "G4LogicalVolume.hh"
G4ThreadLocal G4PolarizationManager * G4PolarizationManager::instance = nullptr;
G4ThreadLocal G4PolarizationManager* G4PolarizationManager::fInstance = nullptr;
G4PolarizationManager* G4PolarizationManager::GetInstance()
{
if (instance == nullptr) instance = new G4PolarizationManager();
return instance;
if(fInstance == nullptr)
fInstance = new G4PolarizationManager();
return fInstance;
}
void G4PolarizationManager::Dispose()
{
if (instance != nullptr)
if(fInstance != nullptr)
{
delete instance;
instance = nullptr;
delete fInstance;
fInstance = nullptr;
}
}
G4PolarizationManager::G4PolarizationManager()
: messenger(nullptr), verboseLevel(0), activated(true)
: fMessenger(nullptr)
, fVerboseLevel(0)
, fActivated(true)
{
messenger = new G4PolarizationMessenger(this);
fMessenger = new G4PolarizationMessenger(this);
}
G4PolarizationManager::~G4PolarizationManager()
{
}
G4PolarizationManager::~G4PolarizationManager() {}
void G4PolarizationManager::ListVolumes()
{
if (volumePolarizations.size()==0) return;
G4cout<<" Polarization for "<<volumePolarizations.size()
<<" registered volume(s) : "<<G4endl;
if (!activated)
G4cout<<" but polarization deactivated "<<G4endl;
for (auto vp : volumePolarizations) {
if(fVolumePolarizations.empty())
return;
G4cout << " Polarization for " << fVolumePolarizations.size()
<< " registered volume(s) : " << G4endl;
if(!fActivated)
G4cout << " but polarization deactivated " << G4endl;
for(auto vp : fVolumePolarizations)
{
G4cout << vp.first->GetName() << " : " << vp.second << G4endl;
}
}
void G4PolarizationManager::SetVolumePolarization(G4LogicalVolume* lVol, const G4ThreeVector & pol)
void G4PolarizationManager::SetVolumePolarization(G4LogicalVolume* lVol,
const G4ThreeVector& pol)
{
volumePolarizations[lVol]=pol;
if (verboseLevel>=1) G4cout<<" SetVolumePolarization "
<<lVol->GetName()<<" "
<<pol<<G4endl;
fVolumePolarizations[lVol] = pol;
if(fVerboseLevel >= 1)
G4cout << " SetVolumePolarization " << lVol->GetName() << " " << pol
<< G4endl;
}
void G4PolarizationManager::SetVolumePolarization(const G4String & lVolName, const G4ThreeVector & pol)
void G4PolarizationManager::SetVolumePolarization(const G4String& lVolName,
const G4ThreeVector& pol)
{
for (auto& vp : volumePolarizations) {
if (vp.first->GetName()==lVolName) {
vp.second=pol;
if (verboseLevel>=1) G4cout<<" SetVolumePolarization "
<<lVolName<<" "
<<pol<<G4endl;
for(auto& vp : fVolumePolarizations)
{
if(vp.first->GetName() == lVolName)
{
vp.second = pol;
if(fVerboseLevel >= 1)
G4cout << " SetVolumePolarization " << lVolName << " " << pol << G4endl;
return;
}
}
G4cout<<" logical volume '"<<lVolName<<"'not registered yet \n"
<<" please register before using '/polarization/volume/set' "<<G4endl;
G4ExceptionDescription ed;
ed << " Logical volume '" << lVolName << "'not registered yet.\n"
<< " Please register before using '/polarization/volume/set'\n";
G4Exception("G4PolarizationManager::SetVolumePolarization", "pol040",
FatalException, ed);
}
@@ -23,37 +23,29 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// GEANT4 Class file
// Geant4 Class file
//
// File name: G4PolarizationManager
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
//
// Class Description:
//
// Provides access to general polarization information and to
// polarization for logical volumes through macro files.
// Provides access to general polarization information and to
// polarization for logical volumes through macro files.
#include "G4PolarizationMessenger.hh"
#include "G4ios.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4UIdirectory.hh"
#include "G4Tokenizer.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithABool.hh"
#include "G4ios.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIdirectory.hh"
G4PolarizationMessenger::G4PolarizationMessenger(G4PolarizationManager * polMgr)
G4PolarizationMessenger::G4PolarizationMessenger(G4PolarizationManager* polMgr)
: polarizationManager(polMgr)
{
polarizationDirectory = new G4UIdirectory("/polarization/");
@@ -62,56 +54,67 @@ G4PolarizationMessenger::G4PolarizationMessenger(G4PolarizationManager * polMgr)
managerDirectory = new G4UIdirectory("/polarization/manager/");
managerDirectory->SetGuidance("general polarization information.");
verboseCmd = new G4UIcmdWithAnInteger("/polarization/manager/verbose",this);
verboseCmd = new G4UIcmdWithAnInteger("/polarization/manager/verbose", this);
verboseCmd->SetGuidance("Set the Verbose level of G4PolarizationManager.");
verboseCmd->SetGuidance(" 0 : Silent (default)");
verboseCmd->SetGuidance(" 1 : Verbose");
verboseCmd->SetParameterName("level",true);
verboseCmd->SetParameterName("level", true);
verboseCmd->SetDefaultValue(0);
verboseCmd->SetRange("level >=0 && level <=1");
optActivateCmd = new G4UIcmdWithABool("/polarization/manager/activate",this);
optActivateCmd = new G4UIcmdWithABool("/polarization/manager/activate", this);
optActivateCmd->SetGuidance("activate/deactivate polarization treatment");
optActivateCmd->SetParameterName("flag",true);
optActivateCmd->SetParameterName("flag", true);
optActivateCmd->SetDefaultValue(true);
volumeDirectory = new G4UIdirectory("/polarization/volume/");
volumeDirectory->SetGuidance("Status control commands of registered polarized logical volumes.");
volumeDirectory->SetGuidance(
"Status control commands of registered polarized logical volumes.");
printVolumeListCmd = new G4UIcmdWithoutParameter("/polarization/volume/list",this);
printVolumeListCmd->SetGuidance("print list of registered polarized logical volumes");
printVolumeListCmd->AvailableForStates(G4State_PreInit,G4State_Idle,G4State_GeomClosed);
setPolarizationCmd = new G4UIcommand("/polarization/volume/set",this);
setPolarizationCmd->SetGuidance("set or change polarization of a logical volume");
// setPolarizationCmd->SetParameterName("polarization",true);
// setPolarizationCmd->SetDefaultValue("worldVolume 0. 0. 0.");
setPolarizationCmd->AvailableForStates(G4State_PreInit,G4State_Idle,G4State_GeomClosed);
printVolumeListCmd =
new G4UIcmdWithoutParameter("/polarization/volume/list", this);
printVolumeListCmd->SetGuidance(
"print list of registered polarized logical volumes");
printVolumeListCmd->AvailableForStates(G4State_PreInit, G4State_Idle,
G4State_GeomClosed);
setPolarizationCmd = new G4UIcommand("/polarization/volume/set", this);
setPolarizationCmd->SetGuidance(
"set or change polarization of a logical volume");
setPolarizationCmd->AvailableForStates(G4State_PreInit, G4State_Idle,
G4State_GeomClosed);
G4UIparameter* param;
param = new G4UIparameter("logicalVolumeName",'s',false);
param = new G4UIparameter("logicalVolumeName", 's', false);
param->SetDefaultValue("worldVolume");
setPolarizationCmd->SetParameter(param);
param = new G4UIparameter("px",'d',true);
param = new G4UIparameter("px", 'd', true);
param->SetDefaultValue("0.0");
setPolarizationCmd->SetParameter(param);
param = new G4UIparameter("py",'d',true);
param = new G4UIparameter("py", 'd', true);
param->SetDefaultValue("0.0");
setPolarizationCmd->SetParameter(param);
param = new G4UIparameter("pz",'d',true);
param = new G4UIparameter("pz", 'd', true);
param->SetDefaultValue("0.0");
setPolarizationCmd->SetParameter(param);
testDirectory = new G4UIdirectory("/polarization/test/");
testDirectory->SetGuidance("provides access to some internal test routines.");
testPolarizationTransformationCmd = new G4UIcmdWithoutParameter("/polarization/test/polarizationTransformation",this);
testPolarizationTransformationCmd->SetGuidance("checks definition of particle reference frame and corresponding translation routines");
testPolarizationTransformationCmd->AvailableForStates(G4State_PreInit,G4State_Idle,G4State_GeomClosed);
testPolarizationTransformationCmd = new G4UIcmdWithoutParameter(
"/polarization/test/polarizationTransformation", this);
testPolarizationTransformationCmd->SetGuidance(
"checks definition of particle reference frame and corresponding "
"translation routines");
testPolarizationTransformationCmd->AvailableForStates(
G4State_PreInit, G4State_Idle, G4State_GeomClosed);
testInteractionFrameCmd = new G4UIcmdWithoutParameter("/polarization/test/interactionFrame",this);
testInteractionFrameCmd->SetGuidance("checks definition of interaction frame");
testInteractionFrameCmd->AvailableForStates(G4State_PreInit,G4State_Idle,G4State_GeomClosed);
testInteractionFrameCmd =
new G4UIcmdWithoutParameter("/polarization/test/interactionFrame", this);
testInteractionFrameCmd->SetGuidance(
"checks definition of interaction frame");
testInteractionFrameCmd->AvailableForStates(G4State_PreInit, G4State_Idle,
G4State_GeomClosed);
}
G4PolarizationMessenger::~G4PolarizationMessenger()
@@ -128,47 +131,60 @@ G4PolarizationMessenger::~G4PolarizationMessenger()
delete polarizationDirectory;
}
void G4PolarizationMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
void G4PolarizationMessenger::SetNewValue(G4UIcommand* command,
G4String newValue)
{
if( command==verboseCmd ) {
polarizationManager->SetVerbose(verboseCmd->GetNewIntValue(newValue));
if(command == verboseCmd)
{
polarizationManager->SetVerbose(verboseCmd->GetNewIntValue(newValue));
}
else if ( command==optActivateCmd ) {
polarizationManager->SetActivated(optActivateCmd->GetNewBoolValue(newValue));
else if(command == optActivateCmd)
{
polarizationManager->SetActivated(
optActivateCmd->GetNewBoolValue(newValue));
}
else if ( command==printVolumeListCmd ) {
else if(command == printVolumeListCmd)
{
polarizationManager->ListVolumes();
}
else if ( command==setPolarizationCmd ) {
G4Tokenizer next( newValue );
G4String volumeName=next();
G4double px=0.,py=0.,pz=0.;
G4String dvalue=next();
if (!dvalue.isNull()) {
px=StoD(dvalue);
dvalue=next();
if (!dvalue.isNull()) {
py=StoD(dvalue);
dvalue=next();
if (!dvalue.isNull()) pz=StoD(dvalue);
else if(command == setPolarizationCmd)
{
G4Tokenizer next(newValue);
G4String volumeName = next();
G4double px = 0., py = 0., pz = 0.;
G4String dvalue = next();
if(!dvalue.isNull())
{
px = StoD(dvalue);
dvalue = next();
if(!dvalue.isNull())
{
py = StoD(dvalue);
dvalue = next();
if(!dvalue.isNull())
pz = StoD(dvalue);
}
}
G4ThreeVector pol(px,py,pz);
polarizationManager->SetVolumePolarization(volumeName,pol);
G4ThreeVector pol(px, py, pz);
polarizationManager->SetVolumePolarization(volumeName, pol);
}
else if ( command==testPolarizationTransformationCmd ) {
else if(command == testPolarizationTransformationCmd)
{
G4PolarizationHelper::TestPolarizationTransformations();
}
else if (command==testInteractionFrameCmd ) {
else if(command == testInteractionFrameCmd)
{
G4PolarizationHelper::TestInteractionFrame();
}
}
G4String G4PolarizationMessenger::GetCurrentValue(G4UIcommand * command)
G4String G4PolarizationMessenger::GetCurrentValue(G4UIcommand* command)
{
G4String cv;
if( command==verboseCmd )
{ cv = verboseCmd->ConvertToString(polarizationManager->GetVerbose()); }
if(command == verboseCmd)
{
cv = verboseCmd->ConvertToString(polarizationManager->GetVerbose());
}
return cv;
}
@@ -0,0 +1,323 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedAnnihilation
//
// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
//
// Class Description:
// Polarized process of e+ annihilation into 2 gammas
#include "G4PolarizedAnnihilation.hh"
#include "G4DynamicParticle.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4PhysicsVector.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizedAnnihilationModel.hh"
#include "G4ProductionCutsTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4StokesVector.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedAnnihilation::G4PolarizedAnnihilation(const G4String& name)
: G4eplusAnnihilation(name)
, fAsymmetryTable(nullptr)
, fTransverseAsymmetryTable(nullptr)
{
fEmModel = new G4PolarizedAnnihilationModel();
SetEmModel(fEmModel);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedAnnihilation::~G4PolarizedAnnihilation() { CleanTables(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilation::CleanTables()
{
if(fAsymmetryTable)
{
fAsymmetryTable->clearAndDestroy();
delete fAsymmetryTable;
fAsymmetryTable = nullptr;
}
if(fTransverseAsymmetryTable)
{
fTransverseAsymmetryTable->clearAndDestroy();
delete fTransverseAsymmetryTable;
fTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedAnnihilation::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
G4double mfp =
G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
if(nullptr != fAsymmetryTable && nullptr != fTransverseAsymmetryTable && mfp < DBL_MAX)
{
mfp *= ComputeSaturationFactor(track);
}
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedAnnihilation::MeanFreePath: " << mfp / mm << " mm "
<< G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedAnnihilation::PostStepGetPhysicalInteractionLength(
const G4Track& track, G4double previousStepSize, G4ForceCondition* condition)
{
// save previous values
G4double nLength = theNumberOfInteractionLengthLeft;
G4double iLength = currentInteractionLength;
// *** compute unpolarized step limit ***
// this changes theNumberOfInteractionLengthLeft and currentInteractionLength
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(
track, previousStepSize, condition);
G4double x0 = x;
G4double satFact = 1.0;
// *** add corrections on polarisation ***
if(nullptr != fAsymmetryTable && nullptr != fTransverseAsymmetryTable && x < DBL_MAX)
{
satFact = ComputeSaturationFactor(track);
G4double curLength = currentInteractionLength * satFact;
G4double prvLength = iLength * satFact;
if(nLength > 0.0)
{
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize / prvLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedAnnihilation::PostStepGPIL: " << std::setprecision(8)
<< x / mm << " mm;" << G4endl
<< " unpolarized value: "
<< std::setprecision(8) << x0 / mm << " mm." << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedAnnihilation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
G4StokesVector electronPolarization =
polarizationManager->GetVolumePolarization(aLVolume);
G4double factor = 1.0;
if(volumeIsPolarized)
{
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
const G4StokesVector positronPolarization =
G4StokesVector(track.GetPolarization());
const G4ParticleMomentum positronDirection0 =
aDynamicPositron->GetMomentumDirection();
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedAnnihilation::ComputeSaturationFactor: " << G4endl;
G4cout << " Mom " << positronDirection0 << G4endl;
G4cout << " Polarization " << positronPolarization << G4endl;
G4cout << " MaterialPol. " << electronPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < fAsymmetryTable->size())
{
aVector = (*fAsymmetryTable)(midx);
}
if(midx < fTransverseAsymmetryTable->size())
{
bVector = (*fTransverseAsymmetryTable)(midx);
}
if(aVector && bVector)
{
G4double lAsymmetry = aVector->Value(positronEnergy);
G4double tAsymmetry = bVector->Value(positronEnergy);
G4double polZZ =
positronPolarization.z() * (electronPolarization * positronDirection0);
G4double polXX =
positronPolarization.x() *
(electronPolarization *
G4PolarizationHelper::GetParticleFrameX(positronDirection0));
G4double polYY =
positronPolarization.y() *
(electronPolarization *
G4PolarizationHelper::GetParticleFrameY(positronDirection0));
factor /= (1. + polZZ * lAsymmetry + (polXX + polYY) * tAsymmetry);
if(verboseLevel >= 2)
{
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry
<< G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ
<< G4endl;
G4cout << " Factor: " << factor << G4endl;
}
}
else
{
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4PolarizedAnnihilation::ComputeSaturationFactor", "em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilation::BuildPhysicsTable(
const G4ParticleDefinition& part)
{
G4VEmProcess::BuildPhysicsTable(part);
if(isTheMaster)
{
BuildAsymmetryTables(part);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTables();
fAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(fAsymmetryTable);
fTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(fTransverseAsymmetryTable);
if(nullptr == fAsymmetryTable) return;
// Access to materials
const G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
for(size_t i = 0; i < numOfCouples; ++i)
{
if(fAsymmetryTable->GetFlag(i))
{
// create physics vector and fill it
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
// use same parameters as for lambda
G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
G4PhysicsVector* tVector = LambdaPhysicsVector(couple);
G4int nn = aVector->GetVectorLength();
for(G4int j = 0; j < nn; ++j)
{
G4double energy = aVector->Energy(j);
G4double tasm = 0.;
G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
aVector->PutValue(j, asym);
tVector->PutValue(j, tasm);
}
if(aVector->GetSpline()) {
aVector->FillSecondDerivatives();
tVector->FillSecondDerivatives();
}
G4PhysicsTableHelper::SetPhysicsVector(fAsymmetryTable, i, aVector);
G4PhysicsTableHelper::SetPhysicsVector(fTransverseAsymmetryTable, i,
tVector);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedAnnihilation::ComputeAsymmetry(
G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
// calculate polarized cross section
G4ThreeVector targetPolarization = G4ThreeVector(0., 0., 1.);
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma2 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// calculate transversely polarized cross section
targetPolarization = G4ThreeVector(1., 0., 0.);
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma3 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// calculate unpolarized cross section
targetPolarization = G4ThreeVector();
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma0 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// determine asymmetries
if(sigma0 > 0.)
{
lAsymmetry = sigma2 / sigma0 - 1.;
tAsymmetry = sigma3 / sigma0 - 1.;
}
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilation::ProcessDescription(std::ostream& out) const
{
out << "Polarized model for positron annihilation into 2 photons.\n";
}
@@ -1,331 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedAnnihilationCrossSection
//
// Author: Andreas Schaelicke
//
// Creation date: 22.03.2006
//
// Modifications:
// 24-03-06 included cross section as given in W.McMaster, Nuovo Cimento 7, 1960, 395
// 27-07-06 new calculation by P.Starovoitov
// 15.10.07 introduced a more general framework for cross sections (AS)
// 16.10.07 some minor corrections in formula longPart
//
// Class Description:
// * calculates the differential cross section in e+e- -> gamma gamma
//
#include "G4PolarizedAnnihilationCrossSection.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedAnnihilationCrossSection::G4PolarizedAnnihilationCrossSection() :
polxx(0.), polyy(0.), polzz(0.), polxz(0.), polzx(0.), polxy(0.),
polyx(0.), polyz(0.), polzy(0.),
re2(1.), diffXSFactor(1.), totalXSFactor(1.),
phi0(0.)
{
re2 = classic_electr_radius * classic_electr_radius;
phi2 = G4ThreeVector(0., 0., 0.);
phi3 = G4ThreeVector(0., 0., 0.);
dice = 0.;
polXS= 0.;
unpXS = 0.;
ISPxx=ISPyy=ISPzz=ISPnd=0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedAnnihilationCrossSection::~G4PolarizedAnnihilationCrossSection()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationCrossSection::TotalXS()
{
// total cross section is sum of
// + unpol xsec "sigma0"
// + longitudinal polarised cross section "sigma_zz" times pol_3(e-)*pol_3(e+)
// + transverse contribution "(sigma_xx+sigma_yy)/2" times pol_T(e-)*pol_T(e+)
// (Note: if both beams are transversely polarised, i.e. pol_T(e-)!=0 and
// pol_T(e+)!=0, and sigma_xx!=sigma_yy, then the diff. cross section will
// exhibit a azimuthal asymmetry even if pol_T(e-)*pol_T(e+)==0)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationCrossSection::Initialize(
G4double eps,
G4double gam,
G4double , // phi
const G4StokesVector & pol0, // positron polarization
const G4StokesVector & pol1, // electron polarization
G4int flag)
{
diffXSFactor=re2/(gam - 1.);
DefineCoefficients(pol0,pol1);
//
// prepare dicing
//
dice = 0.;
G4double symmXS = 0.125*((-1./sqr(gam + 1.))/sqr(eps) +
((sqr(gam) + 4.*gam - 1.)/sqr(gam + 1.))/eps - 1.);
//
//
//
G4ThreeVector epsVector(1./sqr(eps), 1./eps, 1.);
G4ThreeVector oneEpsVector(1./sqr(1. - eps), 1./(1.-eps), 1.);
G4ThreeVector sumEpsVector(epsVector + oneEpsVector);
G4ThreeVector difEpsVector(epsVector - oneEpsVector);
G4ThreeVector calcVector(0., 0., 0.);
//
// temporary variables
//
G4double helpVar2 = 0., helpVar1 = 0.;
//
// unpolarised contribution
//
helpVar1 = (gam*gam + 4.*gam + 1.)/sqr(gam + 1.);
helpVar2 = -1./sqr(gam + 1.);
calcVector = G4ThreeVector(helpVar2, helpVar1, -1.);
unpXS = 0.125 * calcVector * sumEpsVector;
// initial particles polarised contribution
helpVar2 = 1./sqr(gam + 1.);
helpVar1 = -(gam*gam + 4.*gam + 1.)/sqr(gam + 1.);
calcVector = G4ThreeVector(helpVar2, helpVar1, 0.5*(gam + 3.));
ISPxx = 0.25*(calcVector * sumEpsVector)/(gam - 1.);
helpVar1 = 1./sqr(gam + 1.);
calcVector = G4ThreeVector(-helpVar1, 2.*gam*helpVar1, -1.);
ISPyy = 0.125 * calcVector * sumEpsVector;
helpVar1 = 1./(gam - 1.);
helpVar2 = 1./sqr(gam + 1.);
calcVector = G4ThreeVector(-(gam*gam + 1.)*helpVar2,(gam*gam*(gam + 1.) + 7.*gam + 3.)*helpVar2, -(gam + 3.));
ISPzz = 0.125*helpVar1*(calcVector * sumEpsVector);
helpVar1 = std::sqrt(std::fabs(eps*(1. - eps)*2.*(gam + 1.) - 1.));
calcVector = G4ThreeVector(-1./(gam*gam - 1.), 2./(gam - 1.), 0.);
ISPnd = 0.125*(calcVector * difEpsVector) * helpVar1;
polXS = 0.;
polXS += ISPxx*polxx;
polXS += ISPyy*polyy;
polXS += ISPzz*polzz;
polXS += ISPnd*(polzx + polxz);
phi0 = unpXS + polXS;
dice = symmXS;
// if(polzz != 0.) dice *= (1. + std::fabs(polzz*ISPzz/unpXS));
if(polzz != 0.) {
dice *= (1. + (polzz*ISPzz/unpXS));
if (dice<0.) dice=0.;
}
// prepare final state coefficients
if (flag==2) {
//
// circular polarisation
//
G4double circ1 = 0., circ2 = 0., circ3 = 0.;
helpVar1 = 8.*sqr(1. - eps)*sqr(eps)*(gam - 1.)*sqr(gam + 1.)/std::sqrt(gam*gam - 1.);
helpVar2 = sqr(gam + 1.)*sqr(eps)*(-2.*eps + 3.) - (gam*gam + 3.*gam + 2.)*eps;
circ1 = helpVar2 + gam;
circ1 /= helpVar1;
circ2 = helpVar2 + 1.;
circ2 /= helpVar1;
helpVar1 = std::sqrt(std::fabs(eps*(1. - eps)*2.*(gam + 1.) - 1.));
helpVar1 /= std::sqrt(gam*gam - 1.);
calcVector = G4ThreeVector(1., -2.*gam, 0.);
circ3 = 0.125*(calcVector * sumEpsVector)/(gam + 1.);
circ3 *= helpVar1;
phi2.setZ( circ2*pol1.z() + circ1*pol0.z() + circ3*(pol1.x() + pol0.x()));
phi3.setZ(-circ1*pol1.z() - circ2*pol0.z() - circ3*(pol1.x() + pol0.x()));
//
// common to both linear polarisation
//
calcVector = G4ThreeVector(-1., 2.*gam, 0.);
G4double linearZero = 0.125*(calcVector * sumEpsVector)/sqr(gam + 1.);
//
// Linear Polarisation #1
//
helpVar1 = std::sqrt(std::fabs(2.*(gam + 1.)*(1. - eps)*eps - 1.))/((gam + 1.)*eps*(1. - eps));
helpVar2 = helpVar1*helpVar1;
//
// photon 1
//
G4double diagContrib = 0.125*helpVar2*(polxx + polyy - polzz);
G4double nonDiagContrib = 0.125*helpVar1*(-polxz/(1. - eps) + polzx/eps);
phi2.setX(linearZero + diagContrib + nonDiagContrib);
//
// photon 2
//
nonDiagContrib = 0.125*helpVar1*(polxz/eps - polzx/(1. - eps));
phi3.setX(linearZero + diagContrib + nonDiagContrib);
//
// Linear Polarisation #2
//
helpVar1 = std::sqrt(gam*gam - 1.)*(2.*(gam + 1.)*eps*(1. - eps) - 1.);
helpVar1 /= 8.*sqr(1. - eps)*sqr(eps)*sqr(gam + 1.)*(gam - 1.);
helpVar2 = std::sqrt((gam*gam - 1.)*std::fabs(2.*(gam + 1.)*eps*(1. - eps) - 1.));
helpVar2 /= 8.*sqr(1. - eps)*sqr(eps)*sqr(gam + 1.)*(gam - 1.);
G4double contrib21 = (-polxy + polyx)*helpVar1;
G4double contrib32 = -(eps*(gam + 1.) - 1.)*polyz + (eps*(gam + 1.) - gam)*polzy;
contrib32 *=helpVar2;
phi2.setY(contrib21 + contrib32);
contrib32 = -(eps*(gam + 1.) - gam)*polyz + (eps*(gam + 1.) - 1.)*polzy;
contrib32 *=helpVar2;
phi3.setY(contrib21 + contrib32);
}
phi0 *= diffXSFactor;
phi2 *= diffXSFactor;
phi3 *= diffXSFactor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationCrossSection::XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3)
{
G4double xs=phi0+pol2*phi2+pol3*phi3;
return xs;
}
//
// calculate total cross section
//
G4double G4PolarizedAnnihilationCrossSection::TotalXSection(
G4double ,G4double ,G4double gam,
const G4StokesVector & pol0,const G4StokesVector & pol1)
{
totalXSFactor =pi*re2/(gam + 1.); // atomic number ignored
DefineCoefficients(pol0,pol1);
G4double xs = 0.;
G4double gam2 = gam*gam;
G4double sqrtgam1 = std::sqrt(gam2 - 1.);
G4double logMEM = std::log(gam+sqrtgam1);
G4double unpME = (gam*(gam + 4.) + 1.)*logMEM;
unpME += -(gam + 3.)*sqrtgam1;
unpME /= 4.*(gam2 - 1.);
// G4double longPart = - 2.*(gam*(gam + 4.) + 1.)*logMEM;
// longPart += (gam*(gam + 4.) + 7.)*sqrtgam1;
// longPart /= 4.*sqr(gam - 1.)*(gam + 1.);
G4double longPart = (3+gam*(gam*(gam + 1.) + 7.))*logMEM;
longPart += - (5.+ gam*(3*gam + 4.))*sqrtgam1;
longPart /= 4.*sqr(gam - 1.)*(gam + 1.);
G4double tranPart = -(5*gam + 1.)*logMEM;
tranPart += (gam + 5.)*sqrtgam1;
tranPart /= 4.*sqr(gam - 1.)*(gam + 1.);
xs += unpME;
xs += polzz*longPart;
xs += (polxx + polyy)*tranPart;
return xs*totalXSFactor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedAnnihilationCrossSection::GetPol2()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedAnnihilationCrossSection::GetPol3()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi3;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationCrossSection::DefineCoefficients(const G4StokesVector & pol0,
const G4StokesVector & pol1)
{
polxx=pol0.x()*pol1.x();
polyy=pol0.y()*pol1.y();
polzz=pol0.z()*pol1.z();
polxz=pol0.x()*pol1.z();
polzx=pol0.z()*pol1.x();
polyz=pol0.y()*pol1.z();
polzy=pol0.z()*pol1.y();
polxy=pol0.x()*pol1.y();
polyx=pol0.y()*pol1.x();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationCrossSection::GetXmin(G4double y)
{
return 0.5*(1.-std::sqrt((y-1.)/(y+1.)));
}
G4double G4PolarizedAnnihilationCrossSection::GetXmax(G4double y)
{
return 0.5*(1.+std::sqrt((y-1.)/(y+1.)));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationCrossSection::DiceEpsilon()
{
return dice;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationCrossSection::getVar(G4int choice)
{
if (choice == -1) return polXS/unpXS;
if (choice == 0) return unpXS;
if (choice == 1) return ISPxx;
if (choice == 2) return ISPyy;
if (choice == 3) return ISPzz;
if (choice == 4) return ISPnd;
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,369 +23,412 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4PolarizedAnnihilationModel
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
// 18-07-06 use newly calculated cross sections (P. Starovoitov)
// 21-08-06 update interface (A. Schaelicke)
// 17-11-06 add protection agaist e+ zero energy PostStep (V.Ivanchenko)
// 10-07-07 copied Initialise() method from G4eeToTwoGammaModel to provide a
// local ParticleChangeForGamma object and reduce overhead
// in SampleSecondaries() (A. Schaelicke)
//
//
// Class Description:
//
// Implementation of polarized gamma Annihilation scattering on free electron
//
// Implementation of polarized gamma Annihilation scattering on free electron
// -------------------------------------------------------------------
#include "G4PolarizedAnnihilationModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4StokesVector.hh"
#include "G4PolarizedAnnihilationCrossSection.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4TrackStatus.hh"
#include "G4Gamma.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4PhysicalConstants.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizedAnnihilationXS.hh"
#include "G4StokesVector.hh"
#include "G4TrackStatus.hh"
G4PolarizedAnnihilationModel::G4PolarizedAnnihilationModel(const G4ParticleDefinition* p,
const G4String& nam)
: G4eeToTwoGammaModel(p,nam),
crossSectionCalculator(nullptr),
verboseLevel(0),
gParticleChange(nullptr)
G4PolarizedAnnihilationModel::G4PolarizedAnnihilationModel(
const G4ParticleDefinition* p, const G4String& nam)
: G4eeToTwoGammaModel(p, nam)
, fCrossSectionCalculator(nullptr)
, fParticleChange(nullptr)
, fVerboseLevel(0)
{
crossSectionCalculator = new G4PolarizedAnnihilationCrossSection();
fCrossSectionCalculator = new G4PolarizedAnnihilationXS();
fBeamPolarization = G4StokesVector::ZERO;
fTargetPolarization = G4StokesVector::ZERO;
fFinalGamma1Polarization = G4StokesVector::ZERO;
fFinalGamma2Polarization = G4StokesVector::ZERO;
}
G4PolarizedAnnihilationModel::~G4PolarizedAnnihilationModel()
{
delete crossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedAnnihilationModel::~G4PolarizedAnnihilationModel()
{
delete fCrossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilationModel::Initialise(const G4ParticleDefinition* part,
const G4DataVector& dv)
{
G4eeToTwoGammaModel::Initialise(part, dv);
if(gParticleChange) { return; }
gParticleChange = GetParticleChangeForGamma();
if(fParticleChange)
{
return;
}
fParticleChange = GetParticleChangeForGamma();
}
G4double
G4PolarizedAnnihilationModel::ComputeCrossSectionPerElectron(G4double kinEnergy)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedAnnihilationModel::ComputeCrossSectionPerElectron(
G4double kinEnergy)
{
// cross section from base model
G4double xs = G4eeToTwoGammaModel::ComputeCrossSectionPerElectron(kinEnergy);
G4double polzz = theBeamPolarization.z()*theTargetPolarization.z();
G4double poltt = theBeamPolarization.x()*theTargetPolarization.x()
+ theBeamPolarization.y()*theTargetPolarization.y();
if (polzz!=0 || poltt!=0) {
G4double xval,lasym,tasym;
ComputeAsymmetriesPerElectron(kinEnergy,xval,lasym,tasym);
xs*=(1.+polzz*lasym+poltt*tasym);
G4double polzz = fBeamPolarization.z() * fTargetPolarization.z();
G4double poltt = fBeamPolarization.x() * fTargetPolarization.x() +
fBeamPolarization.y() * fTargetPolarization.y();
if(polzz != 0 || poltt != 0)
{
G4double xval, lasym, tasym;
ComputeAsymmetriesPerElectron(kinEnergy, xval, lasym, tasym);
xs *= (1. + polzz * lasym + poltt * tasym);
}
return xs;
}
void G4PolarizedAnnihilationModel::ComputeAsymmetriesPerElectron(G4double ene,
G4double & valueX,
G4double & valueA,
G4double & valueT)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedAnnihilationModel::ComputeAsymmetriesPerElectron(
G4double ene, G4double& valueX, G4double& valueA, G4double& valueT)
{
// *** calculate asymmetries
G4double gam = 1. + ene/electron_mass_c2;
G4double xs0=crossSectionCalculator->TotalXSection(0.,1.,gam,
G4StokesVector::ZERO,
G4StokesVector::ZERO);
G4double xsA=crossSectionCalculator->TotalXSection(0.,1.,gam,
G4StokesVector::P3,
G4StokesVector::P3);
G4double xsT1=crossSectionCalculator->TotalXSection(0.,1.,gam,
G4StokesVector::P1,
G4StokesVector::P1);
G4double xsT2=crossSectionCalculator->TotalXSection(0.,1.,gam,
G4StokesVector::P2,
G4StokesVector::P2);
G4double xsT=0.5*(xsT1+xsT2);
valueX=xs0;
valueA=xsA/xs0-1.;
valueT=xsT/xs0-1.;
// G4cout<<valueX<<"\t"<<valueA<<"\t"<<valueT<<" energy = "<<gam<<G4endl;
if ( (valueA < -1) || (1 < valueA)) {
G4cout<< " ERROR PolarizedAnnihilationPS::ComputeAsymmetries \n";
G4cout<< " something wrong in total cross section calculation (valueA)\n";
G4cout<< " LONG: "<<valueX<<"\t"<<valueA<<"\t"<<valueT<<" energy = "<<gam<<G4endl;
G4double gam = 1. + ene / electron_mass_c2;
G4double xs0 = fCrossSectionCalculator->TotalXSection(
0., 1., gam, G4StokesVector::ZERO, G4StokesVector::ZERO);
G4double xsA = fCrossSectionCalculator->TotalXSection(
0., 1., gam, G4StokesVector::P3, G4StokesVector::P3);
G4double xsT1 = fCrossSectionCalculator->TotalXSection(
0., 1., gam, G4StokesVector::P1, G4StokesVector::P1);
G4double xsT2 = fCrossSectionCalculator->TotalXSection(
0., 1., gam, G4StokesVector::P2, G4StokesVector::P2);
G4double xsT = 0.5 * (xsT1 + xsT2);
valueX = xs0;
valueA = xsA / xs0 - 1.;
valueT = xsT / xs0 - 1.;
if((valueA < -1) || (1 < valueA))
{
G4ExceptionDescription ed;
ed << " ERROR PolarizedAnnihilationPS::ComputeAsymmetries \n";
ed << " something wrong in total cross section calculation (valueA)\n";
ed << " LONG: " << valueX << "\t" << valueA << "\t" << valueT
<< " energy = " << gam << G4endl;
G4Exception("G4PolarizedAnnihilationModel::ComputeAsymmetriesPerElectron",
"pol004", JustWarning, ed);
}
if ( (valueT < -1) || (1 < valueT)) {
G4cout<< " ERROR PolarizedAnnihilationPS::ComputeAsymmetries \n";
G4cout<< " something wrong in total cross section calculation (valueT)\n";
G4cout<< " TRAN: "<<valueX<<"\t"<<valueA<<"\t"<<valueT<<" energy = "<<gam<<G4endl;
if((valueT < -1) || (1 < valueT))
{
G4ExceptionDescription ed;
ed << " ERROR PolarizedAnnihilationPS::ComputeAsymmetries \n";
ed << " something wrong in total cross section calculation (valueT)\n";
ed << " TRAN: " << valueX << "\t" << valueA << "\t" << valueT
<< " energy = " << gam << G4endl;
G4Exception("G4PolarizedAnnihilationModel::ComputeAsymmetriesPerElectron",
"pol005", JustWarning, ed);
}
}
void G4PolarizedAnnihilationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
const G4MaterialCutsCouple*,
const G4DynamicParticle* dp,
G4double, G4double)
void G4PolarizedAnnihilationModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* fvect, const G4MaterialCutsCouple*,
const G4DynamicParticle* dp, G4double, G4double)
{
const G4Track * aTrack = gParticleChange->GetCurrentTrack();
const G4Track* aTrack = fParticleChange->GetCurrentTrack();
// kill primary
gParticleChange->SetProposedKineticEnergy(0.);
gParticleChange->ProposeTrackStatus(fStopAndKill);
// kill primary
fParticleChange->SetProposedKineticEnergy(0.);
fParticleChange->ProposeTrackStatus(fStopAndKill);
// V.Ivanchenko add protection against zero kin energy
G4double PositKinEnergy = dp->GetKineticEnergy();
if(PositKinEnergy == 0.0) {
G4double cosTeta = 2.*G4UniformRand()-1.;
G4double sinTeta = std::sqrt((1.0 - cosTeta)*(1.0 + cosTeta));
if(PositKinEnergy == 0.0)
{
G4double cosTeta = 2. * G4UniformRand() - 1.;
G4double sinTeta = std::sqrt((1.0 - cosTeta) * (1.0 + cosTeta));
G4double phi = twopi * G4UniformRand();
G4ThreeVector dir(sinTeta*std::cos(phi), sinTeta*std::sin(phi), cosTeta);
fvect->push_back( new G4DynamicParticle(G4Gamma::Gamma(), dir, electron_mass_c2));
fvect->push_back( new G4DynamicParticle(G4Gamma::Gamma(),-dir, electron_mass_c2));
G4ThreeVector dir(sinTeta * std::cos(phi), sinTeta * std::sin(phi),
cosTeta);
fvect->push_back(
new G4DynamicParticle(G4Gamma::Gamma(), dir, electron_mass_c2));
fvect->push_back(
new G4DynamicParticle(G4Gamma::Gamma(), -dir, electron_mass_c2));
return;
}
// *** obtain and save target and beam polarization ***
G4PolarizationManager * polarizationManager = G4PolarizationManager::GetInstance();
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
// obtain polarization of the beam
theBeamPolarization = aTrack->GetPolarization();
fBeamPolarization = G4StokesVector(aTrack->GetPolarization());
// obtain polarization of the media
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
const G4bool targetIsPolarized = polarizationManager->IsPolarized(aLVolume);
theTargetPolarization = polarizationManager->GetVolumePolarization(aLVolume);
fTargetPolarization = polarizationManager->GetVolumePolarization(aLVolume);
if (verboseLevel >= 1) {
if(fVerboseLevel >= 1)
{
G4cout << "G4PolarizedComptonModel::SampleSecondaries in "
<< aLVolume->GetName() << G4endl;
<< aLVolume->GetName() << G4endl;
}
// transfer target electron polarization in frame of positron
if (targetIsPolarized)
theTargetPolarization.rotateUz(dp->GetMomentumDirection());
if(targetIsPolarized)
fTargetPolarization.rotateUz(dp->GetMomentumDirection());
G4ParticleMomentum PositDirection = dp->GetMomentumDirection();
// polar asymmetry:
G4double polarization = theBeamPolarization.p3()*theTargetPolarization.p3();
G4double polarization = fBeamPolarization.p3() * fTargetPolarization.p3();
G4double gamam1 = PositKinEnergy/electron_mass_c2;
G4double gama = gamam1+1. , gamap1 = gamam1+2.;
G4double sqgrate = std::sqrt(gamam1/gamap1)/2. , sqg2m1 = std::sqrt(gamam1*gamap1);
G4double gamam1 = PositKinEnergy / electron_mass_c2;
G4double gama = gamam1 + 1., gamap1 = gamam1 + 2.;
G4double sqgrate = std::sqrt(gamam1 / gamap1) / 2.,
sqg2m1 = std::sqrt(gamam1 * gamap1);
// limits of the energy sampling
G4double epsilmin = 0.5 - sqgrate , epsilmax = 0.5 + sqgrate;
G4double epsilqot = epsilmax/epsilmin;
//
// sample the energy rate of the created gammas
// note: for polarized partices, the actual dicing strategy
G4double epsilmin = 0.5 - sqgrate, epsilmax = 0.5 + sqgrate;
G4double epsilqot = epsilmax / epsilmin;
// sample the energy rate of the created gammas
// note: for polarized partices, the actual dicing strategy
// will depend on the energy, and the degree of polarization !!
//
G4double epsil;
G4double gmax=1. + std::fabs(polarization); // crude estimate
G4double gmax = 1. + std::fabs(polarization); // crude estimate
//G4bool check_range=true;
crossSectionCalculator->Initialize(epsilmin, gama, 0., theBeamPolarization, theTargetPolarization);
if (crossSectionCalculator->DiceEpsilon()<0) {
G4cout<<"ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<<"epsilmin DiceRoutine not appropriate ! "<<crossSectionCalculator->DiceEpsilon()<<G4endl;
//check_range=false;
fCrossSectionCalculator->Initialize(epsilmin, gama, 0., fBeamPolarization,
fTargetPolarization);
if(fCrossSectionCalculator->DiceEpsilon() < 0.)
{
G4ExceptionDescription ed;
ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<< "epsilmin DiceRoutine not appropriate ! "
<< fCrossSectionCalculator->DiceEpsilon() << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol006",
JustWarning, ed);
}
crossSectionCalculator->Initialize(epsilmax, gama, 0., theBeamPolarization, theTargetPolarization);
if (crossSectionCalculator->DiceEpsilon()<0) {
G4cout<<"ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<<"epsilmax DiceRoutine not appropriate ! "<<crossSectionCalculator->DiceEpsilon()<<G4endl;
//check_range=false;
fCrossSectionCalculator->Initialize(epsilmax, gama, 0., fBeamPolarization,
fTargetPolarization);
if(fCrossSectionCalculator->DiceEpsilon() < 0)
{
G4ExceptionDescription ed;
ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<< "epsilmax DiceRoutine not appropriate ! "
<< fCrossSectionCalculator->DiceEpsilon() << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol007",
JustWarning, ed);
}
G4int ncount=0;
G4double trejectmax=0.;
G4int ncount = 0;
G4double trejectmax = 0.;
G4double treject;
do
{
epsil = epsilmin * std::pow(epsilqot, G4UniformRand());
do {
//
epsil = epsilmin*std::pow(epsilqot,G4UniformRand());
fCrossSectionCalculator->Initialize(epsil, gama, 0., fBeamPolarization,
fTargetPolarization, 1);
crossSectionCalculator->Initialize(epsil, gama, 0., theBeamPolarization, theTargetPolarization,1);
treject = fCrossSectionCalculator->DiceEpsilon();
treject *= epsil;
treject = crossSectionCalculator->DiceEpsilon();
treject*=epsil;
if (treject>gmax || treject<0.)
G4cout<<"ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<<" eps ("<<epsil<<") rejection does not work properly: "<<treject<<G4endl;
if(treject > gmax || treject < 0.)
{
G4ExceptionDescription ed;
ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<< " eps (" << epsil
<< ") rejection does not work properly: " << treject << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol008",
JustWarning, ed);
}
++ncount;
if (treject>trejectmax) trejectmax=treject;
if (ncount>1000) {
G4cout<<"WARNING in PolarizedAnnihilationPS::PostStepDoIt\n"
<<"eps dicing very inefficient ="<<trejectmax/gmax
<<", "<<treject/gmax<<". For secondary energy = "<<epsil<<" "<<ncount<<G4endl;
if(treject > trejectmax)
trejectmax = treject;
if(ncount > 1000)
{
G4ExceptionDescription ed;
ed << "WARNING in PolarizedAnnihilationPS::PostStepDoIt\n"
<< "eps dicing very inefficient =" << trejectmax / gmax << ", "
<< treject / gmax << ". For secondary energy = " << epsil << " "
<< ncount << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol009",
JustWarning, ed);
break;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while( treject < gmax*G4UniformRand() );
} while(treject < gmax * G4UniformRand());
//
// scattered Gamma angles. ( Z - axis along the parent positron)
//
G4double cost = (epsil*gamap1-1.)/(epsil*sqg2m1);
G4double sint = std::sqrt((1.+cost)*(1.-cost));
G4double cost = (epsil * gamap1 - 1.) / (epsil * sqg2m1);
G4double sint = std::sqrt((1. + cost) * (1. - cost));
G4double phi = 0.;
G4double beamTrans = std::sqrt(sqr(theBeamPolarization.p1()) + sqr(theBeamPolarization.p2()));
G4double targetTrans = std::sqrt(sqr(theTargetPolarization.p1()) + sqr(theTargetPolarization.p2()));
G4double beamTrans =
std::sqrt(sqr(fBeamPolarization.p1()) + sqr(fBeamPolarization.p2()));
G4double targetTrans =
std::sqrt(sqr(fTargetPolarization.p1()) + sqr(fTargetPolarization.p2()));
// G4cout<<"phi dicing START"<<G4endl;
do{
phi = twopi * G4UniformRand();
crossSectionCalculator->Initialize(epsil, gama, 0., theBeamPolarization, theTargetPolarization,2);
do
{
phi = twopi * G4UniformRand();
fCrossSectionCalculator->Initialize(epsil, gama, 0., fBeamPolarization,
fTargetPolarization, 2);
G4double gdiced =crossSectionCalculator->getVar(0);
gdiced += crossSectionCalculator->getVar(3)*theBeamPolarization.p3()*theTargetPolarization.p3();
gdiced += 1.*(std::fabs(crossSectionCalculator->getVar(1))
+ std::fabs(crossSectionCalculator->getVar(2)))*beamTrans*targetTrans;
gdiced += 1.*std::fabs(crossSectionCalculator->getVar(4))
*(std::fabs(theBeamPolarization.p3())*targetTrans + std::fabs(theTargetPolarization.p3())*beamTrans);
G4double gdiced = fCrossSectionCalculator->getVar(0);
gdiced += fCrossSectionCalculator->getVar(3) * fBeamPolarization.p3() *
fTargetPolarization.p3();
gdiced += 1. *
(std::fabs(fCrossSectionCalculator->getVar(1)) +
std::fabs(fCrossSectionCalculator->getVar(2))) *
beamTrans * targetTrans;
gdiced += 1. * std::fabs(fCrossSectionCalculator->getVar(4)) *
(std::fabs(fBeamPolarization.p3()) * targetTrans +
std::fabs(fTargetPolarization.p3()) * beamTrans);
G4double gdist = crossSectionCalculator->getVar(0);
gdist += crossSectionCalculator->getVar(3)*theBeamPolarization.p3()*theTargetPolarization.p3();
gdist += crossSectionCalculator->getVar(1)*(std::cos(phi)*theBeamPolarization.p1()
+ std::sin(phi)*theBeamPolarization.p2())
*(std::cos(phi)*theTargetPolarization.p1()
+ std::sin(phi)*theTargetPolarization.p2());
gdist += crossSectionCalculator->getVar(2)*(std::cos(phi)*theBeamPolarization.p2()
- std::sin(phi)*theBeamPolarization.p1())
*(std::cos(phi)*theTargetPolarization.p2()
- std::sin(phi)*theTargetPolarization.p1());
gdist += crossSectionCalculator->getVar(4)
*(std::cos(phi)*theBeamPolarization.p3()*theTargetPolarization.p1()
+ std::cos(phi)*theBeamPolarization.p1()*theTargetPolarization.p3()
+ std::sin(phi)*theBeamPolarization.p3()*theTargetPolarization.p2()
+ std::sin(phi)*theBeamPolarization.p2()*theTargetPolarization.p3());
G4double gdist = fCrossSectionCalculator->getVar(0);
gdist += fCrossSectionCalculator->getVar(3) * fBeamPolarization.p3() *
fTargetPolarization.p3();
gdist += fCrossSectionCalculator->getVar(1) *
(std::cos(phi) * fBeamPolarization.p1() +
std::sin(phi) * fBeamPolarization.p2()) *
(std::cos(phi) * fTargetPolarization.p1() +
std::sin(phi) * fTargetPolarization.p2());
gdist += fCrossSectionCalculator->getVar(2) *
(std::cos(phi) * fBeamPolarization.p2() -
std::sin(phi) * fBeamPolarization.p1()) *
(std::cos(phi) * fTargetPolarization.p2() -
std::sin(phi) * fTargetPolarization.p1());
gdist +=
fCrossSectionCalculator->getVar(4) *
(std::cos(phi) * fBeamPolarization.p3() * fTargetPolarization.p1() +
std::cos(phi) * fBeamPolarization.p1() * fTargetPolarization.p3() +
std::sin(phi) * fBeamPolarization.p3() * fTargetPolarization.p2() +
std::sin(phi) * fBeamPolarization.p2() * fTargetPolarization.p3());
treject = gdist/gdiced;
//G4cout<<" treject = "<<treject<<" at phi = "<<phi<<G4endl;
if (treject>1.+1.e-10 || treject<0){
G4cout<<"!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<<" phi rejection does not work properly: "<<treject<<G4endl;
G4cout<<" gdiced = "<<gdiced<<G4endl;
G4cout<<" gdist = "<<gdist<<G4endl;
G4cout<<" epsil = "<<epsil<<G4endl;
}
if (treject<1.e-3) {
G4cout<<"!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<<" phi rejection does not work properly: "<<treject<<"\n";
G4cout<<" gdiced="<<gdiced<<" gdist="<<gdist<<"\n";
G4cout<<" epsil = "<<epsil<<G4endl;
}
treject = gdist / gdiced;
if(treject > 1. + 1.e-10 || treject < 0)
{
G4ExceptionDescription ed;
ed << "!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<< " phi rejection does not work properly: " << treject << G4endl;
G4cout << " gdiced = " << gdiced << G4endl;
G4cout << " gdist = " << gdist << G4endl;
G4cout << " epsil = " << epsil << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol009",
JustWarning, ed);
}
if(treject < 1.e-3)
{
G4ExceptionDescription ed;
ed << "!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
<< " phi rejection does not work properly: " << treject << "\n";
G4cout << " gdiced=" << gdiced << " gdist=" << gdist << "\n";
G4cout << " epsil = " << epsil << G4endl;
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol010",
JustWarning, ed);
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while( treject < G4UniformRand() );
// G4cout<<"phi dicing END"<<G4endl;
} while(treject < G4UniformRand());
G4double dirx = sint*std::cos(phi) , diry = sint*std::sin(phi) , dirz = cost;
G4double dirx = sint * std::cos(phi);
G4double diry = sint * std::sin(phi);
G4double dirz = cost;
//
// kinematic of the created pair
//
G4double TotalAvailableEnergy = PositKinEnergy + 2*electron_mass_c2;
G4double Phot1Energy = epsil*TotalAvailableEnergy;
G4double Phot2Energy =(1.-epsil)*TotalAvailableEnergy;
G4double TotalAvailableEnergy = PositKinEnergy + 2 * electron_mass_c2;
G4double Phot1Energy = epsil * TotalAvailableEnergy;
G4double Phot2Energy = (1. - epsil) * TotalAvailableEnergy;
// *** prepare calculation of polarization transfer ***
G4ThreeVector Phot1Direction (dirx, diry, dirz);
G4ThreeVector Phot1Direction(dirx, diry, dirz);
// get interaction frame
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(PositDirection,Phot1Direction);
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(PositDirection, Phot1Direction);
// define proper in-plane and out-of-plane component of initial spins
theBeamPolarization.InvRotateAz(nInteractionFrame,PositDirection);
theTargetPolarization.InvRotateAz(nInteractionFrame,PositDirection);
fBeamPolarization.InvRotateAz(nInteractionFrame, PositDirection);
fTargetPolarization.InvRotateAz(nInteractionFrame, PositDirection);
// calculate spin transfere matrix
crossSectionCalculator->Initialize(epsil,gama,phi,theBeamPolarization,theTargetPolarization,2);
fCrossSectionCalculator->Initialize(epsil, gama, phi, fBeamPolarization,
fTargetPolarization, 2);
// **********************************************************************
Phot1Direction.rotateUz(PositDirection);
// create G4DynamicParticle object for the particle1
G4DynamicParticle* aParticle1= new G4DynamicParticle (G4Gamma::Gamma(),
Phot1Direction, Phot1Energy);
finalGamma1Polarization=crossSectionCalculator->GetPol2();
G4double n1=finalGamma1Polarization.mag2();
if (n1>1) {
G4cout<<"ERROR: PolarizedAnnihilation Polarization Vector at epsil = "
<<epsil<<" is too large!!! \n"
<<"annihi pol1= "<<finalGamma1Polarization<<", ("<<n1<<")\n";
finalGamma1Polarization*=1./std::sqrt(n1);
Phot1Direction.rotateUz(PositDirection);
// create G4DynamicParticle object for the particle1
G4DynamicParticle* aParticle1 =
new G4DynamicParticle(G4Gamma::Gamma(), Phot1Direction, Phot1Energy);
fFinalGamma1Polarization = fCrossSectionCalculator->GetPol2();
G4double n1 = fFinalGamma1Polarization.mag2();
if(n1 > 1.)
{
G4ExceptionDescription ed;
ed << "ERROR: PolarizedAnnihilation Polarization Vector at epsil = "
<< epsil << " is too large!!! \n"
<< "annihi pol1= " << fFinalGamma1Polarization << ", (" << n1 << ")\n";
fFinalGamma1Polarization *= 1. / std::sqrt(n1);
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol011",
JustWarning, ed);
}
// define polarization of first final state photon
finalGamma1Polarization.SetPhoton();
finalGamma1Polarization.RotateAz(nInteractionFrame,Phot1Direction);
aParticle1->SetPolarization(finalGamma1Polarization.p1(),
finalGamma1Polarization.p2(),
finalGamma1Polarization.p3());
fFinalGamma1Polarization.SetPhoton();
fFinalGamma1Polarization.RotateAz(nInteractionFrame, Phot1Direction);
aParticle1->SetPolarization(fFinalGamma1Polarization.p1(),
fFinalGamma1Polarization.p2(),
fFinalGamma1Polarization.p3());
fvect->push_back(aParticle1);
// **********************************************************************
G4double Eratio= Phot1Energy/Phot2Energy;
G4double PositP= std::sqrt(PositKinEnergy*(PositKinEnergy+2.*electron_mass_c2));
G4ThreeVector Phot2Direction (-dirx*Eratio, -diry*Eratio,
(PositP-dirz*Phot1Energy)/Phot2Energy);
Phot2Direction.rotateUz(PositDirection);
// create G4DynamicParticle object for the particle2
G4DynamicParticle* aParticle2= new G4DynamicParticle (G4Gamma::Gamma(),
Phot2Direction, Phot2Energy);
G4double Eratio = Phot1Energy / Phot2Energy;
G4double PositP =
std::sqrt(PositKinEnergy * (PositKinEnergy + 2. * electron_mass_c2));
G4ThreeVector Phot2Direction(-dirx * Eratio, -diry * Eratio,
(PositP - dirz * Phot1Energy) / Phot2Energy);
Phot2Direction.rotateUz(PositDirection);
// create G4DynamicParticle object for the particle2
G4DynamicParticle* aParticle2 =
new G4DynamicParticle(G4Gamma::Gamma(), Phot2Direction, Phot2Energy);
// define polarization of second final state photon
finalGamma2Polarization=crossSectionCalculator->GetPol3();
G4double n2=finalGamma2Polarization.mag2();
if (n2>1) {
G4cout<<"ERROR: PolarizedAnnihilation Polarization Vector at epsil = "<<epsil<<" is too large!!! \n";
G4cout<<"annihi pol2= "<<finalGamma2Polarization<<", ("<<n2<<")\n";
finalGamma2Polarization*=1./std::sqrt(n2);
fFinalGamma2Polarization = fCrossSectionCalculator->GetPol3();
G4double n2 = fFinalGamma2Polarization.mag2();
if(n2 > 1.)
{
G4ExceptionDescription ed;
ed << "ERROR: PolarizedAnnihilation Polarization Vector at epsil = "
<< epsil << " is too large!!! \n";
ed << "annihi pol2= " << fFinalGamma2Polarization << ", (" << n2 << ")\n";
G4Exception("G4PolarizedAnnihilationModel::SampleSecondaries", "pol012",
JustWarning, ed);
fFinalGamma2Polarization *= 1. / std::sqrt(n2);
}
finalGamma2Polarization.SetPhoton();
finalGamma2Polarization.RotateAz(nInteractionFrame,Phot2Direction);
aParticle2->SetPolarization(finalGamma2Polarization.p1(),
finalGamma2Polarization.p2(),
finalGamma2Polarization.p3());
fFinalGamma2Polarization.SetPhoton();
fFinalGamma2Polarization.RotateAz(nInteractionFrame, Phot2Direction);
aParticle2->SetPolarization(fFinalGamma2Polarization.p1(),
fFinalGamma2Polarization.p2(),
fFinalGamma2Polarization.p3());
fvect->push_back(aParticle2);
}
@@ -0,0 +1,312 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// File name: G4PolarizedAnnihilationXS
//
// Author: Andreas Schaelicke
//
// Class Description:
// * calculates the differential cross section in e+e- -> gamma gamma
#include "G4PolarizedAnnihilationXS.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedAnnihilationXS::G4PolarizedAnnihilationXS()
: polxx(0.)
, polyy(0.)
, polzz(0.)
, polxz(0.)
, polzx(0.)
, polxy(0.)
, polyx(0.)
, polyz(0.)
, polzy(0.)
, fPhi0(0.)
{
fPhi2 = G4ThreeVector(0., 0., 0.);
fPhi3 = G4ThreeVector(0., 0., 0.);
fDice = 0.;
fPolXS = 0.;
fUnpXS = 0.;
ISPxx = ISPyy = ISPzz = ISPnd = 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedAnnihilationXS::~G4PolarizedAnnihilationXS() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationXS::TotalXS()
{
// total cross section is sum of
// + unpol xsec "sigma0"
// + longitudinal polarised cross section "sigma_zz" times
// pol_3(e-)*pol_3(e+)
// + transverse contribution "(sigma_xx+sigma_yy)/2" times
// pol_T(e-)*pol_T(e+)
// (Note: if both beams are transversely polarised, i.e. pol_T(e-)!=0 and
// pol_T(e+)!=0, and sigma_xx!=sigma_yy, then the diff. cross section
// will exhibit a azimuthal asymmetry even if pol_T(e-)*pol_T(e+)==0)
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationXS::Initialize(
G4double eps, G4double gam,
G4double, // phi
const G4StokesVector& pol0, // positron polarization
const G4StokesVector& pol1, // electron polarization
G4int flag)
{
G4double diffXSFactor = re2 / (gam - 1.);
DefineCoefficients(pol0, pol1);
// prepare dicing
fDice = 0.;
G4double symmXS =
0.125 * ((-1. / sqr(gam + 1.)) / sqr(eps) +
((sqr(gam) + 4. * gam - 1.) / sqr(gam + 1.)) / eps - 1.);
G4ThreeVector epsVector(1. / sqr(eps), 1. / eps, 1.);
G4ThreeVector oneEpsVector(1. / sqr(1. - eps), 1. / (1. - eps), 1.);
G4ThreeVector sumEpsVector(epsVector + oneEpsVector);
G4ThreeVector difEpsVector(epsVector - oneEpsVector);
G4ThreeVector calcVector(0., 0., 0.);
// temporary variables
G4double helpVar2 = 0., helpVar1 = 0.;
// unpolarised contribution
helpVar1 = (gam * gam + 4. * gam + 1.) / sqr(gam + 1.);
helpVar2 = -1. / sqr(gam + 1.);
calcVector = G4ThreeVector(helpVar2, helpVar1, -1.);
fUnpXS = 0.125 * calcVector * sumEpsVector;
// initial particles polarised contribution
helpVar2 = 1. / sqr(gam + 1.);
helpVar1 = -(gam * gam + 4. * gam + 1.) / sqr(gam + 1.);
calcVector = G4ThreeVector(helpVar2, helpVar1, 0.5 * (gam + 3.));
ISPxx = 0.25 * (calcVector * sumEpsVector) / (gam - 1.);
helpVar1 = 1. / sqr(gam + 1.);
calcVector = G4ThreeVector(-helpVar1, 2. * gam * helpVar1, -1.);
ISPyy = 0.125 * calcVector * sumEpsVector;
helpVar1 = 1. / (gam - 1.);
helpVar2 = 1. / sqr(gam + 1.);
calcVector = G4ThreeVector(
-(gam * gam + 1.) * helpVar2,
(gam * gam * (gam + 1.) + 7. * gam + 3.) * helpVar2, -(gam + 3.));
ISPzz = 0.125 * helpVar1 * (calcVector * sumEpsVector);
helpVar1 = std::sqrt(std::fabs(eps * (1. - eps) * 2. * (gam + 1.) - 1.));
calcVector = G4ThreeVector(-1. / (gam * gam - 1.), 2. / (gam - 1.), 0.);
ISPnd = 0.125 * (calcVector * difEpsVector) * helpVar1;
fPolXS = ISPxx * polxx + ISPyy * polyy + ISPzz * polzz;
fPolXS += ISPnd * (polzx + polxz);
fPhi0 = fUnpXS + fPolXS;
fDice = symmXS;
if(polzz != 0.)
{
fDice *= (1. + (polzz * ISPzz / fUnpXS));
if(fDice < 0.)
fDice = 0.;
}
// prepare final state coefficients
if(flag == 2)
{
// circular polarisation
G4double circ1 = 0., circ2 = 0., circ3 = 0.;
helpVar1 = 8. * sqr(1. - eps) * sqr(eps) * (gam - 1.) * sqr(gam + 1.) /
std::sqrt(gam * gam - 1.);
helpVar2 = sqr(gam + 1.) * sqr(eps) * (-2. * eps + 3.) -
(gam * gam + 3. * gam + 2.) * eps;
circ1 = helpVar2 + gam;
circ1 /= helpVar1;
circ2 = helpVar2 + 1.;
circ2 /= helpVar1;
helpVar1 = std::sqrt(std::fabs(eps * (1. - eps) * 2. * (gam + 1.) - 1.));
helpVar1 /= std::sqrt(gam * gam - 1.);
calcVector = G4ThreeVector(1., -2. * gam, 0.);
circ3 = 0.125 * (calcVector * sumEpsVector) / (gam + 1.);
circ3 *= helpVar1;
fPhi2.setZ(circ2 * pol1.z() + circ1 * pol0.z() +
circ3 * (pol1.x() + pol0.x()));
fPhi3.setZ(-circ1 * pol1.z() - circ2 * pol0.z() -
circ3 * (pol1.x() + pol0.x()));
// common to both linear polarisation
calcVector = G4ThreeVector(-1., 2. * gam, 0.);
G4double linearZero = 0.125 * (calcVector * sumEpsVector) / sqr(gam + 1.);
// Linear Polarisation #1
helpVar1 = std::sqrt(std::fabs(2. * (gam + 1.) * (1. - eps) * eps - 1.)) /
((gam + 1.) * eps * (1. - eps));
helpVar2 = helpVar1 * helpVar1;
// photon 1
G4double diagContrib = 0.125 * helpVar2 * (polxx + polyy - polzz);
G4double nonDiagContrib =
0.125 * helpVar1 * (-polxz / (1. - eps) + polzx / eps);
fPhi2.setX(linearZero + diagContrib + nonDiagContrib);
// photon 2
nonDiagContrib = 0.125 * helpVar1 * (polxz / eps - polzx / (1. - eps));
fPhi3.setX(linearZero + diagContrib + nonDiagContrib);
// Linear Polarisation #2
helpVar1 =
std::sqrt(gam * gam - 1.) * (2. * (gam + 1.) * eps * (1. - eps) - 1.);
helpVar1 /= 8. * sqr(1. - eps) * sqr(eps) * sqr(gam + 1.) * (gam - 1.);
helpVar2 = std::sqrt((gam * gam - 1.) *
std::fabs(2. * (gam + 1.) * eps * (1. - eps) - 1.));
helpVar2 /= 8. * sqr(1. - eps) * sqr(eps) * sqr(gam + 1.) * (gam - 1.);
G4double contrib21 = (-polxy + polyx) * helpVar1;
G4double contrib32 =
-(eps * (gam + 1.) - 1.) * polyz + (eps * (gam + 1.) - gam) * polzy;
contrib32 *= helpVar2;
fPhi2.setY(contrib21 + contrib32);
contrib32 =
-(eps * (gam + 1.) - gam) * polyz + (eps * (gam + 1.) - 1.) * polzy;
contrib32 *= helpVar2;
fPhi3.setY(contrib21 + contrib32);
}
fPhi0 *= diffXSFactor;
fPhi2 *= diffXSFactor;
fPhi3 *= diffXSFactor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3)
{
G4double xs = fPhi0 + pol2 * fPhi2 + pol3 * fPhi3;
return xs;
}
// calculate total cross section
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::TotalXSection(G4double, G4double,
G4double gam,
const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
G4double totalXSFactor = pi * re2 / (gam + 1.); // atomic number ignored
DefineCoefficients(pol0, pol1);
G4double xs = 0.;
G4double gam2 = gam * gam;
G4double sqrtgam1 = std::sqrt(gam2 - 1.);
G4double logMEM = std::log(gam + sqrtgam1);
G4double unpME = (gam * (gam + 4.) + 1.) * logMEM;
unpME += -(gam + 3.) * sqrtgam1;
unpME /= 4. * (gam2 - 1.);
G4double longPart = (3 + gam * (gam * (gam + 1.) + 7.)) * logMEM;
longPart += -(5. + gam * (3 * gam + 4.)) * sqrtgam1;
longPart /= 4. * sqr(gam - 1.) * (gam + 1.);
G4double tranPart = -(5 * gam + 1.) * logMEM;
tranPart += (gam + 5.) * sqrtgam1;
tranPart /= 4. * sqr(gam - 1.) * (gam + 1.);
xs += unpME;
xs += polzz * longPart;
xs += (polxx + polyy) * tranPart;
return xs * totalXSFactor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedAnnihilationXS::GetPol2()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi2);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedAnnihilationXS::GetPol3()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi3);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedAnnihilationXS::DefineCoefficients(const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
polxx = pol0.x() * pol1.x();
polyy = pol0.y() * pol1.y();
polzz = pol0.z() * pol1.z();
polxz = pol0.x() * pol1.z();
polzx = pol0.z() * pol1.x();
polyz = pol0.y() * pol1.z();
polzy = pol0.z() * pol1.y();
polxy = pol0.x() * pol1.y();
polyx = pol0.y() * pol1.x();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::GetXmin(G4double y)
{
return 0.5 * (1. - std::sqrt((y - 1.) / (y + 1.)));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::GetXmax(G4double y)
{
return 0.5 * (1. + std::sqrt((y - 1.) / (y + 1.)));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::DiceEpsilon() { return fDice; }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedAnnihilationXS::getVar(G4int choice)
{
if(choice == -1)
return fPolXS / fUnpXS;
if(choice == 0)
return fUnpXS;
if(choice == 1)
return ISPxx;
if(choice == 2)
return ISPyy;
if(choice == 3)
return ISPzz;
if(choice == 4)
return ISPnd;
return 0;
}
@@ -1,308 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedBhabhaCrossSection
//
// Author: Andreas Schaelicke
//
// Creation date: 12.01.2006
//
// Modifications:
// 16-01-06 included cross section as calculated by P.Starovoitov
// 24-08-06 bugfix in total cross section (A. Schaelicke)
// 07-11-06 modify reference system for polarisation vectors
// (A. Schaelicke & P.Starovoitov)
//
// Class Description:
// * calculates the differential cross section
// incomming positron Kpl(along positive z direction) scatters at
// an electron Kmn at rest
// * phi denotes the angle between the scattering plane (defined by the
// outgoing electron) and X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
//
#include "G4PolarizedBhabhaCrossSection.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedBhabhaCrossSection::G4PolarizedBhabhaCrossSection() : phi0(1.)
{
}
G4PolarizedBhabhaCrossSection::~G4PolarizedBhabhaCrossSection()
{
}
void G4PolarizedBhabhaCrossSection::Initialize(
G4double e,
G4double gamma,
G4double /*phi*/,
const G4StokesVector & pol0,
const G4StokesVector & pol1,
G4int flag)
{
SetXmax(1.);
G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2 = gamma*gamma;
G4double gamma3 = gamma2*gamma;
G4double gmo = (gamma - 1.);
G4double gmo2 = (gamma - 1.)*(gamma - 1.);
G4double gmo3 = gmo2*(gamma - 1.);
G4double gpo = (gamma + 1.);
G4double gpo2 = (gamma + 1.)*(gamma + 1.);
G4double gpo3 = gpo2*(gamma + 1.);
G4double gpo12 = std::sqrt(gpo);
G4double gpo32 = gpo*gpo12;
G4double gpo52 = gpo2*gpo12;
G4double pref = re2/(gamma - 1.0);
G4double sqrttwo=std::sqrt(2.);
G4double d = std::sqrt(1./e - 1.);
G4double e2 = e*e;
G4double e3 = e2*e;
// *** new ***
G4double gmo12 = std::sqrt(gmo);
G4double gmo32 = gmo*gmo12;
G4double egmp32 = std::pow(e*(2 + e*gmo)*gpo,(3./2.));
G4double e32 = e*std::sqrt(e);
G4bool polarized=(!pol0.IsZero())||(!pol1.IsZero());
if (flag==0) polarized=false;
// Unpolarised part of XS
// *AS* UnpME . OK
phi0 = 0.;
phi0+= e2*gmo3/gpo3;
phi0+= -2.*e*gamma*gmo2/gpo3;
phi0+= (3.*gamma2 + 6.*gamma + 4.)*gmo/gpo3;
phi0+= -(2.*gamma2 + 4.*gamma + 1.)/(e*gpo2);
phi0+= gamma2/(e2*(gamma2 - 1.));
phi0*=0.25;
// Initial state polarisarion dependence
if (polarized) {
// G4cout<<"Polarized differential Bhabha cross section"<<G4endl;
// G4cout<<"Initial state polarisation contributions"<<G4endl;
// G4cout<<"Diagonal Matrix Elements"<<G4endl;
// *** new ***
G4double xx = -((e*gmo - gamma)*(-1 - gamma + e*(e*gmo - gamma)*(3 + gamma)))/(4*e*gpo3);
G4double yy = (e3*gmo3 - 2*e2*gmo2*gamma - gpo*(1 + 2*gamma) + e*(-2 + gamma2 + gamma3))/(4*e*gpo3);
G4double zz = ((e*gmo - gamma)*(e2*gmo*(3 + gamma) - e*gamma*(3 + gamma) + gpo*(1 + 2*gamma)))/(4*e*gpo3);
// ***
phi0 += xx*pol0.x()*pol1.x() + yy*pol0.y()*pol1.y() + zz*pol0.z()*pol1.z();
{
G4double xy = 0;
G4double xz = (d*(e*gmo - gamma)*(-1 + 2*e*gmo - gamma))/(2*sqrttwo*gpo52);
G4double yx = 0;
G4double yz = 0;
G4double zx = xz;
G4double zy = 0;
// G4cout<<"Non-diagonal Matrix Elements"<<G4endl;
phi0+=yx*pol0.y()*pol1.x() + xy*pol0.x()*pol1.y();
phi0+=zx*pol0.z()*pol1.x() + xz*pol0.x()*pol1.z();
phi0+=zy*pol0.z()*pol1.y() + yz*pol0.y()*pol1.z();
}
}
// Final state polarisarion dependence
phi2=G4ThreeVector();
phi3=G4ThreeVector();
if (flag>=1) {
//
// Final Positron Ppl
//
// initial positron Kpl
if (!pol0.IsZero()) {
G4double xxPplKpl = -((-1 + e)*(e*gmo - gamma)*(-(gamma*gpo) + e*(-2 + gamma + gamma2)))/
(4*e2*gpo*std::sqrt(gmo*gpo*(-1 + e + gamma - e*gamma)* (1 + e + gamma - e*gamma)));
G4double xyPplKpl = 0;
G4double xzPplKpl = ((e*gmo - gamma)*(-1 - gamma + e*gmo*(1 + 2*gamma)))/
(2*sqrttwo*e32*gmo*gpo2*std::sqrt(1 + e + gamma - e*gamma));
G4double yxPplKpl = 0;
G4double yyPplKpl = (gamma2*gpo + e2*gmo2*(3 + gamma) -
e*gmo*(1 + 2*gamma*(2 + gamma)))/(4*e2*gmo*gpo2);
G4double yzPplKpl = 0;
G4double zxPplKpl = ((e*gmo - gamma)*(1 + e*(-1 + 2*e*gmo - 2*gamma)*gmo + gamma))/
(2*sqrttwo*e*gmo*gpo2*std::sqrt(e*(1 + e + gamma - e*gamma)));
G4double zyPplKpl = 0;
G4double zzPplKpl = -((e*gmo - gamma)*std::sqrt((1 - e)/(e - e*gamma2 + gpo2))*
(2*e2*gmo2 + gamma + gamma2 - e*(-2 + gamma + gamma2)))/
(4*e2*(-1 + gamma2));
phi2[0] += xxPplKpl*pol0.x() + xyPplKpl*pol0.y() + xzPplKpl*pol0.z();
phi2[1] += yxPplKpl*pol0.x() + yyPplKpl*pol0.y() + yzPplKpl*pol0.z();
phi2[2] += zxPplKpl*pol0.x() + zyPplKpl*pol0.y() + zzPplKpl*pol0.z();
}
// initial electron Kmn
if (!pol1.IsZero()) {
G4double xxPplKmn = ((-1 + e)*(e*(-2 + gamma)*gmo + gamma))/(4*e*gpo32*std::sqrt(1 + e2*gmo + gamma - 2*e*gamma));
G4double xyPplKmn = 0;
G4double xzPplKmn = (-1 + e*gmo + gmo*gamma)/(2*sqrttwo*gpo2* std::sqrt(e*(1 + e + gamma - e*gamma)));
G4double yxPplKmn = 0;
G4double yyPplKmn = (-1 - 2*gamma + e*gmo*(3 + gamma))/(4*e*gpo2);
G4double yzPplKmn = 0;
G4double zxPplKmn = (1 + 2*e2*gmo2 + gamma + gamma2 + e*(1 + (3 - 4*gamma)*gamma))/
(2*sqrttwo*gpo2*std::sqrt(e*(1 + e + gamma - e*gamma)));
G4double zyPplKmn = 0;
G4double zzPplKmn = -(std::sqrt((1 - e)/(e - e*gamma2 + gpo2))*
(2*e2*gmo2 + gamma + 2*gamma2 + e*(2 + gamma - 3*gamma2)))/(4*e*gpo);
phi2[0] += xxPplKmn*pol1.x() + xyPplKmn*pol1.y() + xzPplKmn*pol1.z();
phi2[1] += yxPplKmn*pol1.x() + yyPplKmn*pol1.y() + yzPplKmn*pol1.z();
phi2[2] += zxPplKmn*pol1.x() + zyPplKmn*pol1.y() + zzPplKmn*pol1.z();
}
//
// Final Electron Pmn
//
// initial positron Kpl
if (!pol0.IsZero()) {
G4double xxPmnKpl = ((-1 + e*gmo)*(2 + gamma))/(4*gpo* std::sqrt(e*(2 + e*gmo)*gpo));
G4double xyPmnKpl = 0;
G4double xzPmnKpl = (std::sqrt((-1 + e)/(-2 + e - e*gamma))*
(e + gamma + e*gamma - 2*(-1 + e)*gamma2))/(2*sqrttwo*e*gpo2);
G4double yxPmnKpl = 0;
G4double yyPmnKpl = (-1 - 2*gamma + e*gmo*(3 + gamma))/(4*e*gpo2);
G4double yzPmnKpl = 0;
G4double zxPmnKpl = -((-1 + e)*(1 + 2*e*gmo)*(e*gmo - gamma))/
(2*sqrttwo*e*std::sqrt(-((-1 + e)*(2 + e*gmo)))*gpo2);
G4double zyPmnKpl = 0;
G4double zzPmnKpl = (-2 + 2*e2*gmo2 + gamma*(-1 + 2*gamma) +
e*(-2 + (5 - 3*gamma)*gamma))/(4*std::sqrt(e*(2 + e*gmo))* gpo32);
phi3[0] += xxPmnKpl*pol0.x() + xyPmnKpl*pol0.y() + xzPmnKpl*pol0.z();
phi3[1] += yxPmnKpl*pol0.x() + yyPmnKpl*pol0.y() + yzPmnKpl*pol0.z();
phi3[2] += zxPmnKpl*pol0.x() + zyPmnKpl*pol0.y() + zzPmnKpl*pol0.z();
}
// initial electron Kmn
if (!pol1.IsZero()) {
G4double xxPmnKmn = -((2 + e*gmo)*(-1 + e*gmo - gamma)*(e*gmo - gamma)*
(-2 + gamma))/(4*gmo*egmp32);
G4double xyPmnKmn = 0;
G4double xzPmnKmn = ((e*gmo - gamma)*
std::sqrt((-1 + e + gamma - e*gamma)/(2 + e*gmo))*
(e + gamma - e*gamma + gamma2))/
(2*sqrttwo*e2*gmo32*gpo2);
G4double yxPmnKmn = 0;
G4double yyPmnKmn = (gamma2*gpo + e2*gmo2*(3 + gamma) -
e*gmo*(1 + 2*gamma*(2 + gamma)))/(4*e2*gmo*gpo2);
G4double yzPmnKmn = 0;
G4double zxPmnKmn = -((-1 + e)*(e*gmo - gamma)*(e*gmo + 2*e2*gmo2 - gamma*gpo))/
(2*sqrttwo*e2*std::sqrt(-((-1 + e)*(2 + e*gmo)))* gmo*gpo2);
G4double zyPmnKmn = 0;
G4double zzPmnKmn = ((e*gmo - gamma)*std::sqrt(e/((2 + e*gmo)*gpo))*
(-(e*(-2 + gamma)*gmo) + 2*e2*gmo2 + (-2 + gamma)*gpo))/(4*e2*(-1 + gamma2));
phi3[0] += xxPmnKmn*pol1.x() + xyPmnKmn*pol1.y() + xzPmnKmn*pol1.z();
phi3[1] += yxPmnKmn*pol1.x() + yyPmnKmn*pol1.y() + yzPmnKmn*pol1.z();
phi3[2] += zxPmnKmn*pol1.x() + zyPmnKmn*pol1.y() + zzPmnKmn*pol1.z();
}
}
phi0 *= pref;
phi2 *= pref;
phi3 *= pref;
}
G4double G4PolarizedBhabhaCrossSection::XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3)
{
G4double xs=0.;
xs+=phi0;
G4bool polarized=(!pol2.IsZero())||(!pol3.IsZero());
if (polarized) {
xs+=phi2*pol2 + phi3*pol3;
}
return xs;
}
G4double G4PolarizedBhabhaCrossSection::TotalXSection(
G4double xmin, G4double xmax, G4double gamma,
const G4StokesVector & pol0,const G4StokesVector & pol1)
{
G4double xs=0.;
G4double x=xmin;
if (xmax != 1.) G4cout<<" warning xmax expected to be 1 but is "<<xmax<< G4endl;
// re -> electron radius^2;
G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2=gamma*gamma;
G4double gmo2 = (gamma - 1.)*(gamma - 1.);
G4double gpo2 = (gamma + 1.)*(gamma + 1.);
G4double gpo3 = gpo2*(gamma + 1.);
G4double logMEM = std::log(x);
G4double pref = twopi*re2/(gamma - 1.0);
// unpolarise XS
G4double sigma0 = 0.;
sigma0 += -gmo2*(gamma - 1.)*x*x*x/3. + gmo2*gamma*x*x;
sigma0 += -(gamma - 1.)*(3.*gamma*(gamma + 2.) +4.)*x;
sigma0 += (gamma*(gamma*(gamma*(4.*gamma - 1.) - 21.) - 7.)+13.)/(3.*(gamma - 1.));
sigma0 /= gpo3;
sigma0 += logMEM*(2. - 1./gpo2);
sigma0 += gamma2/((gamma2 - 1.)*x);
// longitudinal part
G4double sigma2=0.;
sigma2 += logMEM*gamma*(gamma + 1.)*(2.*gamma + 1.);
sigma2 += gamma*(7.*gamma*(gamma + 1.) - 2.)/3.;
sigma2 += -(3.*gamma + 1.)*(gamma2 + gamma - 1.)*x;
sigma2 += (gamma - 1.)*gamma*(gamma + 3.)*x*x;
sigma2 += -gmo2*(gamma + 3.)*x*x*x/3.;
sigma2 /= gpo3;
// transverse part
G4double sigma3=0.;
sigma3 += 0.5*(gamma + 1.)*(3.*gamma + 1.)*logMEM;
sigma3 += (gamma*(5.*gamma - 4.) - 13.)/6.;
sigma3 += 0.5*(gamma2 + 3.)*x;
sigma3 += - 2.*(gamma - 1.)*gamma*x*x; // *AS* changed sign
sigma3 += 2.*gmo2*x*x*x/3.;
sigma3 /= gpo3;
// total cross section
xs+=pref*(sigma0 + sigma2*pol0.z()*pol1.z() + sigma3*(pol0.x()*pol1.x()+pol0.y()*pol1.y()));
return xs;
}
G4StokesVector G4PolarizedBhabhaCrossSection::GetPol2()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi2;
}
G4StokesVector G4PolarizedBhabhaCrossSection::GetPol3()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi3;
}
@@ -23,58 +23,43 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
// Geant4 Class file
//
//
// File name: G4ePolarizedBremsstrahlung
// File name: G4PolarizedBremsstrahlung
//
// Author: Karim Laihem
//
// Creation date: 26.06.2005
//
// Modifications:
// 19-08-06 addapted to accomodate geant481 structure
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ePolarizedBremsstrahlung.hh"
#include "G4SystemOfUnits.hh"
#include "G4Gamma.hh"
#include "G4ePolarizedBremsstrahlungModel.hh"
#include "G4UniversalFluctuation.hh"
#include "G4UnitsTable.hh"
#include "G4LossTableManager.hh"
#include "G4PolarizedBremsstrahlung.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4EmParameters.hh"
#include "G4Gamma.hh"
#include "G4PolarizedBremsstrahlungModel.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedBremsstrahlung::G4ePolarizedBremsstrahlung(const G4String& name):
G4eBremsstrahlung(name)
G4PolarizedBremsstrahlung::G4PolarizedBremsstrahlung(const G4String& name)
: G4eBremsstrahlung(name)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedBremsstrahlung::~G4PolarizedBremsstrahlung() {}
void G4ePolarizedBremsstrahlung::InitialiseEnergyLossProcess(
const G4ParticleDefinition*,
const G4ParticleDefinition*)
void G4PolarizedBremsstrahlung::ProcessDescription(std::ostream& out) const
{
if(!isInitialised) {
out << "Polarized model for bremsstrahlung.\n";
G4eBremsstrahlung::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedBremsstrahlung::InitialiseEnergyLossProcess(
const G4ParticleDefinition*, const G4ParticleDefinition*)
{
if(!isInitialised)
{
isInitialised = true;
SetSecondaryParticle(G4Gamma::Gamma());
SetIonisation(false);
G4VEmFluctuationModel* fm = nullptr;
G4VEmModel* em = new G4ePolarizedBremsstrahlungModel;
G4VEmFluctuationModel* fm = nullptr;
G4VEmModel* em = new G4PolarizedBremsstrahlungModel;
G4EmParameters* param = G4EmParameters::Instance();
em->SetLowEnergyLimit(param->MinKinEnergy());
em->SetHighEnergyLimit(param->MaxKinEnergy());
@@ -1,213 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedBremsstrahlungCrossSection
//
// Author: Andreas Schaelicke on the base of Karim Laihems code
//
// Creation date: 16.08.2006
//
#include "G4PolarizedBremsstrahlungCrossSection.hh"
#include "G4PhysicalConstants.hh"
G4bool G4PolarizedBremsstrahlungCrossSection::scrnInitialized=false;
G4double G4PolarizedBremsstrahlungCrossSection::SCRN [3][20];
// screening function lookup table;
void G4PolarizedBremsstrahlungCrossSection::InitializeMe()
{
if (!scrnInitialized) {
SCRN [1][1]= 0.5 ; SCRN [2][1] = 0.0145;
SCRN [1][2]= 1.0 ; SCRN [2][2] = 0.0490;
SCRN [1][3]= 2.0 ; SCRN [2][3] = 0.1400;
SCRN [1][4]= 4.0 ; SCRN [2][4] = 0.3312;
SCRN [1][5]= 8.0 ; SCRN [2][5] = 0.6758;
SCRN [1][6]= 15.0 ; SCRN [2][6] = 1.126;
SCRN [1][7]= 20.0 ; SCRN [2][7] = 1.367;
SCRN [1][8]= 25.0 ; SCRN [2][8] = 1.564;
SCRN [1][9]= 30.0 ; SCRN [2][9] = 1.731;
SCRN [1][10]= 35.0 ; SCRN [2][10]= 1.875;
SCRN [1][11]= 40.0 ; SCRN [2][11]= 2.001;
SCRN [1][12]= 45.0 ; SCRN [2][12]= 2.114;
SCRN [1][13]= 50.0 ; SCRN [2][13]= 2.216;
SCRN [1][14]= 60.0 ; SCRN [2][14]= 2.393;
SCRN [1][15]= 70.0 ; SCRN [2][15]= 2.545;
SCRN [1][16]= 80.0 ; SCRN [2][16]= 2.676;
SCRN [1][17]= 90.0 ; SCRN [2][17]= 2.793;
SCRN [1][18]= 100.0 ; SCRN [2][18]= 2.897;
SCRN [1][19]= 120.0 ; SCRN [2][19]= 3.078;
scrnInitialized=true;
}
}
G4PolarizedBremsstrahlungCrossSection::G4PolarizedBremsstrahlungCrossSection()
{
InitializeMe();
}
void G4PolarizedBremsstrahlungCrossSection::Initialize(
G4double aLept0E, G4double aGammaE, G4double sintheta,
const G4StokesVector & beamPol,
const G4StokesVector & /*p1*/,
G4int /*flag*/)
{
// G4cout<<"G4PolarizedBremsstrahlungCrossSection::Initialize \n"
// <<"lepE = "<<aLept0E
// <<"gamE = "<<aGammaE
// <<"sint = "<<sintheta<<"\n"
// <<"beamPol="<<beamPol<<"\n";
G4double aLept1E = aLept0E - aGammaE;
G4double Stokes_S1 = beamPol.x() ;
G4double Stokes_S2 = beamPol.y() ;
G4double Stokes_S3 = beamPol.z() ;
// **************************************************************************
G4double m0_c2 = electron_mass_c2;
G4double Lept0E = aLept0E/m0_c2+1., Lept0E2 = Lept0E * Lept0E ;
G4double GammaE = aGammaE/m0_c2, GammaE2 = GammaE * GammaE ;
G4double Lept1E = aLept1E/m0_c2+1., Lept1E2 = Lept1E * Lept1E ;
// const G4Element* theSelectedElement = theModel->SelectedAtom();
// ******* Gamma Transvers Momentum
G4double TMom = std::sqrt(Lept0E2 -1.)* sintheta;
G4double u = TMom , u2 =u * u ;
G4double Xsi = 1./(1.+u2) , Xsi2 = Xsi * Xsi ;
// G4double theZ = theSelectedElement->GetZ();
// G4double fCoul = theSelectedElement->GetfCoulomb();
G4double delta = 12. * std::pow(theZ, 1./3.) *
Lept0E * Lept1E * Xsi / (121. * GammaE);
G4double GG=0.;
if(delta < 0.5) {
GG = std::log(2.* Lept0E * Lept1E / GammaE) - 2. - fCoul;
}
else if ( delta < 120) {
for (G4int j=2; j<=19; j++) {
if(SCRN[1][j] >= delta) {
GG =std::log(2 * Lept0E * Lept1E / GammaE) - 2 - fCoul
-(SCRN[2][j-1]+(delta-SCRN[1][j-1])*(SCRN[2][j]-SCRN[2][j-1])
/(SCRN[1][j]-SCRN[1][j-1]));
break;
}
}
}
else {
G4double alpha_sc = (111. * std::pow(theZ, -1./3.)) / Xsi;
GG = std::log(alpha_sc)- 2. - fCoul;
}
if(GG<-1.) GG=-1.; // *KL* do we need this ?!
G4double I_Lept = (Lept0E2 + Lept1E2) * (3.+2.*GG) - 2 * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
G4double F_Lept = Lept1E * 4. * GammaE * u * Xsi * (1. - 2 * Xsi) * GG / I_Lept;
G4double E_Lept = Lept0E * 4. * GammaE * u * Xsi * (2. * Xsi - 1.) * GG / I_Lept;
G4double M_Lept = 4. * Lept0E * Lept1E * (1. + GG - 2. * Xsi2 * u2 * GG) / I_Lept ;
G4double P_Lept = GammaE2 * (1. + 8. * GG * (Xsi - 0.5)*(Xsi - 0.5)) / I_Lept ;
G4double Stokes_SS1 = M_Lept * Stokes_S1 + E_Lept * Stokes_S3;
G4double Stokes_SS2 = M_Lept * Stokes_S2 ;
G4double Stokes_SS3 = (M_Lept + P_Lept) * Stokes_S3 + F_Lept * Stokes_S1;
theFinalLeptonPolarization.setX(Stokes_SS1);
theFinalLeptonPolarization.setY(Stokes_SS2);
theFinalLeptonPolarization.setZ(Stokes_SS3);
if(theFinalLeptonPolarization.mag2()>1) {
G4cout<<" WARNING in pol-brem theFinalLeptonPolarization \n";
G4cout
<<"\t"<<theFinalLeptonPolarization
<<"\t GG\t"<<GG
<<"\t delta\t"<<delta
<<G4endl;
theFinalLeptonPolarization.setX(0);
theFinalLeptonPolarization.setY(0);
theFinalLeptonPolarization.setZ(Stokes_SS3);
if(Stokes_SS3>1) theFinalLeptonPolarization.setZ(1);
}
G4double I_Gamma = (Lept0E2 + Lept1E2)*(3.+2.*GG) - 2. * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
G4double D_Gamma = 8. * Lept0E * Lept1E * u2 * Xsi2 * GG / I_Gamma;
G4double L_Gamma = GammaE * ((Lept0E + Lept1E) * (3. + 2. * GG)
- 2. * Lept1E * (1. + 4. * u2 * Xsi2 * GG))/I_Gamma;
G4double T_Gamma = 4. * GammaE * Lept1E * Xsi * u * (2. * Xsi - 1.) * GG / I_Gamma ;
G4double Stokes_P1 = D_Gamma ;
G4double Stokes_P2 = 0.;
G4double Stokes_P3 = (Stokes_S3*L_Gamma + Stokes_S1*T_Gamma) ;
theFinalGammaPolarization.SetPhoton();
theFinalGammaPolarization.setX(Stokes_P1);
theFinalGammaPolarization.setY(Stokes_P2);
theFinalGammaPolarization.setZ(Stokes_P3);
if(theFinalGammaPolarization.mag2()>1) {
G4cout<<" WARNING in pol-brem theFinalGammaPolarization \n";
G4cout
<<"\t"<<theFinalGammaPolarization
<<"\t GG\t"<<GG
<<"\t delta\t"<<delta
<<G4endl;
}
}
G4double G4PolarizedBremsstrahlungCrossSection::XSection(const G4StokesVector & /*pol2*/,
const G4StokesVector & /*pol3*/)
{
G4cout<<"ERROR dummy routine G4PolarizedBremsstrahlungCrossSection::XSection called \n";
return 0.;
}
// return expected mean polarisation
G4StokesVector G4PolarizedBremsstrahlungCrossSection::GetPol2()
{
// electron/positron
return theFinalLeptonPolarization;
}
G4StokesVector G4PolarizedBremsstrahlungCrossSection::GetPol3()
{
// photon
return theFinalGammaPolarization;;
}
@@ -0,0 +1,120 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 class file
//
// File name: G4PolarizedBremsstrahlungModel
//
// Author: Karim Laihem
#include "G4PolarizedBremsstrahlungModel.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizedBremsstrahlungXS.hh"
G4PolarizedBremsstrahlungModel::G4PolarizedBremsstrahlungModel(
const G4ParticleDefinition* p, const G4String& nam)
: G4SeltzerBergerModel(p, nam)
, fCrossSectionCalculator(nullptr)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedBremsstrahlungModel::~G4PolarizedBremsstrahlungModel()
{
if(fCrossSectionCalculator)
delete fCrossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedBremsstrahlungModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& d)
{
G4SeltzerBergerModel::Initialise(p, d);
if(!fCrossSectionCalculator)
fCrossSectionCalculator = new G4PolarizedBremsstrahlungXS();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// The emitted gamma energy is sampled using a parametrized formula
void G4PolarizedBremsstrahlungModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp, const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp, G4double tmin, G4double maxEnergy)
{
G4SeltzerBergerModel::SampleSecondaries(vdp, couple, dp, tmin, maxEnergy);
G4int num = vdp->size();
if(num > 0)
{
G4double lepEnergy0 = dp->GetKineticEnergy();
G4double gamEnergy1 = (*vdp)[0]->GetKineticEnergy();
G4double sintheta =
dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if(sintheta > 1.)
sintheta = 1.;
G4StokesVector beamPol = G4StokesVector(dp->GetPolarization());
// determine interaction plane
G4ThreeVector nInteractionFrame = G4PolarizationHelper::GetFrame(
dp->GetMomentumDirection(),
fParticleChange->GetProposedMomentumDirection());
// transform polarization into interaction frame
beamPol.InvRotateAz(nInteractionFrame, dp->GetMomentumDirection());
// calculate polarization transfer
fCrossSectionCalculator->SetMaterial(
GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(), GetCurrentElement()->GetfCoulomb());
fCrossSectionCalculator->Initialize(lepEnergy0, gamEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// determine final state polarization
G4StokesVector newBeamPol = fCrossSectionCalculator->GetPol2();
newBeamPol.RotateAz(nInteractionFrame,
fParticleChange->GetProposedMomentumDirection());
fParticleChange->ProposePolarization(newBeamPol);
if(num != 1)
{
G4ExceptionDescription ed;
ed << num << " secondaries in polarized bremsstrahlung not supported!\n";
G4Exception("G4PolarizedBremsstrahlungModel::SampleSecondaries", "pol001",
JustWarning, ed);
}
for(G4int i = 0; i < num; ++i)
{
G4StokesVector photonPol = fCrossSectionCalculator->GetPol3();
photonPol.SetPhoton();
photonPol.RotateAz(nInteractionFrame, (*vdp)[i]->GetMomentumDirection());
(*vdp)[i]->SetPolarization(photonPol.p1(), photonPol.p2(),
photonPol.p3());
}
}
return;
}
@@ -0,0 +1,198 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 class file
//
// File name: G4PolarizedBremsstrahlungXS
//
// Author: Andreas Schaelicke on the base of Karim Laihems code
#include "G4PolarizedBremsstrahlungXS.hh"
#include "G4PhysicalConstants.hh"
G4double G4PolarizedBremsstrahlungXS::SCRN[2][19] = {
{ 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0,
60.0, 70.0, 80.0, 90.0, 100.0, 120.0 },
{ 0.0145, 0.0490, 0.1400, 0.3312, 0.6758, 1.126, 1.367, 1.564, 1.731, 1.875,
2.001, 2.114, 2.216, 2.393, 2.545, 2.676, 2.793, 2.897, 3.078 }
};
G4PolarizedBremsstrahlungXS::G4PolarizedBremsstrahlungXS()
{
fFinalLeptonPolarization = G4StokesVector::ZERO;
fFinalGammaPolarization = G4StokesVector::ZERO;
}
G4PolarizedBremsstrahlungXS::~G4PolarizedBremsstrahlungXS() {}
void G4PolarizedBremsstrahlungXS::Initialize(G4double aLept0E, G4double aGammaE,
G4double sintheta,
const G4StokesVector& beamPol,
const G4StokesVector& /*p1*/,
G4int /*flag*/)
{
G4double aLept1E = aLept0E - aGammaE;
G4double Stokes_S1 = beamPol.x();
G4double Stokes_S2 = beamPol.y();
G4double Stokes_S3 = beamPol.z();
G4double Lept0E = aLept0E / electron_mass_c2 + 1.;
G4double Lept0E2 = Lept0E * Lept0E;
G4double GammaE = aGammaE / electron_mass_c2;
G4double GammaE2 = GammaE * GammaE;
G4double Lept1E = aLept1E / electron_mass_c2 + 1.;
G4double Lept1E2 = Lept1E * Lept1E;
// ******* Gamma Transverse Momentum
G4double TMom = std::sqrt(Lept0E2 - 1.) * sintheta;
G4double u = TMom;
G4double u2 = u * u;
G4double Xsi = 1. / (1. + u2);
G4double Xsi2 = Xsi * Xsi;
G4double delta =
12. * std::pow(fZ, 1. / 3.) * Lept0E * Lept1E * Xsi / (121. * GammaE);
G4double GG = 0.;
if(delta < 0.5)
{
GG = std::log(2. * Lept0E * Lept1E / GammaE) - 2. - fCoul;
}
else if(delta < 120)
{
for(G4int j = 1; j < 19; ++j)
{
if(SCRN[0][j] >= delta)
{
GG = std::log(2 * Lept0E * Lept1E / GammaE) - 2 - fCoul -
(SCRN[1][j - 1] + (delta - SCRN[0][j - 1]) *
(SCRN[1][j] - SCRN[1][j - 1]) /
(SCRN[0][j] - SCRN[0][j - 1]));
break;
}
}
}
else
{
G4double alpha_sc = (111. * std::pow(fZ, -1. / 3.)) / Xsi;
GG = std::log(alpha_sc) - 2. - fCoul;
}
if(GG < -1.)
GG = -1.;
G4double I_Lept = (Lept0E2 + Lept1E2) * (3. + 2. * GG) -
2 * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
G4double F_Lept =
Lept1E * 4. * GammaE * u * Xsi * (1. - 2 * Xsi) * GG / I_Lept;
G4double E_Lept =
Lept0E * 4. * GammaE * u * Xsi * (2. * Xsi - 1.) * GG / I_Lept;
G4double M_Lept =
4. * Lept0E * Lept1E * (1. + GG - 2. * Xsi2 * u2 * GG) / I_Lept;
G4double P_Lept =
GammaE2 * (1. + 8. * GG * (Xsi - 0.5) * (Xsi - 0.5)) / I_Lept;
G4double Stokes_SS1 = M_Lept * Stokes_S1 + E_Lept * Stokes_S3;
G4double Stokes_SS2 = M_Lept * Stokes_S2;
G4double Stokes_SS3 = (M_Lept + P_Lept) * Stokes_S3 + F_Lept * Stokes_S1;
fFinalLeptonPolarization.setX(Stokes_SS1);
fFinalLeptonPolarization.setY(Stokes_SS2);
fFinalLeptonPolarization.setZ(Stokes_SS3);
if(fFinalLeptonPolarization.mag2() > 1.)
{
G4ExceptionDescription ed;
ed << " WARNING in pol-brem fFinalLeptonPolarization \n";
ed << "\t" << fFinalLeptonPolarization << "\t GG\t" << GG << "\t delta\t"
<< delta;
G4Exception("G4PolarizedBremsstrahlungXS::Initialize", "pol014",
JustWarning, ed);
fFinalLeptonPolarization.setX(0);
fFinalLeptonPolarization.setY(0);
fFinalLeptonPolarization.setZ(Stokes_SS3);
if(Stokes_SS3 > 1)
fFinalLeptonPolarization.setZ(1);
}
G4double I_Gamma = (Lept0E2 + Lept1E2) * (3. + 2. * GG) -
2. * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
G4double D_Gamma = 8. * Lept0E * Lept1E * u2 * Xsi2 * GG / I_Gamma;
G4double L_Gamma = GammaE *
((Lept0E + Lept1E) * (3. + 2. * GG) -
2. * Lept1E * (1. + 4. * u2 * Xsi2 * GG)) /
I_Gamma;
G4double T_Gamma =
4. * GammaE * Lept1E * Xsi * u * (2. * Xsi - 1.) * GG / I_Gamma;
G4double Stokes_P1 = D_Gamma;
G4double Stokes_P2 = 0.;
G4double Stokes_P3 = (Stokes_S3 * L_Gamma + Stokes_S1 * T_Gamma);
fFinalGammaPolarization.SetPhoton();
fFinalGammaPolarization.setX(Stokes_P1);
fFinalGammaPolarization.setY(Stokes_P2);
fFinalGammaPolarization.setZ(Stokes_P3);
if(fFinalGammaPolarization.mag2() > 1.)
{
G4ExceptionDescription ed;
ed << " WARNING in pol-brem fFinalGammaPolarization \n";
ed << "\t" << fFinalGammaPolarization << "\t GG\t" << GG << "\t delta\t"
<< delta;
G4Exception("G4PolarizedBremsstrahlungXS::Initialize", "pol015",
JustWarning, ed);
}
}
G4double G4PolarizedBremsstrahlungXS::XSection(const G4StokesVector& /*pol2*/,
const G4StokesVector& /*pol3*/)
{
G4ExceptionDescription ed;
ed << "ERROR dummy routine G4PolarizedBremsstrahlungXS::XSection "
"called.\n";
G4Exception("G4PolarizedBremsstrahlungXS::XSection", "pol016", FatalException,
ed);
return 0.;
}
// return expected mean polarisation
G4StokesVector G4PolarizedBremsstrahlungXS::GetPol2()
{
// electron/positron
return fFinalLeptonPolarization;
}
G4StokesVector G4PolarizedBremsstrahlungXS::GetPol3()
{
// photon
return fFinalGammaPolarization;
}
@@ -23,82 +23,63 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// File name: G4PolarizedCompton
//
// Author: Andreas Schaelicke
// based on code by Michel Maire / Vladimir IVANTCHENKO
//
// Class description
//
// modified version respecting media and beam polarization
// using the stokes formalism
//
// Creation date: 01.05.2005
//
// Modifications:
//
// 01-01-05, include polarization description (A.Stahl)
// 01-01-05, create asymmetry table and determine interactionlength (A.Stahl)
// 01-05-05, update handling of media polarization (A.Schalicke)
// 01-05-05, update polarized differential cross section (A.Schalicke)
// 20-05-05, added polarization transfer (A.Schalicke)
// 10-06-05, transformation between different reference frames (A.Schalicke)
// 17-10-05, correct reference frame dependence in GetMeanFreePath (A.Schalicke)
// 26-07-06, cross section recalculated (P.Starovoitov)
// 09-08-06, make it work under current geant4 release (A.Schalicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
// -----------------------------------------------------------------------------
// modified version respecting media and beam polarization
// using the stokes formalism
#include "G4PolarizedCompton.hh"
#include "G4SystemOfUnits.hh"
#include "G4Electron.hh"
#include "G4StokesVector.hh"
#include "G4Electron.hh"
#include "G4EmParameters.hh"
#include "G4KleinNishinaCompton.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizedComptonModel.hh"
#include "G4ProductionCutsTable.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4KleinNishinaCompton.hh"
#include "G4PolarizedComptonModel.hh"
#include "G4EmParameters.hh"
#include "G4StokesVector.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PhysicsTable* G4PolarizedCompton::theAsymmetryTable = nullptr;
G4PolarizedCompton::G4PolarizedCompton(const G4String& processName,
G4ProcessType type):
G4VEmProcess (processName, type),
buildAsymmetryTable(true),
useAsymmetryTable(true),
isInitialised(false),
mType(10),
targetPolarization(0.0,0.0,0.0)
G4ProcessType type)
: G4VEmProcess(processName, type)
, fType(10)
, fBuildAsymmetryTable(true)
, fUseAsymmetryTable(true)
, fIsInitialised(false)
{
SetStartFromNullFlag(true);
SetBuildTableFlag(true);
SetSecondaryParticle(G4Electron::Electron());
SetProcessSubType(fComptonScattering);
SetMinKinEnergyPrim(1*MeV);
SetMinKinEnergyPrim(1. * MeV);
SetSplineFlag(true);
emModel = nullptr;
fEmModel = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedCompton::~G4PolarizedCompton()
G4PolarizedCompton::~G4PolarizedCompton() { CleanTable(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedCompton::ProcessDescription(std::ostream& out) const
{
CleanTable();
out << "Polarized model for Compton scattering.\n";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::CleanTable()
{
if( theAsymmetryTable) {
if(theAsymmetryTable)
{
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
@@ -106,73 +87,73 @@ void G4PolarizedCompton::CleanTable()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4PolarizedCompton::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Gamma::Gamma());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedCompton::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(0 == mType) {
if(!EmModel(0)) { SetEmModel(new G4KleinNishinaCompton()); }
} else {
emModel = new G4PolarizedComptonModel();
SetEmModel(emModel);
if(!fIsInitialised)
{
fIsInitialised = true;
if(0 == fType)
{
if(nullptr == EmModel(0))
{
SetEmModel(new G4KleinNishinaCompton());
}
}
else
{
fEmModel = new G4PolarizedComptonModel();
SetEmModel(fEmModel);
}
G4EmParameters* param = G4EmParameters::Instance();
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(0)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel(0));
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::PrintInfo()
{
G4cout << " Total cross sections has a good parametrisation"
<< " from 10 KeV to (100/Z) GeV"
<< "\n Sampling according " << EmModel(0)->GetName() << " model"
<< G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::SetModel(const G4String& ss)
{
if(ss == "Klein-Nishina") { mType = 0; }
if(ss == "Polarized-Compton") { mType = 10; }
if(ss == "Klein-Nishina")
{
fType = 0;
}
if(ss == "Polarized-Compton")
{
fType = 10;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
G4double previousStepSize,
G4ForceCondition* condition)
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEmProcess::GetMeanFreePath(aTrack, previousStepSize, condition);
G4double mfp =
G4VEmProcess::GetMeanFreePath(aTrack, previousStepSize, condition);
if (theAsymmetryTable && useAsymmetryTable && mfp < DBL_MAX) {
if(theAsymmetryTable && fUseAsymmetryTable && mfp < DBL_MAX)
{
mfp *= ComputeSaturationFactor(aTrack);
}
if (verboseLevel>=2) {
G4cout << "G4PolarizedCompton::MeanFreePath: " << mfp / mm << " mm " << G4endl;
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedCompton::MeanFreePath: " << mfp / mm << " mm "
<< G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
const G4Track& aTrack, G4double previousStepSize, G4ForceCondition* condition)
{
// save previous values
G4double nLength = theNumberOfInteractionLengthLeft;
@@ -180,190 +161,208 @@ G4double G4PolarizedCompton::PostStepGetPhysicalInteractionLength(
// *** compute unpolarized step limit ***
// this changes theNumberOfInteractionLengthLeft and currentInteractionLength
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(aTrack,
previousStepSize,
condition);
G4double x0 = x;
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(
aTrack, previousStepSize, condition);
G4double x0 = x;
G4double satFact = 1.0;
// *** add corrections on polarisation ***
if (theAsymmetryTable && useAsymmetryTable && x < DBL_MAX) {
satFact = ComputeSaturationFactor(aTrack);
G4double curLength = currentInteractionLength*satFact;
G4double prvLength = iLength*satFact;
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize/prvLength, 0.0);
if(theAsymmetryTable && fUseAsymmetryTable && x < DBL_MAX)
{
satFact = ComputeSaturationFactor(aTrack);
G4double curLength = currentInteractionLength * satFact;
G4double prvLength = iLength * satFact;
if(nLength > 0.0)
{
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize / prvLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if (verboseLevel>=2) {
G4cout << "G4PolarizedCompton::PostStepGPIL: "
<< std::setprecision(8) << x/mm << " mm;" << G4endl
<< " unpolarized value: "
<< std::setprecision(8) << x0/mm << " mm." << G4endl;
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedCompton::PostStepGPIL: " << std::setprecision(8)
<< x / mm << " mm;" << G4endl
<< " unpolarized value: " << std::setprecision(8)
<< x0 / mm << " mm." << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::ComputeSaturationFactor(const G4Track& aTrack)
{
G4double factor = 1.0;
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4StokesVector GammaPolarization = aTrack.GetPolarization();
const G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4StokesVector GammaPolarization =
G4StokesVector(aTrack.GetPolarization());
const G4ParticleMomentum GammaDirection0 =
aDynamicGamma->GetMomentumDirection();
G4Material* aMaterial = aTrack.GetMaterial();
G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4Material* aMaterial = aTrack.GetMaterial();
G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
const G4bool VolumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector ElectronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
const G4bool VolumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
G4StokesVector ElectronPolarization =
polarizationManager->GetVolumePolarization(aLVolume);
if (VolumeIsPolarized) {
if (verboseLevel>=2) {
if(VolumeIsPolarized)
{
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedCompton::ComputeSaturationFactor: " << G4endl;
G4cout << " Mom " << GammaDirection0 << G4endl;
G4cout << " Polarization " << GammaPolarization << G4endl;
G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
G4cout << " Mom " << GammaDirection0 << G4endl;
G4cout << " Polarization " << GammaPolarization << G4endl;
G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
if(midx < theAsymmetryTable->size()) {
if(midx < theAsymmetryTable->size())
{
aVector = (*theAsymmetryTable)(midx);
}
if (aVector) {
if(aVector)
{
G4double asymmetry = aVector->Value(GammaEnergy);
// we have to determine angle between particle motion
// and target polarisation here
// we have to determine angle between particle motion
// and target polarisation here
// circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
// both vectors in global reference frame
G4double pol = ElectronPolarization*GammaDirection0;
G4double pol = ElectronPolarization * GammaDirection0;
G4double polProduct = GammaPolarization.p3() * pol;
factor /= (1. + polProduct * asymmetry);
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << asymmetry << G4endl;
G4cout << " PolProduct: " << polProduct << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
if(verboseLevel >= 2)
{
G4cout << " Asymmetry: " << asymmetry << G4endl;
G4cout << " PolProduct: " << polProduct << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
}
else
{
G4ExceptionDescription ed;
ed << "Problem with asymmetry table: material index " << midx
<< " is out of range or the table is not filled";
G4Exception("G4PolarizedComptonModel::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
ed << "Problem with asymmetry table: material index " << midx
<< " is out of range or the table is not filled";
G4Exception("G4PolarizedComptonModel::ComputeSaturationFactor", "em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& part)
{
// *** build (unpolarized) cross section tables (Lambda)
G4VEmProcess::BuildPhysicsTable(part);
if(buildAsymmetryTable && emModel) {
if(fBuildAsymmetryTable && fEmModel)
{
G4bool isMaster = true;
const G4PolarizedCompton* masterProcess =
const G4PolarizedCompton* masterProcess =
static_cast<const G4PolarizedCompton*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { isMaster = false; }
if(isMaster) { BuildAsymmetryTable(part); }
if(masterProcess && masterProcess != this)
{
isMaster = false;
}
if(isMaster)
{
BuildAsymmetryTable(part);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTable();
theAsymmetryTable =
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
const G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
if(!theAsymmetryTable) { return; }
G4int nbins = LambdaBinning();
G4double emin = MinKinEnergy();
G4double emax = MaxKinEnergy();
if(!theAsymmetryTable)
{
return;
}
G4int nbins = LambdaBinning();
G4double emin = MinKinEnergy();
G4double emax = MaxKinEnergy();
G4PhysicsLogVector* aVector = nullptr;
G4PhysicsLogVector* bVector = nullptr;
for(size_t i=0; i<numOfCouples; ++i) {
if (theAsymmetryTable->GetFlag(i)) {
for(size_t i = 0; i < numOfCouples; ++i)
{
if(theAsymmetryTable->GetFlag(i))
{
// create physics vector and fill it
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(i);
// use same parameters as for lambda
if(!aVector) {
aVector = new G4PhysicsLogVector(emin, emax, nbins);
aVector->SetSpline(true);
if(!aVector)
{
aVector = new G4PhysicsLogVector(emin, emax, nbins, true);
bVector = aVector;
} else {
bVector = new G4PhysicsLogVector(*aVector);
}
else
{
bVector = new G4PhysicsLogVector(*aVector);
}
for (G4int j = 0; j <= nbins; ++j ) {
G4double energy = bVector->Energy(j);
G4double tasm=0.;
G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
bVector->PutValue(j,asym);
for(G4int j = 0; j <= nbins; ++j)
{
G4double energy = bVector->Energy(j);
G4double tasm = 0.;
G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
bVector->PutValue(j, asym);
}
bVector->FillSecondDerivatives();
G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, bVector);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle,
G4double cut,
G4double & tAsymmetry)
G4double G4PolarizedCompton::ComputeAsymmetry(
G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry=0;
tAsymmetry = 0;
//
// calculate polarized cross section
//
G4ThreeVector thePolarization=G4ThreeVector(0.,0.,1.);
emModel->SetTargetPolarization(thePolarization);
emModel->SetBeamPolarization(thePolarization);
G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
G4ThreeVector thePolarization = G4ThreeVector(0., 0., 1.);
fEmModel->SetTargetPolarization(thePolarization);
fEmModel->SetBeamPolarization(thePolarization);
G4double sigma2 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
//
// calculate unpolarized cross section
//
thePolarization=G4ThreeVector();
emModel->SetTargetPolarization(thePolarization);
emModel->SetBeamPolarization(thePolarization);
G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
thePolarization = G4ThreeVector();
fEmModel->SetTargetPolarization(thePolarization);
fEmModel->SetBeamPolarization(thePolarization);
G4double sigma0 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// determine assymmetries
if (sigma0 > 0.) {
lAsymmetry = sigma2/sigma0-1.;
// determine asymmetries
if(sigma0 > 0.)
{
lAsymmetry = sigma2 / sigma0 - 1.;
}
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1,250 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class file
//
//
// File name: G4PolarizedComptonCrossSection
//
// Author: Andreas Schaelicke
//
// Creation date: 15.05.2005
//
// Modifications:
//
// Class Description:
// determine the polarization of the final state
// in a Compton scattering process employing the differential
// cross section by F.W.Lipps & H.A.Tolhoek
// ( Physica 20 (1954) 395 )
// recalculated by P.Starovoitov
//
#include "G4PolarizedComptonCrossSection.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedComptonCrossSection::G4PolarizedComptonCrossSection()
: gammaPol2(false), electronPol3(false)
{
SetYmin(0.);
// G4cout<<"G4PolarizedComptonCrossSection() init\n";
re2 = classic_electr_radius * classic_electr_radius * sqr(4*pi/hbarc);
// G4double unit_conversion = hbarc_squared ;
// G4cout<<" (keV)^2* m^2 ="<<unit_conversion<<"\n";
phi0 = 0.; polXS = 0.; unpXS = 0.;
phi2 = G4ThreeVector(0., 0., 0.);
phi3 = G4ThreeVector(0., 0., 0.);
polxx = polyy = polzz = polxz = polzx = polyz = polzy = polxy = polyx = 0.;
diffXSFactor = 1.;
totalXSFactor = 1.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedComptonCrossSection::~G4PolarizedComptonCrossSection()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedComptonCrossSection::Initialize(G4double eps, G4double X, G4double , // phi
const G4StokesVector & pol0,
const G4StokesVector & pol1,
G4int flag)
{
G4double cosT = 1. - (1./eps - 1.)/X;
if(cosT > 1.+1.e-8) cosT = 1.;
if(cosT < -1.-1.e-8) cosT = -1.;
G4double cosT2 = cosT*cosT;
G4double cosT3 = cosT2*cosT;
G4double sinT2 = 1. - cosT2;
if(sinT2 > 1. + 1.e-8) sinT2 = 1.;
if(sinT2 < 0.) sinT2 = 0.;
G4double sinT = std::sqrt(sinT2);
G4double cos2T = 2.*cosT2 - 1.;
G4double sin2T = 2.*sinT*cosT;
G4double eps2 = sqr(eps);
DefineCoefficients(pol0,pol1);
diffXSFactor = re2/(4.*X);
// unpolarized Cross Section
unpXS = (eps2 + 1. - eps*sinT2)/(2.*eps);
// initial polarization dependence
polXS = -sinT2*pol0.x() + (1. - eps)*sinT*polzx + ((eps2 - 1.)/eps)*cosT*polzz;
polXS *= 0.5;
phi0 = unpXS + polXS;
if (flag == 2 ){
// polarization of outgoing photon
G4double PHI21 = -sinT2 + 0.5*(cos2T + 3.)*pol0.x() - ((1. - eps)/eps)*sinT*polzx;
PHI21 *= 0.5;
G4double PHI22 = cosT*pol0.y() + ((1. - eps)/(2.*eps))*sinT*polzy;
G4double PHI23 = ((eps2 + 1.)/eps)*cosT*pol0.z() - ((1. - eps)/eps)*(eps*cosT2 + 1.)*pol1.z();
PHI23 += 0.5*(1. - eps)*sin2T*pol1.x();
PHI23 += (eps - 1.)*(-sinT2*polxz + sinT*polyy - 0.5*sin2T*polxx);
PHI23 *= 0.5;
phi2 = G4ThreeVector(PHI21, PHI22, PHI23);
// polarization of outgoing electron
G4double PHI32 = -sinT2*polxy + ((1. - eps)/eps)*sinT*polyz + 0.5*(cos2T + 3.)*pol1.y();
PHI32 *= 0.5;
G4double PHI31 = 0., PHI31add = 0., PHI33 = 0., PHI33add = 0.;
if ((1. - eps) > 1.e-12){
G4double helpVar = std::sqrt(eps2 - 2.*cosT*eps + 1.);
PHI31 = (1. - eps)*(1. + cosT)*sinT*pol0.z();
PHI31 += (-eps*cosT3 + eps*cosT2 + (eps - 2.)*cosT + eps)*pol1.x();
PHI31 += -(eps*cosT2 - eps*cosT + cosT + 1.)*sinT*pol1.z();
PHI31 /= 2.*helpVar;
PHI31add = -eps*sqr(1. - cosT)*(1. + cosT)*polxx;
PHI31add += (1. - eps)*sinT2*polyy;
PHI31add += -(-eps2 + cosT*(cosT*eps - eps + 1.)*eps + eps - 1.)*sinT*polxz/eps;
PHI31add /= 2.*helpVar;
PHI33 = ((1. - eps)/eps)*(-eps*cosT2 + eps*(eps + 1.)*cosT - 1.)*pol0.z();
PHI33 += -(eps*cosT2 + (1. - eps)*eps*cosT + 1.)*sinT*pol1.x();
PHI33 += -(-eps2*cosT3 + eps*(eps2 - eps + 1.)*cosT2 - cosT + eps2)*pol1.z()/eps;
PHI33 /= -2.*helpVar;
PHI33add = (eps*(eps - cosT - 1.)*cosT + 1.)*sinT*polxx;
PHI33add += -(-eps2 + cosT*eps + eps - 1.)*sinT2*polxz;
PHI33add += (eps - 1.)*(cosT - eps)*sinT*polyy;
PHI33add /= -2.*helpVar;
}else{
PHI31 = -pol1.z() - (X - 1.)*std::sqrt(1. - eps)*pol1.x()/std::sqrt(2.*X);
PHI31add = -(-X*X*pol1.z() - 2.*X*(2.*pol0.z() - pol1.z()) - (4.*pol0.x() + 5.)*pol1.z())*(1. - eps)/(4.*X);
PHI33 = pol1.x() - (X - 1.)*std::sqrt(1. - eps)*pol1.z()/std::sqrt(2.*X);
PHI33add = -(X*X - 2.*X + 4.*pol0.x() + 5.)*(1. - eps)*pol1.x()/(4.*X);
}
phi3 = G4ThreeVector(PHI31 + PHI31add, PHI32, PHI33 + PHI33add);
}
unpXS *= diffXSFactor;
polXS *= diffXSFactor;
phi0 *= diffXSFactor;
phi2 *= diffXSFactor;
phi3 *= diffXSFactor;
}
G4double G4PolarizedComptonCrossSection::XSection(const G4StokesVector & pol2,const G4StokesVector & pol3)
{
gammaPol2 = !(pol2==G4StokesVector::ZERO);
electronPol3 = !(pol3==G4StokesVector::ZERO);
G4double phi = 0.;
// polarization independent part
phi += phi0;
if (gammaPol2) {
// part depending on the polarization of the final photon
phi += phi2*pol2;
}
if (electronPol3) {
// part depending on the polarization of the final electron
phi += phi3*pol3;
}
// return cross section.
return phi;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedComptonCrossSection::TotalXSection(G4double /*xmin*/, G4double /*xmax*/, G4double k0,
const G4StokesVector & pol0,
const G4StokesVector & pol1)
{
// G4double k0 = gammaEnergy / electron_mass_c2 ;
G4double k1 = 1. + 2.*k0 ;
// // pi*re^2
// G4double re=2.81794e-15; //m
// G4double barn=1.e-28; //m^2
G4double Z=theZ;
G4double unit = Z*pi*classic_electr_radius
* classic_electr_radius ; // *1./barn;
G4double pre = unit/(sqr(k0)*sqr(1.+2.*k0));
G4double xs_0 = ((k0 - 2.)*k0 -2.)*sqr(k1)*std::log(k1) + 2.*k0*(k0*(k0 + 1.)*(k0 + 8.) + 2.);
G4double xs_pol = (k0 + 1.)*sqr(k1)*std::log(k1) - 2.*k0*(5.*sqr(k0) + 4.*k0 + 1.);
return pre*(xs_0/k0 + pol0.p3()*pol1.z()*xs_pol);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedComptonCrossSection::GetPol2()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedComptonCrossSection::GetPol3()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi3;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedComptonCrossSection::DefineCoefficients(const G4StokesVector & pol0,
const G4StokesVector & pol1)
{
polxx=pol0.x()*pol1.x();
polyy=pol0.y()*pol1.y();
polzz=pol0.z()*pol1.z();
polxz=pol0.x()*pol1.z();
polzx=pol0.z()*pol1.x();
polyz=pol0.y()*pol1.z();
polzy=pol0.z()*pol1.y();
polxy=pol0.x()*pol1.y();
polyx=pol0.y()*pol1.x();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,160 +23,138 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4PolarizedComptonModel
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
// 18-07-06 use newly calculated cross sections (P. Starovoitov)
// 21-08-05 update interface (A. Schaelicke)
//
// Class Description:
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4PolarizedComptonModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "Randomize.hh"
#include "G4DataVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4StokesVector.hh"
#include "G4Exp.hh"
#include "G4Log.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4PhysicalConstants.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizedComptonCrossSection.hh"
#include "G4PolarizedComptonXS.hh"
#include "G4StokesVector.hh"
#include "G4SystemOfUnits.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
static const G4int nlooplim = 10000;
G4PolarizedComptonModel::G4PolarizedComptonModel(const G4ParticleDefinition*,
const G4String& nam)
: G4KleinNishinaCompton(nullptr,nam),
verboseLevel(0)
const G4String& nam)
: G4KleinNishinaCompton(nullptr, nam)
, fVerboseLevel(0)
{
crossSectionCalculator = new G4PolarizedComptonCrossSection();
fCrossSectionCalculator = new G4PolarizedComptonXS();
fBeamPolarization = G4StokesVector::ZERO;
fTargetPolarization = G4StokesVector::ZERO;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedComptonModel::~G4PolarizedComptonModel()
{
delete crossSectionCalculator;
delete fCrossSectionCalculator;
}
G4double G4PolarizedComptonModel::ComputeAsymmetryPerAtom
(G4double gammaEnergy, G4double /*Z*/)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedComptonModel::ComputeAsymmetryPerAtom(G4double gammaEnergy,
G4double /*Z*/)
{
G4double asymmetry = 0.0 ;
G4double asymmetry = 0.0;
G4double k0 = gammaEnergy / electron_mass_c2 ;
G4double k1 = 1. + 2.*k0 ;
G4double k0 = gammaEnergy / electron_mass_c2;
G4double k1 = 1. + 2. * k0;
asymmetry = -k0;
asymmetry *= (k0 + 1.)*sqr(k1)*G4Log(k1) - 2.*k0*(5.*sqr(k0) + 4.*k0 + 1.);
asymmetry /= ((k0 - 2.)*k0 -2.)*sqr(k1)*G4Log(k1) + 2.*k0*(k0*(k0 + 1.)*(k0 + 8.) + 2.);
asymmetry *=
(k0 + 1.) * sqr(k1) * G4Log(k1) - 2. * k0 * (5. * sqr(k0) + 4. * k0 + 1.);
asymmetry /= ((k0 - 2.) * k0 - 2.) * sqr(k1) * G4Log(k1) +
2. * k0 * (k0 * (k0 + 1.) * (k0 + 8.) + 2.);
// G4cout<<"energy = "<<GammaEnergy<<" asymmetry = "<<asymmetry<<"\t\t GAM = "<<k0<<G4endl;
if (asymmetry>1.) G4cout<<"ERROR in G4PolarizedComptonModel::ComputeAsymmetryPerAtom"<<G4endl;
if(asymmetry > 1.)
{
G4ExceptionDescription ed;
ed << "ERROR in G4PolarizedComptonModel::ComputeAsymmetryPerAtom.\n"
<< " asymmetry = " << asymmetry << "\n";
G4Exception("G4PolarizedComptonModel::ComputeAsymmetryPerAtom", "pol035",
JustWarning, ed);
}
return asymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedComptonModel::ComputeCrossSectionPerAtom(
const G4ParticleDefinition* pd,
G4double kinEnergy,
G4double Z,
G4double A,
G4double cut,
G4double emax)
const G4ParticleDefinition* pd, G4double kinEnergy, G4double Z, G4double A,
G4double cut, G4double emax)
{
double xs =
G4KleinNishinaCompton::ComputeCrossSectionPerAtom(pd,kinEnergy,
Z,A,cut,emax);
G4double polzz = theBeamPolarization.p3()*theTargetPolarization.z();
if (polzz > 0.0) {
G4double asym = ComputeAsymmetryPerAtom(kinEnergy, Z);
xs *= (1.+polzz*asym);
G4double xs = G4KleinNishinaCompton::ComputeCrossSectionPerAtom(
pd, kinEnergy, Z, A, cut, emax);
G4double polzz = fBeamPolarization.p3() * fTargetPolarization.z();
if(polzz > 0.0)
{
G4double asym = ComputeAsymmetryPerAtom(kinEnergy, Z);
xs *= (1. + polzz * asym);
}
return xs;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedComptonModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* fvect,
const G4MaterialCutsCouple*,
const G4DynamicParticle* aDynamicGamma,
G4double, G4double)
std::vector<G4DynamicParticle*>* fvect, const G4MaterialCutsCouple*,
const G4DynamicParticle* aDynamicGamma, G4double, G4double)
{
// do nothing below the threshold
if(aDynamicGamma->GetKineticEnergy() <= LowEnergyLimit()) { return; }
const G4Track * aTrack = fParticleChange->GetCurrentTrack();
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
if (verboseLevel >= 1) {
G4cout<<"G4PolarizedComptonModel::SampleSecondaries in "
<< aLVolume->GetName() <<G4endl;
if(aDynamicGamma->GetKineticEnergy() <= LowEnergyLimit())
{
return;
}
G4PolarizationManager * polarizationManager =
const G4Track* aTrack = fParticleChange->GetCurrentTrack();
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
if(fVerboseLevel >= 1)
{
G4cout << "G4PolarizedComptonModel::SampleSecondaries in "
<< aLVolume->GetName() << G4endl;
}
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
// obtain polarization of the beam
theBeamPolarization = aDynamicGamma->GetPolarization();
theBeamPolarization.SetPhoton();
fBeamPolarization = G4StokesVector(aDynamicGamma->GetPolarization());
fBeamPolarization.SetPhoton();
// obtain polarization of the media
G4bool targetIsPolarized = polarizationManager->IsPolarized(aLVolume);
theTargetPolarization =
polarizationManager->GetVolumePolarization(aLVolume);
fTargetPolarization = polarizationManager->GetVolumePolarization(aLVolume);
// if beam is linear polarized or target is transversely polarized
// if beam is linear polarized or target is transversely polarized
// determine the angle to x-axis
// (assumes same PRF as in the polarization definition)
G4ThreeVector gamDirection0 = aDynamicGamma->GetMomentumDirection();
// transfere theTargetPolarization
// transfer fTargetPolarization
// into the gamma frame (problem electron is at rest)
if (targetIsPolarized) {
theTargetPolarization.rotateUz(gamDirection0);
if(targetIsPolarized)
{
fTargetPolarization.rotateUz(gamDirection0);
}
// The scattered gamma energy is sampled according to
// The scattered gamma energy is sampled according to
// Klein - Nishina formula.
// The random number techniques of Butcher & Messel are used
// The random number techniques of Butcher & Messel are used
// (Nuc Phys 20(1960),15).
// Note : Effects due to binding of atomic electrons are negliged.
// Note : Effects due to binding of atomic electrons are neglected.
G4double gamEnergy0 = aDynamicGamma->GetKineticEnergy();
G4double E0_m = gamEnergy0 / electron_mass_c2 ;
//
// sample the energy rate of the scattered gamma
//
G4double E0_m = gamEnergy0 / electron_mass_c2;
// sample the energy rate of the scattered gamma
G4double epsilon, sint2;
G4double onecost = 0.0;
G4double Phi = 0.0;
@@ -184,64 +162,69 @@ void G4PolarizedComptonModel::SampleSecondaries(
G4double cosTeta = 1.0;
G4double sinTeta = 0.0;
G4double eps0 = 1./(1. + 2.*E0_m);
G4double epsilon0sq = eps0*eps0;
G4double alpha1 = - G4Log(eps0);
G4double alpha2 = alpha1 + 0.5*(1.- epsilon0sq);
G4double eps0 = 1. / (1. + 2. * E0_m);
G4double epsilon0sq = eps0 * eps0;
G4double alpha1 = -G4Log(eps0);
G4double alpha2 = alpha1 + 0.5 * (1. - epsilon0sq);
G4double polarization =
theBeamPolarization.p3()*theTargetPolarization.p3();
G4double polarization = fBeamPolarization.p3() * fTargetPolarization.p3();
CLHEP::HepRandomEngine* rndmEngineMod = G4Random::getTheEngine();
G4int nloop = 0;
G4bool end = false;
G4int nloop = 0;
G4bool end = false;
G4double rndm[3];
do {
do {
do
{
do
{
++nloop;
// false interaction if too many iterations
if(nloop > nlooplim) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
if(nloop > fLoopLim)
{
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
}
// 3 random numbers to sample scattering
rndmEngineMod->flatArray(3, rndm);
if ( alpha1 > alpha2*rndm[0]) {
epsilon = G4Exp(-alpha1*rndm[1]); // epsilon0**r
} else {
epsilon = std::sqrt(epsilon0sq + (1.- epsilon0sq)*rndm[1]);
if(alpha1 > alpha2 * rndm[0])
{
epsilon = G4Exp(-alpha1 * rndm[1]);
}
else
{
epsilon = std::sqrt(epsilon0sq + (1. - epsilon0sq) * rndm[1]);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
onecost = (1. - epsilon) / (epsilon * E0_m);
sint2 = onecost * (2. - onecost);
G4double gdiced = 2.*(1./epsilon+epsilon);
G4double gdist = 1./epsilon + epsilon - sint2
- polarization*(1./epsilon-epsilon)*(1.-onecost);
G4double gdiced = 2. * (1. / epsilon + epsilon);
G4double gdist = 1. / epsilon + epsilon - sint2 -
polarization * (1. / epsilon - epsilon) * (1. - onecost);
greject = gdist/gdiced;
greject = gdist / gdiced;
if (greject > 1.0) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"theta majoranta wrong");
if(greject > 1.0)
{
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"theta majoranta wrong");
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (greject < rndm[2]);
} while(greject < rndm[2]);
// assuming phi loop sucessful
// assuming phi loop successful
end = true;
//
// scattered gamma angles. ( Z - axis along the parent gamma)
//
cosTeta = 1. - onecost;
cosTeta = 1. - onecost;
sinTeta = std::sqrt(sint2);
do {
do
{
++nloop;
// 2 random numbers to sample scattering
@@ -249,189 +232,202 @@ void G4PolarizedComptonModel::SampleSecondaries(
// false interaction if too many iterations
Phi = twopi * rndm[0];
if(nloop > nlooplim) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
if(nloop > fLoopLim)
{
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
}
G4double gdiced = 1./epsilon + epsilon - sint2
+ std::abs(theBeamPolarization.p3())*
( std::abs((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3())
+(1.-epsilon)*sinTeta*(std::sqrt(sqr(theTargetPolarization.p1())
+ sqr(theTargetPolarization.p2()))))
+sint2*(std::sqrt(sqr(theBeamPolarization.p1()) +
sqr(theBeamPolarization.p2())));
G4double gdiced = 1. / epsilon + epsilon - sint2 +
std::abs(fBeamPolarization.p3()) *
(std::abs((1. / epsilon - epsilon) * cosTeta *
fTargetPolarization.p3()) +
(1. - epsilon) * sinTeta *
(std::sqrt(sqr(fTargetPolarization.p1()) +
sqr(fTargetPolarization.p2())))) +
sint2 * (std::sqrt(sqr(fBeamPolarization.p1()) +
sqr(fBeamPolarization.p2())));
G4double gdist = 1./epsilon + epsilon - sint2
+ theBeamPolarization.p3()*
((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3()
+(1.-epsilon)*sinTeta*(std::cos(Phi)*theTargetPolarization.p1()+
std::sin(Phi)*theTargetPolarization.p2()))
-sint2*(std::cos(2.*Phi)*theBeamPolarization.p1()
+std::sin(2.*Phi)*theBeamPolarization.p2());
greject = gdist/gdiced;
G4double gdist =
1. / epsilon + epsilon - sint2 +
fBeamPolarization.p3() *
((1. / epsilon - epsilon) * cosTeta * fTargetPolarization.p3() +
(1. - epsilon) * sinTeta *
(std::cos(Phi) * fTargetPolarization.p1() +
std::sin(Phi) * fTargetPolarization.p2())) -
sint2 * (std::cos(2. * Phi) * fBeamPolarization.p1() +
std::sin(2. * Phi) * fBeamPolarization.p2());
greject = gdist / gdiced;
if (greject > 1.0) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi majoranta wrong");
if(greject > 1.0)
{
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi majoranta wrong");
}
if(greject < 1.e-3) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi loop ineffective");
// restart theta loop
if(greject < 1.e-3)
{
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi loop ineffective");
// restart theta loop
end = false;
break;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (greject < rndm[1]);
} while(!end);
G4double dirx = sinTeta*std::cos(Phi), diry = sinTeta*std::sin(Phi),
dirz = cosTeta;
//
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(greject < rndm[1]);
} while(!end);
G4double dirx = sinTeta * std::cos(Phi);
G4double diry = sinTeta * std::sin(Phi);
G4double dirz = cosTeta;
// update G4VParticleChange for the scattered gamma
//
G4ThreeVector gamDirection1 ( dirx,diry,dirz );
G4ThreeVector gamDirection1(dirx, diry, dirz);
gamDirection1.rotateUz(gamDirection0);
G4double gamEnergy1 = epsilon*gamEnergy0;
G4double gamEnergy1 = epsilon * gamEnergy0;
G4double edep = 0.0;
if(gamEnergy1 > lowestSecondaryEnergy) {
if(gamEnergy1 > lowestSecondaryEnergy)
{
fParticleChange->ProposeMomentumDirection(gamDirection1);
fParticleChange->SetProposedKineticEnergy(gamEnergy1);
} else {
}
else
{
fParticleChange->ProposeTrackStatus(fStopAndKill);
fParticleChange->SetProposedKineticEnergy(0.0);
edep = gamEnergy1;
}
//
// calculate Stokesvector of final state photon and electron
//
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(gamDirection1,gamDirection0);
// transfere theBeamPolarization and theTargetPolarization
// calculate Stokes vector of final state photon and electron
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(gamDirection1, gamDirection0);
// transfer fBeamPolarization and fTargetPolarization
// into the interaction frame (note electron is in gamma frame)
if (verboseLevel>=1) {
G4cout << "========================================\n";
G4cout << " nInteractionFrame = " <<nInteractionFrame<<"\n";
G4cout << " GammaDirection0 = " <<gamDirection0<<"\n";
G4cout << " gammaPolarization = " <<theBeamPolarization<<"\n";
G4cout << " electronPolarization = " <<theTargetPolarization<<"\n";
if(fVerboseLevel >= 1)
{
G4cout << "========================================" << G4endl;
G4cout << " nInteractionFrame = " << nInteractionFrame << G4endl;
G4cout << " GammaDirection0 = " << gamDirection0 << G4endl;
G4cout << " gammaPolarization = " << fBeamPolarization << G4endl;
G4cout << " electronPolarization = " << fTargetPolarization << G4endl;
}
theBeamPolarization.InvRotateAz(nInteractionFrame,gamDirection0);
theTargetPolarization.InvRotateAz(nInteractionFrame,gamDirection0);
fBeamPolarization.InvRotateAz(nInteractionFrame, gamDirection0);
fTargetPolarization.InvRotateAz(nInteractionFrame, gamDirection0);
if (verboseLevel>=1) {
G4cout << "----------------------------------------\n";
G4cout << " gammaPolarization = " <<theBeamPolarization<<"\n";
G4cout << " electronPolarization = " <<theTargetPolarization<<"\n";
G4cout << "----------------------------------------\n";
if(fVerboseLevel >= 1)
{
G4cout << "----------------------------------------" << G4endl;
G4cout << " gammaPolarization = " << fBeamPolarization << G4endl;
G4cout << " electronPolarization = " << fTargetPolarization << G4endl;
G4cout << "----------------------------------------" << G4endl;
}
// initialize the polarization transfer matrix
crossSectionCalculator->Initialize(epsilon,E0_m,0.,
theBeamPolarization,
theTargetPolarization,2);
if(gamEnergy1 > lowestSecondaryEnergy) {
fCrossSectionCalculator->Initialize(epsilon, E0_m, 0., fBeamPolarization,
fTargetPolarization, 2);
if(gamEnergy1 > lowestSecondaryEnergy)
{
// in interaction frame
// calculate polarization transfer to the photon (in interaction plane)
finalGammaPolarization = crossSectionCalculator->GetPol2();
if (verboseLevel>=1) {
G4cout << " gammaPolarization1 = " <<finalGammaPolarization<<"\n";
fFinalGammaPolarization = fCrossSectionCalculator->GetPol2();
if(fVerboseLevel >= 1)
{
G4cout << " gammaPolarization1 = " << fFinalGammaPolarization << G4endl;
}
finalGammaPolarization.SetPhoton();
fFinalGammaPolarization.SetPhoton();
// translate polarization into particle reference frame
finalGammaPolarization.RotateAz(nInteractionFrame,gamDirection1);
if (finalGammaPolarization.mag() > 1.+1.e-8){
G4cout<<"ERROR in Polarizaed Compton Scattering !"<<G4endl;
G4cout<<"Polarization of final photon more than 100%"<<G4endl;
G4cout<<finalGammaPolarization<<" mag = "
<<finalGammaPolarization.mag()<<G4endl;
fFinalGammaPolarization.RotateAz(nInteractionFrame, gamDirection1);
if(fFinalGammaPolarization.mag() > 1. + 1.e-8)
{
G4ExceptionDescription ed;
ed << "ERROR in Polarizaed Compton Scattering !\n";
ed << "Polarization of final photon more than 100%.\n";
ed << fFinalGammaPolarization
<< " mag = " << fFinalGammaPolarization.mag() << "\n";
G4Exception("G4PolarizedComptonModel::SampleSecondaries", "pol033",
FatalException, ed);
}
//store polarization vector
fParticleChange->ProposePolarization(finalGammaPolarization);
if (verboseLevel>=1) {
G4cout << " gammaPolarization1 = " <<finalGammaPolarization<<"\n";
G4cout << " GammaDirection1 = " <<gamDirection1<<"\n";
// store polarization vector
fParticleChange->ProposePolarization(fFinalGammaPolarization);
if(fVerboseLevel >= 1)
{
G4cout << " gammaPolarization1 = " << fFinalGammaPolarization << G4endl;
G4cout << " GammaDirection1 = " << gamDirection1 << G4endl;
}
}
//
// kinematic of the scattered electron
//
G4double eKinEnergy = gamEnergy0 - gamEnergy1;
if (eKinEnergy > lowestSecondaryEnergy) {
G4ThreeVector eDirection =
gamEnergy0*gamDirection0 - gamEnergy1*gamDirection1;
if(eKinEnergy > lowestSecondaryEnergy)
{
G4ThreeVector eDirection =
gamEnergy0 * gamDirection0 - gamEnergy1 * gamDirection1;
eDirection = eDirection.unit();
finalElectronPolarization = crossSectionCalculator->GetPol3();
if (verboseLevel>=1) {
G4cout << " electronPolarization1 = "
<<finalElectronPolarization<<"\n";
finalElectronPolarization = fCrossSectionCalculator->GetPol3();
if(fVerboseLevel >= 1)
{
G4cout << " electronPolarization1 = " << finalElectronPolarization
<< G4endl;
}
// transfer into particle reference frame
finalElectronPolarization.RotateAz(nInteractionFrame,eDirection);
if (verboseLevel>=1) {
G4cout << " electronPolarization1 = "
<<finalElectronPolarization<<"\n";
G4cout << " ElecDirection = " <<eDirection<<"\n";
finalElectronPolarization.RotateAz(nInteractionFrame, eDirection);
if(fVerboseLevel >= 1)
{
G4cout << " electronPolarization1 = " << finalElectronPolarization
<< G4endl << " ElecDirection = " << eDirection << G4endl;
}
// create G4DynamicParticle object for the electron.
G4DynamicParticle* aElectron =
new G4DynamicParticle(theElectron,eDirection,eKinEnergy);
//store polarization vector
if (finalElectronPolarization.mag() > 1.+1.e-8){
G4cout<<"ERROR in Polarizaed Compton Scattering !"<<G4endl;
G4cout<<"Polarization of final electron more than 100%"<<G4endl;
G4cout<<finalElectronPolarization<<" mag = "
<<finalElectronPolarization.mag()<<G4endl;
G4DynamicParticle* aElectron =
new G4DynamicParticle(theElectron, eDirection, eKinEnergy);
// store polarization vector
if(finalElectronPolarization.mag() > 1. + 1.e-8)
{
G4ExceptionDescription ed;
ed << "ERROR in Polarized Compton Scattering !\n";
ed << "Polarization of final electron more than 100%.\n";
ed << finalElectronPolarization
<< " mag = " << finalElectronPolarization.mag() << G4endl;
G4Exception("G4PolarizedComptonModel::SampleSecondaries", "pol034",
FatalException, ed);
}
aElectron->SetPolarization(finalElectronPolarization.p1(),
finalElectronPolarization.p2(),
finalElectronPolarization.p3());
finalElectronPolarization.p2(),
finalElectronPolarization.p3());
fvect->push_back(aElectron);
} else {
edep += eKinEnergy;
}
else
{
edep += eKinEnergy;
}
// energy balance
if(edep > 0.0) {
if(edep > 0.0)
{
fParticleChange->ProposeLocalEnergyDeposit(edep);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4PolarizedComptonModel::PrintWarning(const G4DynamicParticle* dp, G4int nloop,
G4double grej, G4double onecos,
G4double phi, const G4String sss) const
void G4PolarizedComptonModel::PrintWarning(const G4DynamicParticle* dp,
G4int nloop, G4double grej,
G4double onecos, G4double phi,
const G4String sss) const
{
G4ExceptionDescription ed;
ed << "Problem of scattering sampling: " << sss << "\n"
<< "Niter= " << nloop << " grej= " << grej << " cos(theta)= "
<< 1.0-onecos << " phi= " << phi << "\n"
<< "Gamma E(MeV)= " << dp->GetKineticEnergy()/MeV
<< " dir= " << dp->GetMomentumDirection()
<< "Niter= " << nloop << " grej= " << grej
<< " cos(theta)= " << 1.0 - onecos << " phi= " << phi << "\n"
<< "Gamma E(MeV)= " << dp->GetKineticEnergy() / MeV
<< " dir= " << dp->GetMomentumDirection()
<< " pol= " << dp->GetPolarization();
G4Exception("G4PolarizedComptonModel::SampleSecondaries","em0044",
JustWarning, ed, "");
G4Exception("G4PolarizedComptonModel::SampleSecondaries", "em0044",
JustWarning, ed, "");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,243 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// File name: G4PolarizedComptonXS
//
// Author: Andreas Schaelicke
//
// Class Description:
// determine the polarization of the final state in a Compton scattering
// process employing the differential cross section by F.W.Lipps & H.A.Tolhoek
// ( Physica 20 (1954) 395 )
// recalculated by P.Starovoitov
#include "G4PolarizedComptonXS.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedComptonXS::G4PolarizedComptonXS()
{
SetYmin(0.);
fPhi0 = 0.;
fPolXS = 0.;
fUnpXS = 0.;
fPhi2 = G4ThreeVector(0., 0., 0.);
fPhi3 = G4ThreeVector(0., 0., 0.);
polxx = polyy = polzz = polxz = polzx = polyz = polzy = polxy = polyx = 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedComptonXS::~G4PolarizedComptonXS() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedComptonXS::Initialize(G4double eps, G4double X,
G4double, // phi
const G4StokesVector& pol0,
const G4StokesVector& pol1, G4int flag)
{
G4double cosT = 1. - (1. / eps - 1.) / X;
if(cosT > 1. + 1.e-8)
cosT = 1.;
else if(cosT < -1. - 1.e-8)
cosT = -1.;
G4double cosT2 = cosT * cosT;
G4double cosT3 = cosT2 * cosT;
G4double sinT2 = 1. - cosT2;
if(sinT2 > 1. + 1.e-8)
sinT2 = 1.;
else if(sinT2 < 0.)
sinT2 = 0.;
G4double sinT = std::sqrt(sinT2);
G4double cos2T = 2. * cosT2 - 1.;
G4double sin2T = 2. * sinT * cosT;
G4double eps2 = sqr(eps);
DefineCoefficients(pol0, pol1);
G4double diffXSFactor = re2 / (4. * X);
// unpolarized Cross Section
fUnpXS = (eps2 + 1. - eps * sinT2) / (2. * eps);
// initial polarization dependence
fPolXS = -sinT2 * pol0.x() + (1. - eps) * sinT * polzx +
((eps2 - 1.) / eps) * cosT * polzz;
fPolXS *= 0.5;
fPhi0 = fUnpXS + fPolXS;
if(flag == 2)
{
// polarization of outgoing photon
G4double phi21 = -sinT2 + 0.5 * (cos2T + 3.) * pol0.x() -
((1. - eps) / eps) * sinT * polzx;
phi21 *= 0.5;
G4double phi22 = cosT * pol0.y() + ((1. - eps) / (2. * eps)) * sinT * polzy;
G4double phi23 = ((eps2 + 1.) / eps) * cosT * pol0.z() -
((1. - eps) / eps) * (eps * cosT2 + 1.) * pol1.z();
phi23 += 0.5 * (1. - eps) * sin2T * pol1.x();
phi23 += (eps - 1.) * (-sinT2 * polxz + sinT * polyy - 0.5 * sin2T * polxx);
phi23 *= 0.5;
fPhi2 = G4ThreeVector(phi21, phi22, phi23);
// polarization of outgoing electron
G4double phi32 = -sinT2 * polxy + ((1. - eps) / eps) * sinT * polyz +
0.5 * (cos2T + 3.) * pol1.y();
phi32 *= 0.5;
G4double phi31 = 0.;
G4double phi31add = 0.;
G4double phi33 = 0.;
G4double phi33add = 0.;
if((1. - eps) > 1.e-12)
{
G4double helpVar = std::sqrt(eps2 - 2. * cosT * eps + 1.);
phi31 = (1. - eps) * (1. + cosT) * sinT * pol0.z();
phi31 +=
(-eps * cosT3 + eps * cosT2 + (eps - 2.) * cosT + eps) * pol1.x();
phi31 += -(eps * cosT2 - eps * cosT + cosT + 1.) * sinT * pol1.z();
phi31 /= 2. * helpVar;
phi31add = -eps * sqr(1. - cosT) * (1. + cosT) * polxx;
phi31add += (1. - eps) * sinT2 * polyy;
phi31add += -(-eps2 + cosT * (cosT * eps - eps + 1.) * eps + eps - 1.) *
sinT * polxz / eps;
phi31add /= 2. * helpVar;
phi33 = ((1. - eps) / eps) *
(-eps * cosT2 + eps * (eps + 1.) * cosT - 1.) * pol0.z();
phi33 += -(eps * cosT2 + (1. - eps) * eps * cosT + 1.) * sinT * pol1.x();
phi33 +=
-(-eps2 * cosT3 + eps * (eps2 - eps + 1.) * cosT2 - cosT + eps2) *
pol1.z() / eps;
phi33 /= -2. * helpVar;
phi33add = (eps * (eps - cosT - 1.) * cosT + 1.) * sinT * polxx;
phi33add += -(-eps2 + cosT * eps + eps - 1.) * sinT2 * polxz;
phi33add += (eps - 1.) * (cosT - eps) * sinT * polyy;
phi33add /= -2. * helpVar;
}
else
{
phi31 = -pol1.z() -
(X - 1.) * std::sqrt(1. - eps) * pol1.x() / std::sqrt(2. * X);
phi31add = -(-X * X * pol1.z() - 2. * X * (2. * pol0.z() - pol1.z()) -
(4. * pol0.x() + 5.) * pol1.z()) *
(1. - eps) / (4. * X);
phi33 = pol1.x() -
(X - 1.) * std::sqrt(1. - eps) * pol1.z() / std::sqrt(2. * X);
phi33add = -(X * X - 2. * X + 4. * pol0.x() + 5.) * (1. - eps) *
pol1.x() / (4. * X);
}
fPhi3 = G4ThreeVector(phi31 + phi31add, phi32, phi33 + phi33add);
}
fUnpXS *= diffXSFactor;
fPolXS *= diffXSFactor;
fPhi0 *= diffXSFactor;
fPhi2 *= diffXSFactor;
fPhi3 *= diffXSFactor;
}
G4double G4PolarizedComptonXS::XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3)
{
G4bool gammaPol2 = !(pol2 == G4StokesVector::ZERO);
G4bool electronPol3 = !(pol3 == G4StokesVector::ZERO);
G4double phi = 0.;
// polarization independent part
phi += fPhi0;
if(gammaPol2)
{
// part depending on the polarization of the final photon
phi += fPhi2 * pol2;
}
if(electronPol3)
{
// part depending on the polarization of the final electron
phi += fPhi3 * pol3;
}
// return cross section.
return phi;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedComptonXS::TotalXSection(G4double /*xmin*/,
G4double /*xmax*/, G4double k0,
const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
G4double k1 = 1. + 2. * k0;
G4double unit = fZ * CLHEP::pi * CLHEP::classic_electr_radius *
CLHEP::classic_electr_radius;
G4double pre = unit / (sqr(k0) * sqr(1. + 2. * k0));
G4double xs_0 = ((k0 - 2.) * k0 - 2.) * sqr(k1) * std::log(k1) +
2. * k0 * (k0 * (k0 + 1.) * (k0 + 8.) + 2.);
G4double xs_pol = (k0 + 1.) * sqr(k1) * std::log(k1) -
2. * k0 * (5. * sqr(k0) + 4. * k0 + 1.);
return pre * (xs_0 / k0 + pol0.p3() * pol1.z() * xs_pol);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedComptonXS::GetPol2()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi2);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedComptonXS::GetPol3()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi3);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedComptonXS::DefineCoefficients(const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
polxx = pol0.x() * pol1.x();
polyy = pol0.y() * pol1.y();
polzz = pol0.z() * pol1.z();
polxz = pol0.x() * pol1.z();
polzx = pol0.z() * pol1.x();
polyz = pol0.y() * pol1.z();
polzy = pol0.z() * pol1.y();
polxy = pol0.x() * pol1.y();
polyx = pol0.y() * pol1.x();
}
@@ -23,74 +23,71 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
//
// File name: G4PolarizedGammaConversion
//
// Author: Karim Laihem based on code by Michel Maire
//
// Creation date: 01.05.2005
//
// Class Description:
// polarized version of G4GammaConversion
//
// polarized version of G4GammaConversion
//
// -----------------------------------------------------------------------------
#include "G4PolarizedGammaConversion.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4PolarizedGammaConversionModel.hh"
#include "G4Electron.hh"
#include "G4EmParameters.hh"
#include "G4Gamma.hh"
#include "G4PhysicalConstants.hh"
#include "G4PolarizedGammaConversionModel.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedGammaConversion::G4PolarizedGammaConversion(const G4String& processName,
G4ProcessType type):G4VEmProcess (processName, type),
isInitialised(false)
G4PolarizedGammaConversion::G4PolarizedGammaConversion(
const G4String& processName, G4ProcessType type)
: G4VEmProcess(processName, type)
, fIsInitialised(false)
{
SetMinKinEnergy(2.0*electron_mass_c2);
SetMinKinEnergy(2.0 * electron_mass_c2);
SetLambdaBinning(220);
//SetMaxKinEnergy(100.0*GeV);
SetProcessSubType(fGammaConversion);
SetBuildTableFlag(true);
SetSecondaryParticle(G4Electron::Electron());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedGammaConversion::~G4PolarizedGammaConversion()
{}
G4PolarizedGammaConversion::~G4PolarizedGammaConversion() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedGammaConversion::ProcessDescription(std::ostream& out) const
{
out << "Polarized model for gamma conversion.\n";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4PolarizedGammaConversion::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Gamma::Gamma());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedGammaConversion::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(!fIsInitialised)
{
fIsInitialised = true;
G4EmParameters* param = G4EmParameters::Instance();
G4double emin = std::max(param->MinKinEnergy(), 2*electron_mass_c2);
G4double emin = std::max(param->MinKinEnergy(), 2. * electron_mass_c2);
G4double emax = param->MaxKinEnergy();
if(!EmModel(0)) { SetEmModel(new G4PolarizedGammaConversionModel()); }
if(!EmModel(0))
{
SetEmModel(new G4PolarizedGammaConversionModel());
}
EmModel(0)->SetLowEnergyLimit(emin);
EmModel(0)->SetHighEnergyLimit(emax);
AddEmModel(1, EmModel(0));
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedGammaConversion::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,122 +23,102 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4PolarizedGammaConversionModel
//
// Author: Karim Laihem
//
// Creation date: 19.04.2005
//
// Modifications:
// 21-08-06 Modified to fit in g4.8.1 framework (A.Schaelicke)
// 19-03-07 Add initialisation of crossSectionCalculator (VI)
//
// Class Description:
//
// Implementation of gamma conversion to e+e- in the field of a nucleus
// including polarization transfer
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Implementation of gamma conversion to e+e- in the field of a nucleus
// including polarization transfer
#include "G4PolarizedGammaConversionModel.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "Randomize.hh"
#include "G4DataVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4PolarizedPairProductionCrossSection.hh"
#include "G4DynamicParticle.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4PolarizedGammaConversionXS.hh"
#include "G4PolarizationHelper.hh"
#include "G4StokesVector.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedGammaConversionModel::G4PolarizedGammaConversionModel(const G4ParticleDefinition* pd,
const G4String& nam)
: G4BetheHeitlerModel(pd,nam), crossSectionCalculator(nullptr)
{
}
G4PolarizedGammaConversionModel::G4PolarizedGammaConversionModel(
const G4ParticleDefinition* pd, const G4String& nam)
: G4BetheHeitlerModel(pd, nam)
, fCrossSectionCalculator(nullptr)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedGammaConversionModel::~G4PolarizedGammaConversionModel()
{
if (crossSectionCalculator) delete crossSectionCalculator;
if(fCrossSectionCalculator)
delete fCrossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedGammaConversionModel::Initialise(const G4ParticleDefinition* pd,
const G4DataVector& dv)
const G4DataVector& dv)
{
G4BetheHeitlerModel::Initialise(pd,dv);
if (!crossSectionCalculator)
crossSectionCalculator = new G4PolarizedPairProductionCrossSection();
G4BetheHeitlerModel::Initialise(pd, dv);
if(!fCrossSectionCalculator)
fCrossSectionCalculator = new G4PolarizedGammaConversionXS();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedGammaConversionModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmin,
G4double maxEnergy)
void G4PolarizedGammaConversionModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp, const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp, G4double tmin, G4double maxEnergy)
{
G4BetheHeitlerModel::SampleSecondaries(vdp, couple, dp, tmin, maxEnergy);
if(vdp && vdp->size()>0) {
if(vdp && vdp->size() > 0)
{
G4double gamEnergy0 = dp->GetKineticEnergy();
G4double lepEnergy1 = (*vdp)[0]->GetKineticEnergy();
G4double sintheta = dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if (sintheta>1.) sintheta=1.;
G4double sintheta =
dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if(sintheta > 1.)
sintheta = 1.;
G4StokesVector beamPol = dp->GetPolarization();
G4StokesVector beamPol = G4StokesVector(dp->GetPolarization());
beamPol.SetPhoton();
// determine interaction plane
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(dp->GetMomentumDirection(),
(*vdp)[0]->GetMomentumDirection());
G4ThreeVector nInteractionFrame = G4PolarizationHelper::GetFrame(
dp->GetMomentumDirection(), (*vdp)[0]->GetMomentumDirection());
// transform polarization into interaction frame
beamPol.InvRotateAz(nInteractionFrame,dp->GetMomentumDirection());
beamPol.InvRotateAz(nInteractionFrame, dp->GetMomentumDirection());
// calulcate polarization transfer
crossSectionCalculator->SetMaterial(GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(),
GetCurrentElement()->GetfCoulomb());
crossSectionCalculator->Initialize(gamEnergy0, lepEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// calculate polarization transfer
fCrossSectionCalculator->SetMaterial(
GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(), GetCurrentElement()->GetfCoulomb());
fCrossSectionCalculator->Initialize(gamEnergy0, lepEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// deterimine final state polarization
G4StokesVector lep1Pol = crossSectionCalculator->GetPol2();
lep1Pol.RotateAz(nInteractionFrame,(*vdp)[0]->GetMomentumDirection());
(*vdp)[0]->SetPolarization(lep1Pol.p1(),
lep1Pol.p2(),
lep1Pol.p3());
// determine final state polarization
G4StokesVector lep1Pol = fCrossSectionCalculator->GetPol2();
lep1Pol.RotateAz(nInteractionFrame, (*vdp)[0]->GetMomentumDirection());
(*vdp)[0]->SetPolarization(lep1Pol.p1(), lep1Pol.p2(), lep1Pol.p3());
size_t num = vdp->size();
if (num!=2) G4cout<<" WARNING "<<num<<" secondaries in polarized pairproduction not supported!\n";
for (size_t i =1; i<num; ++i) {
G4StokesVector lep2Pol = crossSectionCalculator->GetPol3();
lep2Pol.RotateAz(nInteractionFrame,(*vdp)[i]->GetMomentumDirection());
(*vdp)[i]->SetPolarization(lep2Pol.p1(),
lep2Pol.p2(),
lep2Pol.p3());
if(num != 2)
{
G4ExceptionDescription ed;
ed << " WARNING " << num
<< " secondaries in polarized pairproduction not supported!\n";
G4Exception("G4PolarizedGammaConversionModel::SampleSecondaries",
"pol018", JustWarning, ed);
}
for(size_t i = 1; i < num; ++i)
{
G4StokesVector lep2Pol = fCrossSectionCalculator->GetPol3();
lep2Pol.RotateAz(nInteractionFrame, (*vdp)[i]->GetMomentumDirection());
(*vdp)[i]->SetPolarization(lep2Pol.p1(), lep2Pol.p2(), lep2Pol.p3());
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,186 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedGammaConversionXS
//
// Author: Andreas Schaelicke on the base of Karim Laihems code
#include "G4PolarizedGammaConversionXS.hh"
G4double G4PolarizedGammaConversionXS::SCRN[2][19] = {
{ 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0,
60.0, 70.0, 80.0, 90.0, 100.0, 120.0 },
{ 0.0145, 0.0490, 0.1400, 0.3312, 0.6758, 1.126, 1.367, 1.564, 1.731, 1.875,
2.001, 2.114, 2.216, 2.393, 2.545, 2.676, 2.793, 2.897, 3.078 }
};
G4PolarizedGammaConversionXS::G4PolarizedGammaConversionXS()
{
fFinalElectronPolarization = G4StokesVector::ZERO;
fFinalPositronPolarization = G4StokesVector::ZERO;
}
G4PolarizedGammaConversionXS::~G4PolarizedGammaConversionXS() {}
void G4PolarizedGammaConversionXS::Initialize(
G4double aGammaE, G4double aLept0E, G4double sintheta,
const G4StokesVector& beamPol, const G4StokesVector& /*p1*/, G4int /*flag*/)
{
G4double aLept1E = aGammaE - aLept0E;
G4double Stokes_P3 = beamPol.z();
G4double Lept0E = aLept0E / CLHEP::electron_mass_c2 + 1.;
G4double Lept0E2 = Lept0E * Lept0E;
G4double GammaE = aGammaE / CLHEP::electron_mass_c2;
G4double Lept1E = aLept1E / CLHEP::electron_mass_c2 - 1.;
G4double Lept1E2 = Lept1E * Lept1E;
// ******* Gamma Transvers Momentum
G4double TMom = std::sqrt(Lept0E2 - 1.) * sintheta;
G4double u = TMom;
G4double u2 = u * u;
G4double Xsi = 1. / (1. + u2);
G4double Xsi2 = Xsi * Xsi;
G4double delta =
12. * std::pow(fZ, 1. / 3.) * Lept0E * Lept1E * Xsi / (121. * GammaE);
G4double GG = 0.;
if(delta < 0.5)
{
GG = std::log(2. * Lept0E * Lept1E / GammaE) - 2. - fCoul;
}
else if(delta < 120.)
{
for(G4int j = 1; j < 19; ++j)
{
if(SCRN[0][j] >= delta)
{
GG = std::log(2. * Lept0E * Lept1E / GammaE) - 2. - fCoul -
(SCRN[1][j - 1] + (delta - SCRN[0][j - 1]) *
(SCRN[1][j] - SCRN[1][j - 1]) /
(SCRN[0][j] - SCRN[0][j - 1]));
break;
}
}
}
else
{
G4double alpha_sc = (111. * std::pow(fZ, -1. / 3.)) / Xsi;
GG = std::log(alpha_sc) - 2. - fCoul;
}
if(GG < -1.)
GG = -1.;
G4double I_Lepton = (Lept0E2 + Lept1E2) * (3 + 2 * GG) +
2. * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
G4double L_Lepton1 = GammaE *
((Lept0E - Lept1E) * (3. + 2. * GG) +
2 * Lept1E * (1. + 4. * u2 * Xsi2 * GG)) /
I_Lepton;
G4double T_Lepton1 =
4. * GammaE * Lept1E * Xsi * u * (1. - 2. * Xsi) * GG / I_Lepton;
G4double Stokes_S1 = (Stokes_P3 * T_Lepton1);
G4double Stokes_S2 = 0.;
G4double Stokes_S3 = (Stokes_P3 * L_Lepton1);
fFinalElectronPolarization.setX(Stokes_S1);
fFinalElectronPolarization.setY(Stokes_S2);
fFinalElectronPolarization.setZ(Stokes_S3);
if(fFinalElectronPolarization.mag2() > 1.)
{
G4ExceptionDescription ed;
ed << "\t" << fFinalElectronPolarization << "\t GG\t" << GG << "\t delta\t"
<< delta << "\n";
G4Exception("G4PolarizedGammaConversionXS::Initialize", "pol022",
JustWarning, ed);
fFinalElectronPolarization.setX(0.);
fFinalElectronPolarization.setY(0.);
fFinalElectronPolarization.setZ(Stokes_S3);
if(Stokes_S3 > 1.)
fFinalElectronPolarization.setZ(1.);
}
G4double L_Lepton2 = GammaE *
((Lept1E - Lept0E) * (3. + 2. * GG) +
2 * Lept0E * (1. + 4. * u2 * Xsi2 * GG)) /
I_Lepton;
G4double T_Lepton2 =
4. * GammaE * Lept0E * Xsi * u * (1. - 2. * Xsi) * GG / I_Lepton;
G4double Stokes_SS1 = (Stokes_P3 * T_Lepton2);
G4double Stokes_SS2 = 0.;
G4double Stokes_SS3 = (Stokes_P3 * L_Lepton2);
fFinalPositronPolarization.SetPhoton();
fFinalPositronPolarization.setX(Stokes_SS1);
fFinalPositronPolarization.setY(Stokes_SS2);
fFinalPositronPolarization.setZ(Stokes_SS3);
if(fFinalPositronPolarization.mag2() > 1.)
{
G4ExceptionDescription ed;
ed << "\t" << fFinalPositronPolarization << "\t GG\t" << GG << "\t delta\t"
<< delta << "\n";
G4Exception("G4PolarizedGammaConversionXS::Initialize", "pol023",
JustWarning, ed);
}
}
G4double G4PolarizedGammaConversionXS::XSection(const G4StokesVector& /*pol2*/,
const G4StokesVector& /*pol3*/)
{
G4ExceptionDescription ed;
ed << "ERROR dummy routine G4PolarizedGammaConversionXS::XSection "
"called \n";
G4Exception("G4PolarizedGammaConversionXS::Initialize", "pol024",
FatalException, ed);
return 0.;
}
// return expected mean polarisation
G4StokesVector G4PolarizedGammaConversionXS::GetPol2()
{
// electron/positron
return fFinalElectronPolarization;
}
G4StokesVector G4PolarizedGammaConversionXS::GetPol3()
{
// photon
return fFinalPositronPolarization;
}
@@ -0,0 +1,392 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedIonisation
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
#include "G4PolarizedIonisation.hh"
#include "G4Electron.hh"
#include "G4EmParameters.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizedIonisationModel.hh"
#include "G4Positron.hh"
#include "G4ProductionCutsTable.hh"
#include "G4StokesVector.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4UniversalFluctuation.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedIonisation::G4PolarizedIonisation(const G4String& name)
: G4VEnergyLossProcess(name)
, fAsymmetryTable(nullptr)
, fTransverseAsymmetryTable(nullptr)
, fIsElectron(true)
, fIsInitialised(false)
{
verboseLevel = 0;
SetProcessSubType(fIonisation);
SetSecondaryParticle(G4Electron::Electron());
fFlucModel = nullptr;
fEmModel = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedIonisation::~G4PolarizedIonisation() { CleanTables(); }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisation::ProcessDescription(std::ostream& out) const
{
out << "Polarized version of G4eIonisation.\n";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisation::CleanTables()
{
if(fAsymmetryTable)
{
fAsymmetryTable->clearAndDestroy();
delete fAsymmetryTable;
fAsymmetryTable = nullptr;
}
if(fTransverseAsymmetryTable)
{
fTransverseAsymmetryTable->clearAndDestroy();
delete fTransverseAsymmetryTable;
fTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedIonisation::MinPrimaryEnergy(const G4ParticleDefinition*,
const G4Material*,
G4double cut)
{
G4double x = cut;
if(fIsElectron)
{
x += cut;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4PolarizedIonisation::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron() || &p == G4Positron::Positron());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisation::InitialiseEnergyLossProcess(
const G4ParticleDefinition* part, const G4ParticleDefinition*)
{
if(!fIsInitialised)
{
if(part == G4Positron::Positron())
{
fIsElectron = false;
}
if(!FluctModel())
{
SetFluctModel(new G4UniversalFluctuation());
}
fFlucModel = FluctModel();
fEmModel = new G4PolarizedIonisationModel();
SetEmModel(fEmModel);
G4EmParameters* param = G4EmParameters::Instance();
fEmModel->SetLowEnergyLimit(param->MinKinEnergy());
fEmModel->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, fEmModel, fFlucModel);
fIsInitialised = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedIonisation::GetMeanFreePath(const G4Track& track,
G4double step,
G4ForceCondition* cond)
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEnergyLossProcess::GetMeanFreePath(track, step, cond);
if(fAsymmetryTable && fTransverseAsymmetryTable && mfp < DBL_MAX)
{
mfp *= ComputeSaturationFactor(track);
}
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedIonisation::MeanFreePath: " << mfp / mm << " mm "
<< G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedIonisation::PostStepGetPhysicalInteractionLength(
const G4Track& track, G4double step, G4ForceCondition* cond)
{
// save previous values
G4double nLength = theNumberOfInteractionLengthLeft;
G4double iLength = currentInteractionLength;
// *** get unpolarised mean free path from lambda table ***
// this changes theNumberOfInteractionLengthLeft and currentInteractionLength
G4double x = G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
track, step, cond);
G4double x0 = x;
G4double satFact = 1.;
// *** add corrections on polarisation ***
if(fAsymmetryTable && fTransverseAsymmetryTable && x < DBL_MAX)
{
satFact = ComputeSaturationFactor(track);
G4double curLength = currentInteractionLength * satFact;
G4double prvLength = iLength * satFact;
if(nLength > 0.0)
{
theNumberOfInteractionLengthLeft =
std::max(nLength - step / prvLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedIonisation::PostStepGPIL: " << std::setprecision(8)
<< x / mm << " mm;" << G4endl
<< " unpolarized value: " << std::setprecision(8)
<< x0 / mm << " mm." << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedIonisation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
G4StokesVector volPolarization =
polarizationManager->GetVolumePolarization(aLVolume);
G4double factor = 1.0;
if(volumeIsPolarized && !volPolarization.IsZero())
{
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPart = track.GetDynamicParticle();
const G4double energy = aDynamicPart->GetKineticEnergy();
const G4StokesVector polarization = G4StokesVector(track.GetPolarization());
const G4ParticleMomentum direction0 = aDynamicPart->GetMomentumDirection();
if(verboseLevel >= 2)
{
G4cout << "G4PolarizedIonisation::ComputeSaturationFactor: " << G4endl;
G4cout << " Energy(MeV) " << energy / MeV << G4endl;
G4cout << " Direction " << direction0 << G4endl;
G4cout << " Polarization " << polarization << G4endl;
G4cout << " MaterialPol. " << volPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < fAsymmetryTable->size())
{
aVector = (*fAsymmetryTable)(midx);
}
if(midx < fTransverseAsymmetryTable->size())
{
bVector = (*fTransverseAsymmetryTable)(midx);
}
if(aVector && bVector)
{
G4double lAsymmetry = aVector->Value(energy);
G4double tAsymmetry = bVector->Value(energy);
G4double polZZ = polarization.z() * (volPolarization * direction0);
G4double polXX =
polarization.x() *
(volPolarization * G4PolarizationHelper::GetParticleFrameX(direction0));
G4double polYY =
polarization.y() *
(volPolarization * G4PolarizationHelper::GetParticleFrameY(direction0));
factor /= (1. + polZZ * lAsymmetry + (polXX + polYY) * tAsymmetry);
if(verboseLevel >= 2)
{
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry
<< G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ
<< G4endl;
G4cout << " Factor: " << factor << G4endl;
}
}
else
{
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4PolarizedIonisation::ComputeSaturationFactor", "em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisation::BuildPhysicsTable(const G4ParticleDefinition& part)
{
// *** build DEDX and (unpolarized) cross section tables
G4VEnergyLossProcess::BuildPhysicsTable(part);
G4bool master = true;
const G4PolarizedIonisation* masterProcess =
static_cast<const G4PolarizedIonisation*>(GetMasterProcess());
if(masterProcess && masterProcess != this)
{
master = false;
}
if(master)
{
BuildAsymmetryTables(part);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTables();
fAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(fAsymmetryTable);
fTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(fTransverseAsymmetryTable);
const G4ProductionCutsTable* theCoupleTable =
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
for(size_t j = 0; j < numOfCouples; ++j)
{
// get cut value
const G4MaterialCutsCouple* couple =
theCoupleTable->GetMaterialCutsCouple(j);
G4double cut = (*theCoupleTable->GetEnergyCutsVector(1))[j];
// create physics vectors then fill it (same parameters as lambda vector)
G4PhysicsVector* ptrVectorA = LambdaPhysicsVector(couple, cut);
G4PhysicsVector* ptrVectorB = LambdaPhysicsVector(couple, cut);
size_t bins = ptrVectorA->GetVectorLength();
for(size_t i = 0; i < bins; ++i)
{
G4double lowEdgeEnergy = ptrVectorA->Energy(i);
G4double tasm = 0.;
G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, cut, tasm);
ptrVectorA->PutValue(i, asym);
ptrVectorB->PutValue(i, tasm);
}
fAsymmetryTable->insertAt(j, ptrVectorA);
fTransverseAsymmetryTable->insertAt(j, ptrVectorB);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4PolarizedIonisation::ComputeAsymmetry(
G4double energy, const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
if(fIsElectron)
{
lAsymmetry = tAsymmetry = -1.0;
}
// calculate polarized cross section
G4ThreeVector targetPolarization = G4ThreeVector(0., 0., 1.);
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma2 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// calculate transversely polarized cross section
targetPolarization = G4ThreeVector(1., 0., 0.);
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma3 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// calculate unpolarized cross section
targetPolarization = G4ThreeVector();
fEmModel->SetTargetPolarization(targetPolarization);
fEmModel->SetBeamPolarization(targetPolarization);
G4double sigma0 =
fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
// determine asymmetries
if(sigma0 > 0.)
{
lAsymmetry = sigma2 / sigma0 - 1.;
tAsymmetry = sigma3 / sigma0 - 1.;
}
if(std::fabs(lAsymmetry) > 1.)
{
G4ExceptionDescription ed;
ed << "G4PolarizedIonisation::ComputeAsymmetry : E(MeV)= " << energy
<< " lAsymmetry= " << lAsymmetry << " (" << std::fabs(lAsymmetry) - 1.
<< ")";
G4Exception("G4PolarizedIonisation::ComputeAsymmetry", "pol002",
JustWarning, ed);
}
if(std::fabs(tAsymmetry) > 1.)
{
G4ExceptionDescription ed;
ed << "G4PolarizedIonisation::ComputeAsymmetry : E(MeV)= " << energy
<< " tAsymmetry= " << tAsymmetry << " (" << std::fabs(tAsymmetry) - 1.
<< ")";
G4Exception("G4PolarizedIonisation::ComputeAsymmetry", "pol003",
JustWarning, ed);
}
return lAsymmetry;
}
@@ -0,0 +1,349 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedIonisationBhabhaXS
//
// Author: Andreas Schaelicke
//
// Class Description:
// * calculates the differential cross section
// incoming positron Kpl(along positive z direction) scatters at
// an electron Kmn at rest
// * phi denotes the angle between the scattering plane (defined by the
// outgoing electron) and X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
#include "G4PolarizedIonisationBhabhaXS.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedIonisationBhabhaXS::G4PolarizedIonisationBhabhaXS()
: fPhi0(1.)
{
fPhi2 = G4ThreeVector();
fPhi3 = G4ThreeVector();
}
G4PolarizedIonisationBhabhaXS::~G4PolarizedIonisationBhabhaXS() {}
void G4PolarizedIonisationBhabhaXS::Initialize(G4double e, G4double gamma,
G4double /*phi*/,
const G4StokesVector& pol0,
const G4StokesVector& pol1,
G4int flag)
{
SetXmax(1.);
constexpr G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2 = gamma * gamma;
G4double gamma3 = gamma2 * gamma;
G4double gmo = (gamma - 1.);
G4double gmo2 = (gamma - 1.) * (gamma - 1.);
G4double gmo3 = gmo2 * (gamma - 1.);
G4double gpo = (gamma + 1.);
G4double gpo2 = (gamma + 1.) * (gamma + 1.);
G4double gpo3 = gpo2 * (gamma + 1.);
G4double gpo12 = std::sqrt(gpo);
G4double gpo32 = gpo * gpo12;
G4double gpo52 = gpo2 * gpo12;
G4double pref = re2 / (gamma - 1.0);
constexpr G4double sqrttwo = 1.41421356237309504880; // sqrt(2.)
G4double d = std::sqrt(1. / e - 1.);
G4double e2 = e * e;
G4double e3 = e2 * e;
G4double gmo12 = std::sqrt(gmo);
G4double gmo32 = gmo * gmo12;
G4double egmp32 = std::pow(e * (2 + e * gmo) * gpo, (3. / 2.));
G4double e32 = e * std::sqrt(e);
G4bool polarized = (!pol0.IsZero()) || (!pol1.IsZero());
if(flag == 0)
polarized = false;
// Unpolarised part of XS
fPhi0 = e2 * gmo3 / gpo3;
fPhi0 -= 2. * e * gamma * gmo2 / gpo3;
fPhi0 += (3. * gamma2 + 6. * gamma + 4.) * gmo / gpo3;
fPhi0 -= (2. * gamma2 + 4. * gamma + 1.) / (e * gpo2);
fPhi0 += gamma2 / (e2 * (gamma2 - 1.));
fPhi0 *= 0.25;
// Initial state polarisation dependence
if(polarized)
{
G4double xx = -((e * gmo - gamma) *
(-1. - gamma + e * (e * gmo - gamma) * (3. + gamma))) /
(4. * e * gpo3);
G4double yy = (e3 * gmo3 - 2. * e2 * gmo2 * gamma -
gpo * (1. + 2. * gamma) + e * (-2. + gamma2 + gamma3)) /
(4. * e * gpo3);
G4double zz =
((e * gmo - gamma) * (e2 * gmo * (3. + gamma) - e * gamma * (3. + gamma) +
gpo * (1. + 2. * gamma))) /
(4. * e * gpo3);
fPhi0 += xx * pol0.x() * pol1.x() + yy * pol0.y() * pol1.y() +
zz * pol0.z() * pol1.z();
{
G4double xy = 0.;
G4double xz = (d * (e * gmo - gamma) * (-1. + 2. * e * gmo - gamma)) /
(2. * sqrttwo * gpo52);
G4double yx = 0.;
G4double yz = 0.;
G4double zx = xz;
G4double zy = 0.;
fPhi0 += yx * pol0.y() * pol1.x() + xy * pol0.x() * pol1.y();
fPhi0 += zx * pol0.z() * pol1.x() + xz * pol0.x() * pol1.z();
fPhi0 += zy * pol0.z() * pol1.y() + yz * pol0.y() * pol1.z();
}
}
// Final state polarisarion dependence
fPhi2 = G4ThreeVector();
fPhi3 = G4ThreeVector();
if(flag >= 1)
{
// Final Positron Ppl
// initial positron Kpl
if(!pol0.IsZero())
{
G4double xxPplKpl = -((-1. + e) * (e * gmo - gamma) *
(-(gamma * gpo) + e * (-2. + gamma + gamma2))) /
(4. * e2 * gpo *
std::sqrt(gmo * gpo * (-1. + e + gamma - e * gamma) *
(1. + e + gamma - e * gamma)));
G4double xyPplKpl = 0.;
G4double xzPplKpl =
((e * gmo - gamma) * (-1. - gamma + e * gmo * (1. + 2. * gamma))) /
(2. * sqrttwo * e32 * gmo * gpo2 *
std::sqrt(1. + e + gamma - e * gamma));
G4double yxPplKpl = 0.;
G4double yyPplKpl = (gamma2 * gpo + e2 * gmo2 * (3. + gamma) -
e * gmo * (1. + 2. * gamma * (2. + gamma))) /
(4. * e2 * gmo * gpo2);
G4double yzPplKpl = 0.;
G4double zxPplKpl =
((e * gmo - gamma) *
(1. + e * (-1. + 2. * e * gmo - 2. * gamma) * gmo + gamma)) /
(2. * sqrttwo * e * gmo * gpo2 *
std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double zyPplKpl = 0.;
G4double zzPplKpl =
-((e * gmo - gamma) * std::sqrt((1. - e) / (e - e * gamma2 + gpo2)) *
(2. * e2 * gmo2 + gamma + gamma2 - e * (-2. + gamma + gamma2))) /
(4. * e2 * (-1. + gamma2));
fPhi2[0] +=
xxPplKpl * pol0.x() + xyPplKpl * pol0.y() + xzPplKpl * pol0.z();
fPhi2[1] +=
yxPplKpl * pol0.x() + yyPplKpl * pol0.y() + yzPplKpl * pol0.z();
fPhi2[2] +=
zxPplKpl * pol0.x() + zyPplKpl * pol0.y() + zzPplKpl * pol0.z();
}
// initial electron Kmn
if(!pol1.IsZero())
{
G4double xxPplKmn =
((-1. + e) * (e * (-2. + gamma) * gmo + gamma)) /
(4. * e * gpo32 * std::sqrt(1. + e2 * gmo + gamma - 2. * e * gamma));
G4double xyPplKmn = 0.;
G4double xzPplKmn =
(-1. + e * gmo + gmo * gamma) /
(2. * sqrttwo * gpo2 * std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double yxPplKmn = 0.;
G4double yyPplKmn =
(-1. - 2. * gamma + e * gmo * (3. + gamma)) / (4. * e * gpo2);
G4double yzPplKmn = 0.;
G4double zxPplKmn =
(1. + 2. * e2 * gmo2 + gamma + gamma2 +
e * (1. + (3. - 4. * gamma) * gamma)) /
(2. * sqrttwo * gpo2 * std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double zyPplKmn = 0.;
G4double zzPplKmn = -(std::sqrt((1. - e) / (e - e * gamma2 + gpo2)) *
(2. * e2 * gmo2 + gamma + 2. * gamma2 +
e * (2. + gamma - 3. * gamma2))) /
(4. * e * gpo);
fPhi2[0] +=
xxPplKmn * pol1.x() + xyPplKmn * pol1.y() + xzPplKmn * pol1.z();
fPhi2[1] +=
yxPplKmn * pol1.x() + yyPplKmn * pol1.y() + yzPplKmn * pol1.z();
fPhi2[2] +=
zxPplKmn * pol1.x() + zyPplKmn * pol1.y() + zzPplKmn * pol1.z();
}
// Final Electron Pmn
// initial positron Kpl
if(!pol0.IsZero())
{
G4double xxPmnKpl = ((-1. + e * gmo) * (2. + gamma)) /
(4. * gpo * std::sqrt(e * (2. + e * gmo) * gpo));
G4double xyPmnKpl = 0.;
G4double xzPmnKpl = (std::sqrt((-1. + e) / (-2. + e - e * gamma)) *
(e + gamma + e * gamma - 2. * (-1. + e) * gamma2)) /
(2. * sqrttwo * e * gpo2);
G4double yxPmnKpl = 0.;
G4double yyPmnKpl =
(-1. - 2. * gamma + e * gmo * (3. + gamma)) / (4. * e * gpo2);
G4double yzPmnKpl = 0.;
G4double zxPmnKpl =
-((-1. + e) * (1. + 2. * e * gmo) * (e * gmo - gamma)) /
(2. * sqrttwo * e * std::sqrt(-((-1. + e) * (2. + e * gmo))) * gpo2);
G4double zyPmnKpl = 0;
G4double zzPmnKpl = (-2. + 2. * e2 * gmo2 + gamma * (-1. + 2. * gamma) +
e * (-2. + (5. - 3. * gamma) * gamma)) /
(4. * std::sqrt(e * (2. + e * gmo)) * gpo32);
fPhi3[0] +=
xxPmnKpl * pol0.x() + xyPmnKpl * pol0.y() + xzPmnKpl * pol0.z();
fPhi3[1] +=
yxPmnKpl * pol0.x() + yyPmnKpl * pol0.y() + yzPmnKpl * pol0.z();
fPhi3[2] +=
zxPmnKpl * pol0.x() + zyPmnKpl * pol0.y() + zzPmnKpl * pol0.z();
}
// initial electron Kmn
if(!pol1.IsZero())
{
G4double xxPmnKmn = -((2. + e * gmo) * (-1. + e * gmo - gamma) *
(e * gmo - gamma) * (-2. + gamma)) /
(4. * gmo * egmp32);
G4double xyPmnKmn = 0.;
G4double xzPmnKmn =
((e * gmo - gamma) *
std::sqrt((-1. + e + gamma - e * gamma) / (2. + e * gmo)) *
(e + gamma - e * gamma + gamma2)) /
(2. * sqrttwo * e2 * gmo32 * gpo2);
G4double yxPmnKmn = 0.;
G4double yyPmnKmn = (gamma2 * gpo + e2 * gmo2 * (3. + gamma) -
e * gmo * (1. + 2. * gamma * (2. + gamma))) /
(4. * e2 * gmo * gpo2);
G4double yzPmnKmn = 0.;
G4double zxPmnKmn =
-((-1. + e) * (e * gmo - gamma) *
(e * gmo + 2. * e2 * gmo2 - gamma * gpo)) /
(2. * sqrttwo * e2 * std::sqrt(-((-1. + e) * (2. + e * gmo))) * gmo *
gpo2);
G4double zyPmnKmn = 0.;
G4double zzPmnKmn =
((e * gmo - gamma) * std::sqrt(e / ((2. + e * gmo) * gpo)) *
(-(e * (-2. + gamma) * gmo) + 2. * e2 * gmo2 + (-2. + gamma) * gpo)) /
(4. * e2 * (-1. + gamma2));
fPhi3[0] +=
xxPmnKmn * pol1.x() + xyPmnKmn * pol1.y() + xzPmnKmn * pol1.z();
fPhi3[1] +=
yxPmnKmn * pol1.x() + yyPmnKmn * pol1.y() + yzPmnKmn * pol1.z();
fPhi3[2] +=
zxPmnKmn * pol1.x() + zyPmnKmn * pol1.y() + zzPmnKmn * pol1.z();
}
}
fPhi0 *= pref;
fPhi2 *= pref;
fPhi3 *= pref;
}
G4double G4PolarizedIonisationBhabhaXS::XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3)
{
G4double xs = 0.;
xs += fPhi0;
G4bool polarized = (!pol2.IsZero()) || (!pol3.IsZero());
if(polarized)
{
xs += fPhi2 * pol2 + fPhi3 * pol3;
}
return xs;
}
G4double G4PolarizedIonisationBhabhaXS::TotalXSection(
G4double xmin, G4double /*xmax*/, G4double gamma,
const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
// VI: In this model an incorrect G4Exception was used in which
// xmax was compared with 1. In the case of electron this
// value is 0.5, for positrons 1.0. The computation of the
// cross section is left unchanged, so part of integral
// from 0.5 to 1.0 is computed for electrons, which is not
// correct, however, this part is significantly smaller then
// from the interval xmin - 0.5.
G4double xs = 0.;
G4double x = xmin;
constexpr G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2 = gamma * gamma;
G4double gmo2 = (gamma - 1.) * (gamma - 1.);
G4double gpo2 = (gamma + 1.) * (gamma + 1.);
G4double gpo3 = gpo2 * (gamma + 1.);
G4double logMEM = std::log(x);
G4double pref = twopi * re2 / (gamma - 1.0);
// unpolarised XS
G4double sigma0 = 0.;
sigma0 += -gmo2 * (gamma - 1.) * x * x * x / 3. + gmo2 * gamma * x * x;
sigma0 += -(gamma - 1.) * (3. * gamma * (gamma + 2.) + 4.) * x;
sigma0 += (gamma * (gamma * (gamma * (4. * gamma - 1.) - 21.) - 7.) + 13.) /
(3. * (gamma - 1.));
sigma0 /= gpo3;
sigma0 += logMEM * (2. - 1. / gpo2);
sigma0 += gamma2 / ((gamma2 - 1.) * x);
// longitudinal part
G4double sigma2 = 0.;
sigma2 += logMEM * gamma * (gamma + 1.) * (2. * gamma + 1.);
sigma2 += gamma * (7. * gamma * (gamma + 1.) - 2.) / 3.;
sigma2 += -(3. * gamma + 1.) * (gamma2 + gamma - 1.) * x;
sigma2 += (gamma - 1.) * gamma * (gamma + 3.) * x * x;
sigma2 += -gmo2 * (gamma + 3.) * x * x * x / 3.;
sigma2 /= gpo3;
// transverse part
G4double sigma3 = 0.;
sigma3 += 0.5 * (gamma + 1.) * (3. * gamma + 1.) * logMEM;
sigma3 += (gamma * (5. * gamma - 4.) - 13.) / 6.;
sigma3 += 0.5 * (gamma2 + 3.) * x;
sigma3 += -2. * (gamma - 1.) * gamma * x * x;
sigma3 += 2. * gmo2 * x * x * x / 3.;
sigma3 /= gpo3;
// total cross section
xs += pref * (sigma0 + sigma2 * pol0.z() * pol1.z() +
sigma3 * (pol0.x() * pol1.x() + pol0.y() * pol1.y()));
return xs;
}
G4StokesVector G4PolarizedIonisationBhabhaXS::GetPol2()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi2);
}
G4StokesVector G4PolarizedIonisationBhabhaXS::GetPol3()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi3);
}
@@ -0,0 +1,364 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedIonisationModel
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
//
// Class Description:
// Implementation of energy loss and delta-electron production by e+/e-
// (including polarization effects)
#include "G4PolarizedIonisationModel.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4PhysicalConstants.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizedIonisationBhabhaXS.hh"
#include "G4PolarizedIonisationMollerXS.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedIonisationModel::G4PolarizedIonisationModel(
const G4ParticleDefinition* p, const G4String& nam)
: G4MollerBhabhaModel(p, nam)
, fCrossSectionCalculator(nullptr)
{
fBeamPolarization = G4StokesVector::ZERO;
fTargetPolarization = G4StokesVector::ZERO;
fPositronPolarization = G4StokesVector::ZERO;
fElectronPolarization = G4StokesVector::ZERO;
isElectron = (p == theElectron); // necessary due to wrong order in
// G4MollerBhabhaModel constructor!
if(!isElectron)
{
G4cout << " buildBhabha cross section " << isElectron << G4endl;
fCrossSectionCalculator = new G4PolarizedIonisationBhabhaXS();
}
else
{
G4cout << " buildMoller cross section " << isElectron << G4endl;
fCrossSectionCalculator = new G4PolarizedIonisationMollerXS();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedIonisationModel::~G4PolarizedIonisationModel()
{
if(fCrossSectionCalculator)
{
delete fCrossSectionCalculator;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedIonisationModel::ComputeCrossSectionPerElectron(
const G4ParticleDefinition* pd, G4double kinEnergy, G4double cut,
G4double emax)
{
G4double xs = G4MollerBhabhaModel::ComputeCrossSectionPerElectron(
pd, kinEnergy, cut, emax);
G4double factor = 1.;
if(xs != 0.)
{
G4double tmax = MaxSecondaryEnergy(pd, kinEnergy);
tmax = std::min(emax, tmax);
if(std::fabs(cut / emax - 1.) < 1.e-10)
return xs;
if(cut < tmax)
{
G4double xmin = cut / kinEnergy;
G4double xmax = tmax / kinEnergy;
G4double gam = kinEnergy / electron_mass_c2 + 1.0;
G4double crossPol = fCrossSectionCalculator->TotalXSection(
xmin, xmax, gam, fBeamPolarization, fTargetPolarization);
G4double crossUnpol = fCrossSectionCalculator->TotalXSection(
xmin, xmax, gam, G4StokesVector::ZERO, G4StokesVector::ZERO);
if(crossUnpol > 0.)
factor = crossPol / crossUnpol;
}
}
return xs * factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedIonisationModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp, const G4MaterialCutsCouple*,
const G4DynamicParticle* dp, G4double tmin, G4double maxEnergy)
{
// *** obtain and save target and beam polarization ***
G4PolarizationManager* polarizationManager =
G4PolarizationManager::GetInstance();
const G4Track* aTrack = fParticleChange->GetCurrentTrack();
// obtain polarization of the beam
fBeamPolarization = G4StokesVector(dp->GetPolarization());
// obtain polarization of the media
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
const G4bool targetIsPolarized = polarizationManager->IsPolarized(aLVolume);
fTargetPolarization = polarizationManager->GetVolumePolarization(aLVolume);
// transfer target polarization in interaction frame
if(targetIsPolarized)
fTargetPolarization.rotateUz(dp->GetMomentumDirection());
G4double tmax = std::min(maxEnergy, MaxSecondaryKinEnergy(dp));
if(tmin >= tmax)
return;
G4double polL = fBeamPolarization.z() * fTargetPolarization.z();
polL = std::fabs(polL);
G4double polT = fBeamPolarization.x() * fTargetPolarization.x() +
fBeamPolarization.y() * fTargetPolarization.y();
polT = std::fabs(polT);
G4double kineticEnergy = dp->GetKineticEnergy();
G4double energy = kineticEnergy + electron_mass_c2;
G4double totalMomentum =
std::sqrt(kineticEnergy * (energy + electron_mass_c2));
G4double xmin = tmin / kineticEnergy;
G4double xmax = tmax / kineticEnergy;
G4double gam = energy / electron_mass_c2;
G4double gamma2 = gam * gam;
G4double gmo = gam - 1.;
G4double gmo2 = gmo * gmo;
G4double gmo3 = gmo2 * gmo;
G4double gpo = gam + 1.;
G4double gpo2 = gpo * gpo;
G4double gpo3 = gpo2 * gpo;
G4double x, y, q, grej, grej2;
G4double z = 0.;
G4double xs = 0., phi = 0.;
G4ThreeVector direction = dp->GetMomentumDirection();
//(Polarized) Moller (e-e-) scattering
if(isElectron)
{
// *** dice according to polarized cross section
G4double G = ((2.0 * gam - 1.0) / gamma2) * (1. - polT - polL * gam);
G4double H = (sqr(gam - 1.0) / gamma2) *
(1. + polT + polL * ((gam + 3.) / (gam - 1.)));
y = 1.0 - xmax;
grej = 1.0 - G * xmax + xmax * xmax * (H + (1.0 - G * y) / (y * y));
grej2 = 1.0 - G * xmin + xmin * xmin * (H + (1.0 - G * y) / (y * y));
if(grej2 > grej)
grej = grej2;
G4double prefM = gamma2 * classic_electr_radius * classic_electr_radius /
(gmo2 * (gam + 1.0));
grej *= prefM;
do
{
q = G4UniformRand();
x = xmin * xmax / (xmin * (1.0 - q) + xmax * q);
if(fCrossSectionCalculator)
{
fCrossSectionCalculator->Initialize(x, gam, phi, fBeamPolarization,
fTargetPolarization, 1);
xs = fCrossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
z = xs * sqr(x) * 4.;
if(grej < z)
{
G4ExceptionDescription ed;
ed << "WARNING : error in Moller rejection routine! \n"
<< " z = " << z << " grej=" << grej << "\n";
G4Exception("G4PolarizedIonisationModel::SampleSecondaries", "pol019",
JustWarning, ed);
}
}
else
{
G4cout << "No calculator in Moller scattering" << G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
// Bhabha (e+e-) scattering
}
else
{
// *** dice according to polarized cross section
y = xmax * xmax;
grej = 0.;
grej += y * y * gmo3 * (1. + (polL + polT) * (gam + 3.) / gmo);
grej += -2. * xmin * xmin * xmin * gam * gmo2 *
(1. - (polL + polT) * (gam + 3.) / gmo);
grej += y * y * gmo * (3. * gamma2 + 6. * gam + 4.) *
(1. + (polL * (3. * gam + 1.) * (gamma2 + gam + 1.) +
polT * ((gam + 2.) * gamma2 + 1.)) /
(gmo * (3. * gam * (gam + 2.) + 4.)));
grej /= gpo3;
grej += -xmin * (2. * gamma2 + 4. * gam + 1.) *
(1. - gam * (polL * (2. * gam + 1.) + polT) /
(2. * gam * (gam + 2.) + 1.)) /
gpo2;
grej += gamma2 / (gamma2 - 1.);
G4double prefB =
classic_electr_radius * classic_electr_radius / (gam - 1.0);
grej *= prefB;
do
{
q = G4UniformRand();
x = xmin * xmax / (xmin * (1.0 - q) + xmax * q);
if(fCrossSectionCalculator)
{
fCrossSectionCalculator->Initialize(x, gam, phi, fBeamPolarization,
fTargetPolarization, 1);
xs = fCrossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
z = xs * sqr(x) * 4.;
}
else
{
G4cout << "No calculator in Bhabha scattering" << G4endl;
}
if(z > grej)
{
G4ExceptionDescription ed;
ed << "G4PolarizedIonisationModel::SampleSecondaries Warning!\n "
<< "Majorant " << grej << " < " << z << " for x= " << x << G4endl
<< " e+e- (Bhabha) scattering"
<< " at KinEnergy " << kineticEnergy << G4endl;
G4Exception("G4PolarizedIonisationModel::SampleSecondaries", "pol020",
JustWarning, ed);
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
}
// polar asymmetries (due to transverse polarizations)
if(fCrossSectionCalculator)
{
grej = xs * 2.;
do
{
phi = twopi * G4UniformRand();
fCrossSectionCalculator->Initialize(x, gam, phi, fBeamPolarization,
fTargetPolarization, 1);
xs = fCrossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
if(xs > grej)
{
if(isElectron)
{
G4ExceptionDescription ed;
ed << "Majorant " << grej << " < " << xs << " for phi= " << phi
<< "\n"
<< " e-e- (Moller) scattering\n"
<< "PHI DICING\n";
G4Exception("G4PolarizedIonisationModel::SampleSecondaries", "pol021",
JustWarning, ed);
}
else
{
G4ExceptionDescription ed;
ed << "Majorant " << grej << " < " << xs << " for phi= " << phi
<< "\n"
<< " e+e- (Bhabha) scattering\n"
<< "PHI DICING\n";
G4Exception("G4PolarizedIonisationModel::SampleSecondaries", "pol022",
JustWarning, ed);
}
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > xs);
}
// fix kinematics of delta electron
G4double deltaKinEnergy = x * kineticEnergy;
G4double deltaMomentum =
std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0 * electron_mass_c2));
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
(deltaMomentum * totalMomentum);
G4double sint = 1.0 - cost * cost;
if(sint > 0.0)
sint = std::sqrt(sint);
G4ThreeVector deltaDirection(-sint * std::cos(phi), -sint * std::sin(phi),
cost);
deltaDirection.rotateUz(direction);
// primary change
kineticEnergy -= deltaKinEnergy;
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
if(kineticEnergy > DBL_MIN)
{
G4ThreeVector dir =
totalMomentum * direction - deltaMomentum * deltaDirection;
direction = dir.unit();
fParticleChange->SetProposedMomentumDirection(direction);
}
// create G4DynamicParticle object for delta ray
G4DynamicParticle* delta =
new G4DynamicParticle(theElectron, deltaDirection, deltaKinEnergy);
vdp->push_back(delta);
// get interaction frame
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(direction, deltaDirection);
if(fCrossSectionCalculator)
{
// calculate mean final state polarizations
fBeamPolarization.InvRotateAz(nInteractionFrame, direction);
fTargetPolarization.InvRotateAz(nInteractionFrame, direction);
fCrossSectionCalculator->Initialize(x, gam, phi, fBeamPolarization,
fTargetPolarization, 2);
// electron/positron
fPositronPolarization = fCrossSectionCalculator->GetPol2();
fPositronPolarization.RotateAz(nInteractionFrame, direction);
fParticleChange->ProposePolarization(fPositronPolarization);
// electron
fElectronPolarization = fCrossSectionCalculator->GetPol3();
fElectronPolarization.RotateAz(nInteractionFrame, deltaDirection);
delta->SetPolarization(fElectronPolarization.x(), fElectronPolarization.y(),
fElectronPolarization.z());
}
else
{
fPositronPolarization = G4StokesVector::ZERO;
fElectronPolarization = G4StokesVector::ZERO;
}
}
@@ -0,0 +1,291 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedIonisationMollerXS
//
// Author: Andreas Schaelicke
//
// Class Description:
// * calculates the differential cross section
// incoming electron K1(along positive z direction) scatters at an electron
// K2 at rest
// * phi denotes the angle between the scattering plane (defined by the
// outgoing electron) and X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
// * cross section as calculated by P.Starovoitov
#include "G4PolarizedIonisationMollerXS.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedIonisationMollerXS::G4PolarizedIonisationMollerXS()
: fPhi0(0.)
{
SetXmax(.5);
fPhi2 = G4ThreeVector(0., 0., 0.);
fPhi3 = G4ThreeVector(0., 0., 0.);
}
G4PolarizedIonisationMollerXS::~G4PolarizedIonisationMollerXS() {}
void G4PolarizedIonisationMollerXS::Initialize(G4double e, G4double gamma,
G4double /*phi*/,
const G4StokesVector& pol0,
const G4StokesVector& pol1,
G4int flag)
{
constexpr G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2 = gamma * gamma;
G4double gmo = (gamma - 1.);
G4double gmo2 = (gamma - 1.) * (gamma - 1.);
G4double gpo = (gamma + 1.);
G4double pref = gamma2 * re2 / (gmo2 * (gamma + 1.0));
constexpr G4double sqrttwo = 1.41421356237309504880; // sqrt(2.)
G4double f = (-1. + e);
G4double e2 = e * e;
G4double f2 = f * f;
G4bool polarized = (!pol0.IsZero()) || (!pol1.IsZero());
if(flag == 0)
polarized = false;
// Unpolarised part of XS
fPhi0 = gmo2 / gamma2;
fPhi0 += ((1. - 2. * gamma) / gamma2) * (1. / e + 1. / (1. - e));
fPhi0 += 1. / (e * e) + 1. / ((1. - e) * (1. - e));
fPhi0 *= 0.25;
// Initial state polarisarion dependence
if(polarized)
{
G4bool usephi = true;
if(flag <= 1)
usephi = false;
G4double xx = (gamma - f * e * gmo * (3. + gamma)) / (4. * f * e * gamma2);
G4double yy = (-1. + f * e * gmo2 + 2. * gamma) / (4. * f * e * gamma2);
G4double zz = (-(e * gmo * (3. + gamma)) + e2 * gmo * (3. + gamma) +
gamma * (-1. + 2. * gamma)) /
(4. * f * e * gamma2);
fPhi0 += xx * pol0.x() * pol1.x() + yy * pol0.y() * pol1.y() +
zz * pol0.z() * pol1.z();
if(usephi)
{
G4double xy = 0.;
G4double xz = -((-1. + 2. * e) * gmo) /
(2. * sqrttwo * gamma2 * std::sqrt(-((f * e) / gpo)));
G4double yx = 0.;
G4double yz = 0.;
G4double zx = -((-1. + 2. * e) * gmo) /
(2. * sqrttwo * gamma2 * std::sqrt(-((f * e) / gpo)));
G4double zy = 0.;
fPhi0 += yx * pol0.y() * pol1.x() + xy * pol0.x() * pol1.y();
fPhi0 += zx * pol0.z() * pol1.x() + xz * pol0.x() * pol1.z();
fPhi0 += zy * pol0.z() * pol1.y() + yz * pol0.y() * pol1.z();
}
}
// Final state polarisarion dependence
fPhi2 = G4ThreeVector();
fPhi3 = G4ThreeVector();
if(flag >= 1)
{
// Final Electron P1
// initial electron K1
if(!pol0.IsZero())
{
G4double xxP1K1 =
(std::sqrt(gpo / (1. + e2 * gmo + gamma - 2. * e * gamma)) *
(gamma - e * gpo)) /
(4. * e2 * gamma);
G4double xyP1K1 = 0.;
G4double xzP1K1 = (-1. + 2. * e * gamma) /
(2. * sqrttwo * f * gamma *
std::sqrt(e * e2 * (1. + e + gamma - e * gamma)));
G4double yxP1K1 = 0.;
G4double yyP1K1 =
(-gamma2 + e * (-1. + gamma * (2. + gamma))) / (4. * f * e2 * gamma2);
G4double yzP1K1 = 0.;
G4double zxP1K1 = (1. + 2. * e2 * gmo - 2. * e * gamma) /
(2. * sqrttwo * f * e * gamma *
std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double zyP1K1 = 0.;
G4double zzP1K1 =
(-gamma + e * (1. - 2. * e * gmo + gamma)) /
(4. * f * e2 * gamma * std::sqrt(1. - (2. * e) / (f * gpo)));
fPhi2[0] += xxP1K1 * pol0.x() + xyP1K1 * pol0.y() + xzP1K1 * pol0.z();
fPhi2[1] += yxP1K1 * pol0.x() + yyP1K1 * pol0.y() + yzP1K1 * pol0.z();
fPhi2[2] += zxP1K1 * pol0.x() + zyP1K1 * pol0.y() + zzP1K1 * pol0.z();
}
// initial electron K2
if(!pol1.IsZero())
{
G4double xxP1K2 =
((1. + e * (-3. + gamma)) *
std::sqrt(gpo / (1. + e2 * gmo + gamma - 2. * e * gamma))) /
(4. * f * e * gamma);
G4double xyP1K2 = 0.;
G4double xzP1K2 =
(-2. + 2. * e + gamma) / (2. * sqrttwo * f2 * gamma *
std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double yxP1K2 = 0.;
G4double yyP1K2 = (1. - 2. * gamma + e * (-1. + gamma * (2. + gamma))) /
(4. * f2 * e * gamma2);
G4double yzP1K2 = 0.;
G4double zxP1K2 = (2. * e * (1. + e * gmo - 2. * gamma) + gamma) /
(2. * sqrttwo * f2 * gamma *
std::sqrt(e * (1. + e + gamma - e * gamma)));
G4double zyP1K2 = 0.;
G4double zzP1K2 =
(1. - 2. * gamma + e * (-1. - 2. * e * gmo + 3. * gamma)) /
(4. * f2 * e * gamma * std::sqrt(1. - (2. * e) / (f * gpo)));
fPhi2[0] += xxP1K2 * pol1.x() + xyP1K2 * pol1.y() + xzP1K2 * pol1.z();
fPhi2[1] += yxP1K2 * pol1.x() + yyP1K2 * pol1.y() + yzP1K2 * pol1.z();
fPhi2[2] += zxP1K2 * pol1.x() + zyP1K2 * pol1.y() + zzP1K2 * pol1.z();
}
// Final Electron P2
// initial electron K1
if(!pol0.IsZero())
{
G4double xxP2K1 =
(-1. + e + e * gamma) /
(4. * f2 * gamma * std::sqrt((e * (2. + e * gmo)) / gpo));
G4double xyP2K1 = 0.;
G4double xzP2K1 =
-((1. + 2. * f * gamma) * std::sqrt(f / (-2. + e - e * gamma))) /
(2. * sqrttwo * f2 * e * gamma);
G4double yxP2K1 = 0.;
G4double yyP2K1 = (1. - 2. * gamma + e * (-1. + gamma * (2. + gamma))) /
(4. * f2 * e * gamma2);
G4double yzP2K1 = 0.;
G4double zxP2K1 =
(1. + 2. * e * (-2. + e + gamma - e * gamma)) /
(2. * sqrttwo * f * e * std::sqrt(-(f * (2. + e * gmo))) * gamma);
G4double zyP2K1 = 0.;
G4double zzP2K1 =
(std::sqrt((e * gpo) / (2. + e * gmo)) *
(-3. + e * (5. + 2. * e * gmo - 3. * gamma) + 2. * gamma)) /
(4. * f2 * e * gamma);
fPhi3[0] += xxP2K1 * pol0.x() + xyP2K1 * pol0.y() + xzP2K1 * pol0.z();
fPhi3[1] += yxP2K1 * pol0.x() + yyP2K1 * pol0.y() + yzP2K1 * pol0.z();
fPhi3[2] += zxP2K1 * pol0.x() + zyP2K1 * pol0.y() + zzP2K1 * pol0.z();
}
// initial electron K2
if(!pol1.IsZero())
{
G4double xxP2K2 =
(-2. - e * (-3. + gamma) + gamma) /
(4. * f * e * gamma * std::sqrt((e * (2. + e * gmo)) / gpo));
G4double xyP2K2 = 0.;
G4double xzP2K2 =
((-2. * e + gamma) * std::sqrt(f / (-2. + e - e * gamma))) /
(2. * sqrttwo * f * e2 * gamma);
G4double yxP2K2 = 0.;
G4double yyP2K2 =
(-gamma2 + e * (-1. + gamma * (2. + gamma))) / (4. * f * e2 * gamma2);
G4double yzP2K2 = 0.;
G4double zxP2K2 =
(gamma + 2. * e * (-1. + e - e * gamma)) /
(2. * sqrttwo * e2 * std::sqrt(-(f * (2. + e * gmo))) * gamma);
G4double zyP2K2 = 0.;
G4double zzP2K2 = (std::sqrt((e * gpo) / (2. + e * gmo)) *
(-2. + e * (3. + 2. * e * gmo - gamma) + gamma)) /
(4. * f * e2 * gamma);
fPhi3[0] += xxP2K2 * pol1.x() + xyP2K2 * pol1.y() + xzP2K2 * pol1.z();
fPhi3[1] += yxP2K2 * pol1.x() + yyP2K2 * pol1.y() + yzP2K2 * pol1.z();
fPhi3[2] += zxP2K2 * pol1.x() + zyP2K2 * pol1.y() + zzP2K2 * pol1.z();
}
}
fPhi0 *= pref;
fPhi2 *= pref;
fPhi3 *= pref;
}
G4double G4PolarizedIonisationMollerXS::XSection(const G4StokesVector& pol2,
const G4StokesVector& pol3)
{
G4double xs = fPhi0;
G4bool polarized = (!pol2.IsZero()) || (!pol3.IsZero());
if(polarized)
{
xs += fPhi2 * pol2 + fPhi3 * pol3;
}
return xs;
}
G4double G4PolarizedIonisationMollerXS::TotalXSection(
G4double xmin, G4double xmax, G4double gamma, const G4StokesVector& pol0,
const G4StokesVector& pol1)
{
G4double xs = 0.;
G4double x = xmin;
if(xmax != 0.5)
{
G4ExceptionDescription ed;
ed << " warning xmax expected to be 1/2 but is " << xmax << "\n";
G4Exception("G4PolarizedIonisationMollerXS::TotalXSection", "pol020",
JustWarning, ed);
}
constexpr G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2 = gamma * gamma;
G4double gmo2 = (gamma - 1.) * (gamma - 1.);
G4double logMEM = std::log(1. / x - 1.);
G4double pref = twopi * gamma2 * re2 / (gmo2 * (gamma + 1.0));
// unpolarised XS
G4double sigma0 = (gmo2 / gamma2) * (0.5 - x);
sigma0 += ((1. - 2. * gamma) / gamma2) * logMEM;
sigma0 += 1. / x - 1. / (1. - x);
// longitudinal part
G4double sigma2 = ((gamma2 + 2. * gamma - 3.) / gamma2) * (0.5 - x);
sigma2 += (1. / gamma - 2.) * logMEM;
// transverse part
G4double sigma3 = (2. * (1. - gamma) / gamma2) * (0.5 - x);
sigma3 += (1. - 3. * gamma) / (2. * gamma2) * logMEM;
// total cross section
xs += pref * (sigma0 + sigma2 * pol0.z() * pol1.z() +
sigma3 * (pol0.x() * pol1.x() + pol0.y() * pol1.y()));
return xs;
}
G4StokesVector G4PolarizedIonisationMollerXS::GetPol2()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi2);
}
G4StokesVector G4PolarizedIonisationMollerXS::GetPol3()
{
// Note, mean polarization can not contain correlation effects.
return G4StokesVector(1. / fPhi0 * fPhi3);
}
@@ -1,353 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
// File name: G4PolarizedMollerBhabhaModel
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
//
// Creation date: 10.11.2005
//
// Modifications:
//
// 20-08-05, modified interface (A.Schaelicke)
//
// Class Description:
//
// Implementation of energy loss and delta-electron production by e+/e-
// (including polarization effects)
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4PolarizedMollerBhabhaModel.hh"
#include "G4PhysicalConstants.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4ParticleChangeForLoss.hh"
#include "Randomize.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizedBhabhaCrossSection.hh"
#include "G4PolarizedMollerCrossSection.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedMollerBhabhaModel::G4PolarizedMollerBhabhaModel(const G4ParticleDefinition* p,
const G4String& nam)
: G4MollerBhabhaModel(p,nam)
{
// G4cout<<" particle==electron "<<(p==theElectron)<<G4endl;
isElectron=(p==theElectron); // necessary due to wrong order in G4MollerBhabhaModel constructor!
if (p==nullptr) {
}
if (!isElectron) {
G4cout<<" buildBhabha cross section "<<isElectron<<G4endl;
crossSectionCalculator = new G4PolarizedBhabhaCrossSection();
} else {
G4cout<<" buildMoller cross section "<<isElectron<<G4endl;
crossSectionCalculator = new G4PolarizedMollerCrossSection();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedMollerBhabhaModel::~G4PolarizedMollerBhabhaModel()
{
if (crossSectionCalculator) {
delete crossSectionCalculator;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedMollerBhabhaModel::ComputeCrossSectionPerElectron(
const G4ParticleDefinition* pd,
G4double kinEnergy,
G4double cut,
G4double emax)
{
G4double xs =
G4MollerBhabhaModel::ComputeCrossSectionPerElectron(pd,kinEnergy,
cut,emax);
// G4cout<<"calc eIoni xsec "<<xs<<G4endl;
// G4cout<<" "<<kinEnergy<<" "<<cut<<" "<<emax<<G4endl;
G4double factor=1.;
if (xs!=0.) {
// G4cout<<"calc asym"<<G4endl;
G4double tmax = MaxSecondaryEnergy(pd, kinEnergy);
tmax = std::min(emax, tmax);
if (std::fabs(cut/emax-1.)<1.e-10) return xs;
if(cut < tmax) {
G4double xmin = cut/kinEnergy;
G4double xmax = tmax/kinEnergy;
// G4cout<<"calc asym "<<xmin<<","<<xmax<<G4endl;
G4double gam = kinEnergy/electron_mass_c2 + 1.0;
G4double crossPol=crossSectionCalculator->
TotalXSection(xmin,xmax,gam,
theBeamPolarization,
theTargetPolarization);
G4double crossUnpol=crossSectionCalculator->
TotalXSection(xmin,xmax,gam,
G4StokesVector::ZERO,
G4StokesVector::ZERO);
if (crossUnpol>0.) factor=crossPol/crossUnpol;
// G4cout<<" factor="<<factor<<G4endl;
}
}
return xs*factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedMollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* ,
const G4DynamicParticle* dp,
G4double tmin,
G4double maxEnergy)
{
// *** obtain and save target and beam polarization ***
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4Track * aTrack = fParticleChange->GetCurrentTrack();
// obtain polarization of the beam
theBeamPolarization = dp->GetPolarization();
// obtain polarization of the media
G4VPhysicalVolume* aPVolume = aTrack->GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
const G4bool targetIsPolarized = polarizationManger->IsPolarized(aLVolume);
theTargetPolarization = polarizationManger->GetVolumePolarization(aLVolume);
// transfer target polarization in interaction frame
if (targetIsPolarized)
theTargetPolarization.rotateUz(dp->GetMomentumDirection());
G4double tmax = std::min(maxEnergy, MaxSecondaryKinEnergy(dp));
if(tmin >= tmax) return;
// if(tmin > tmax) tmin = tmax;
G4double polL = theBeamPolarization.z()*theTargetPolarization.z();
polL=std::fabs(polL);
G4double polT = theBeamPolarization.x()*theTargetPolarization.x() +
theBeamPolarization.y()*theTargetPolarization.y();
polT=std::fabs(polT);
G4double kineticEnergy = dp->GetKineticEnergy();
G4double energy = kineticEnergy + electron_mass_c2;
G4double totalMomentum = std::sqrt(kineticEnergy*(energy + electron_mass_c2));
G4double xmin = tmin/kineticEnergy;
G4double xmax = tmax/kineticEnergy;
G4double gam = energy/electron_mass_c2;
G4double gamma2 = gam*gam;
G4double gmo = gam - 1.;
G4double gmo2 = gmo*gmo;
G4double gmo3 = gmo2*gmo;
G4double gpo = gam + 1.;
G4double gpo2 = gpo*gpo;
G4double gpo3 = gpo2*gpo;
G4double x, y, q, grej, grej2;
G4double z = 0.;
G4double xs = 0., phi =0.;
G4ThreeVector direction = dp->GetMomentumDirection();
//(Polarized) Moller (e-e-) scattering
if (isElectron) {
// *** dice according to polarized cross section
G4double G = ((2.0*gam - 1.0)/gamma2)*(1. - polT - polL*gam);
G4double H = (sqr(gam - 1.0)/gamma2)*(1. + polT + polL*((gam + 3.)/(gam - 1.)));
y = 1.0 - xmax;
grej = 1.0 - G*xmax + xmax*xmax*(H + (1.0 - G*y)/(y*y));
grej2 = 1.0 - G*xmin + xmin*xmin*(H + (1.0 - G*y)/(y*y));
if (grej2 > grej) grej = grej2;
G4double prefM = gamma2*classic_electr_radius*classic_electr_radius/(gmo2*(gam + 1.0));
grej *= prefM;
do {
q = G4UniformRand();
x = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
if (crossSectionCalculator) {
crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
theTargetPolarization,1);
xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
z=xs*sqr(x)*4.;
if (grej < z) {
G4cout<<"WARNING : error in Moller rejection routine! \n"
<<" z = "<<z<<" grej="<<grej<<"\n";
}
} else {
G4cout<<"No calculator in Moller scattering"<<G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
//Bhabha (e+e-) scattering
} else {
// *** dice according to polarized cross section
y = xmax*xmax;
grej = 0.;
grej += y*y*gmo3*(1. + (polL + polT)*(gam + 3.)/gmo);
grej += -2.*xmin*xmin*xmin*gam*gmo2*(1. - (polL + polT)*(gam + 3.)/gmo);
grej += y*y*gmo*(3.*gamma2 + 6.*gam + 4.)*(1. + (polL*(3.*gam + 1.)*(gamma2 + gam + 1.) + polT*((gam + 2.)*gamma2 + 1.))/(gmo*(3.*gam*(gam + 2.) + 4.)));
grej /= gpo3;
grej += -xmin*(2.*gamma2 + 4.*gam + 1.)*(1. - gam*(polL*(2.*gam + 1.) + polT)/(2.*gam*(gam + 2.) + 1.))/gpo2;
grej += gamma2/(gamma2 - 1.);
G4double prefB = classic_electr_radius*classic_electr_radius/(gam - 1.0);
grej *= prefB;
do {
q = G4UniformRand();
x = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
if (crossSectionCalculator) {
crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
theTargetPolarization,1);
xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
z=xs*sqr(x)*4.;
} else {
G4cout<<"No calculator in Bhabha scattering"<<G4endl;
}
if(z > grej) {
G4cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<G4endl;
G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
<< "Majorant " << grej << " < "
<< z << " for x= " << x<<G4endl
<< " e+e- (Bhabha) scattering"<<" at KinEnergy "<<kineticEnergy<<G4endl;
G4cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
}
//
//
// polar asymmetries (due to transverse polarizations)
//
//
if (crossSectionCalculator) {
// grej*=1./(sqr(x)*sqr(gamma2-1))*sqr(gam*(1+gam));
grej=xs*2.;
do {
phi = twopi * G4UniformRand() ;
crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
theTargetPolarization,1);
xs=crossSectionCalculator->XSection(G4StokesVector::ZERO,
G4StokesVector::ZERO);
if(xs > grej) {
if (isElectron){
G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
<< "Majorant " << grej << " < "
<< xs << " for phi= " << phi<<G4endl
<< " e-e- (Moller) scattering"<< G4endl
<<"PHI DICING"<<G4endl;
} else {
G4cout << "G4PolarizedMollerBhabhaModel::SampleSecondaries Warning! "<<G4endl
<< "Majorant " << grej << " < "
<< xs << " for phi= " << phi<<G4endl
<< " e+e- (Bhabha) scattering"<< G4endl
<<"PHI DICING"<<G4endl;
}
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > xs);
}
// fix kinematics of delta electron
G4double deltaKinEnergy = x * kineticEnergy;
G4double deltaMomentum =
std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
(deltaMomentum * totalMomentum);
G4double sint = 1.0 - cost*cost;
if(sint > 0.0) sint = std::sqrt(sint);
G4ThreeVector deltaDirection(-sint*std::cos(phi),-sint*std::sin(phi), cost) ;
deltaDirection.rotateUz(direction);
// primary change
kineticEnergy -= deltaKinEnergy;
fParticleChange->SetProposedKineticEnergy(kineticEnergy);
if(kineticEnergy > DBL_MIN) {
G4ThreeVector dir = totalMomentum*direction - deltaMomentum*deltaDirection;
direction = dir.unit();
fParticleChange->SetProposedMomentumDirection(direction);
}
// create G4DynamicParticle object for delta ray
G4DynamicParticle* delta = new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
vdp->push_back(delta);
// get interaction frame
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(direction,deltaDirection);
if (crossSectionCalculator) {
// calculate mean final state polarizations
theBeamPolarization.InvRotateAz(nInteractionFrame,direction);
theTargetPolarization.InvRotateAz(nInteractionFrame,direction);
crossSectionCalculator->Initialize(x,gam,phi,theBeamPolarization,
theTargetPolarization,2);
// electron/positron
fPositronPolarization=crossSectionCalculator->GetPol2();
fPositronPolarization.RotateAz(nInteractionFrame,direction);
fParticleChange->ProposePolarization(fPositronPolarization);
// electron
fElectronPolarization=crossSectionCalculator->GetPol3();
fElectronPolarization.RotateAz(nInteractionFrame,deltaDirection);
delta->SetPolarization(fElectronPolarization.x(),
fElectronPolarization.y(),
fElectronPolarization.z());
}
else {
fPositronPolarization=G4ThreeVector();
fElectronPolarization=G4ThreeVector();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1,274 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedMollerCrossSection
//
// Author: Andreas Schaelicke
//
// Creation date: 12.01.2006
//
// Modifications:
// 16-01-06 included cross section as calculated by P.Starovoitov
//
// Class Description:
// * calculates the differential cross section
// incomming electron K1(along positive z direction) scatters at an electron K2 at rest
// * phi denotes the angle between the scattering plane (defined by the
// outgoing electron) and X-axis
// * all stokes vectors refer to spins in the Global System (X,Y,Z)
//
#include "G4PolarizedMollerCrossSection.hh"
#include "G4PhysicalConstants.hh"
G4PolarizedMollerCrossSection::G4PolarizedMollerCrossSection() :
phi0(0.)
{
SetXmax(.5);
}
G4PolarizedMollerCrossSection::~G4PolarizedMollerCrossSection() {}
void G4PolarizedMollerCrossSection::Initialize(
G4double e,
G4double gamma,
G4double /*phi*/,
const G4StokesVector & pol0,
const G4StokesVector & pol1,
G4int flag)
{
G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2=gamma*gamma;
G4double gmo = (gamma - 1.);
G4double gmo2 = (gamma - 1.)*(gamma - 1.);
G4double gpo = (gamma + 1.);
G4double pref = gamma2*re2/(gmo2*(gamma + 1.0));
G4double sqrttwo=std::sqrt(2.);
G4double f = (-1. + e);
G4double e2 = e*e;
G4double f2 = f*f;
// G4double w = e*(1. - e);
G4bool polarized=(!pol0.IsZero())||(!pol1.IsZero());
if (flag==0) polarized=false;
// Unpolarised part of XS
phi0 = 0.;
phi0+= gmo2/gamma2;
phi0+= ((1. - 2.*gamma)/gamma2)*(1./e + 1./(1.-e));
phi0+= 1./(e*e) + 1./((1. - e)*(1. - e));
phi0*=0.25;
// Initial state polarisarion dependence
if (polarized) {
G4double usephi=1.;
if (flag<=1) usephi=0.;
// G4cout<<"Polarized differential moller cross section"<<G4endl;
// G4cout<<"Initial state polarisation contributions"<<G4endl;
// G4cout<<"Diagonal Matrix Elements"<<G4endl;
G4double xx = (gamma - f*e*gmo*(3. + gamma))/(4.*f*e*gamma2);
G4double yy = (-1. + f*e*gmo2 + 2.*gamma)/(4.*f*e*gamma2);
G4double zz = (-(e*gmo*(3. + gamma)) + e2*gmo*(3. + gamma) +
gamma*(-1. + 2.*gamma))/(4.*f*e*gamma2);
phi0 += xx*pol0.x()*pol1.x() + yy*pol0.y()*pol1.y() + zz*pol0.z()*pol1.z();
if (usephi==1.) {
// G4cout<<"Non-diagonal Matrix Elements"<<G4endl;
G4double xy = 0.;
G4double xz = -((-1. + 2.*e)*gmo)/(2.*sqrttwo*gamma2*
std::sqrt(-((f*e)/gpo)));
G4double yx = 0.;
G4double yz = 0.;
G4double zx = -((-1. + 2.*e)*gmo)/(2.*sqrttwo*gamma2*
std::sqrt(-((f*e)/gpo)));
G4double zy = 0.;
phi0+=yx*pol0.y()*pol1.x() + xy*pol0.x()*pol1.y();
phi0+=zx*pol0.z()*pol1.x() + xz*pol0.x()*pol1.z();
phi0+=zy*pol0.z()*pol1.y() + yz*pol0.y()*pol1.z();
}
}
// Final state polarisarion dependence
phi2=G4ThreeVector();
phi3=G4ThreeVector();
if (flag>=1) {
//
// Final Electron P1
//
// initial electron K1
if (!pol0.IsZero()) {
G4double xxP1K1 = (std::sqrt(gpo/(1. + e2*gmo + gamma - 2.*e*gamma))*
(gamma - e*gpo))/(4.*e2*gamma);
G4double xyP1K1 = 0.;
G4double xzP1K1 = (-1. + 2.*e*gamma)/(2.*sqrttwo*f*gamma*
std::sqrt(e*e2*(1. + e + gamma - e*gamma)));
G4double yxP1K1 = 0.;
G4double yyP1K1 = (-gamma2 + e*(-1. + gamma*(2. + gamma)))/(4.*f*e2*gamma2);
G4double yzP1K1 = 0.;
G4double zxP1K1 = (1. + 2.*e2*gmo - 2.*e*gamma)/(2.*sqrttwo*f*e*gamma*
std::sqrt(e*(1. + e + gamma - e*gamma)));
G4double zyP1K1 = 0.;
G4double zzP1K1 = (-gamma + e*(1. - 2.*e*gmo + gamma))/(4.*f*e2*gamma*
std::sqrt(1. - (2.*e)/(f*gpo)));
phi2[0] += xxP1K1*pol0.x() + xyP1K1*pol0.y() + xzP1K1*pol0.z();
phi2[1] += yxP1K1*pol0.x() + yyP1K1*pol0.y() + yzP1K1*pol0.z();
phi2[2] += zxP1K1*pol0.x() + zyP1K1*pol0.y() + zzP1K1*pol0.z();
}
// initial electron K2
if (!pol1.IsZero()) {
G4double xxP1K2 = ((1. + e*(-3. + gamma))*std::sqrt(gpo/(1. + e2*gmo + gamma -
2.*e*gamma)))/(4.*f*e*gamma);
G4double xyP1K2 = 0.;
G4double xzP1K2 = (-2. + 2.*e + gamma)/(2.*sqrttwo*f2*gamma*
std::sqrt(e*(1. + e + gamma - e*gamma)));
G4double yxP1K2 = 0.;
G4double yyP1K2 = (1. - 2.*gamma + e*(-1. + gamma*(2. + gamma)))/(4.*f2*e*gamma2);
G4double yzP1K2 = 0.;
G4double zxP1K2 = (2.*e*(1. + e*gmo - 2.*gamma) + gamma)/(2.*sqrttwo*f2*gamma*
std::sqrt(e*(1. + e + gamma - e*gamma)));
G4double zyP1K2 = 0.;
G4double zzP1K2 = (1. - 2.*gamma + e*(-1. - 2.*e*gmo + 3.*gamma))/
(4.*f2*e*gamma*std::sqrt(1. - (2.*e)/(f*gpo)));
phi2[0] += xxP1K2*pol1.x() + xyP1K2*pol1.y() + xzP1K2*pol1.z();
phi2[1] += yxP1K2*pol1.x() + yyP1K2*pol1.y() + yzP1K2*pol1.z();
phi2[2] += zxP1K2*pol1.x() + zyP1K2*pol1.y() + zzP1K2*pol1.z();
}
//
// Final Electron P2
//
// initial electron K1
if (!pol0.IsZero()) {
G4double xxP2K1 = (-1. + e + e*gamma)/(4.*f2*gamma*
std::sqrt((e*(2. + e*gmo))/gpo));
G4double xyP2K1 = 0.;
G4double xzP2K1 = -((1. + 2.*f*gamma)*std::sqrt(f/(-2. + e - e*gamma)))/
(2.*sqrttwo*f2*e*gamma);
G4double yxP2K1 = 0.;
G4double yyP2K1 = (1. - 2.*gamma + e*(-1. + gamma*(2. + gamma)))/(4.*f2*e*gamma2);
G4double yzP2K1 = 0.;
G4double zxP2K1 = (1. + 2.*e*(-2. + e + gamma - e*gamma))/(2.*sqrttwo*f*e*
std::sqrt(-(f*(2. + e*gmo)))*gamma);
G4double zyP2K1 = 0.;
G4double zzP2K1 = (std::sqrt((e*gpo)/(2. + e*gmo))*
(-3. + e*(5. + 2.*e*gmo - 3.*gamma) + 2.*gamma))/(4.*f2*e*gamma);
phi3[0] += xxP2K1*pol0.x() + xyP2K1*pol0.y() + xzP2K1*pol0.z();
phi3[1] += yxP2K1*pol0.x() + yyP2K1*pol0.y() + yzP2K1*pol0.z();
phi3[2] += zxP2K1*pol0.x() + zyP2K1*pol0.y() + zzP2K1*pol0.z();
}
// initial electron K2
if (!pol1.IsZero()) {
G4double xxP2K2 = (-2. - e*(-3. + gamma) + gamma)/
(4.*f*e*gamma* std::sqrt((e*(2. + e*gmo))/gpo));
G4double xyP2K2 = 0.;
G4double xzP2K2 = ((-2.*e + gamma)*std::sqrt(f/(-2. + e - e*gamma)))/
(2.*sqrttwo*f*e2*gamma);
G4double yxP2K2 = 0.;
G4double yyP2K2 = (-gamma2 + e*(-1. + gamma*(2. + gamma)))/(4.*f*e2*gamma2);
G4double yzP2K2 = 0.;
G4double zxP2K2 = (gamma + 2.*e*(-1. + e - e*gamma))/
(2.*sqrttwo*e2* std::sqrt(-(f*(2. + e*gmo)))*gamma);
G4double zyP2K2 = 0.;
G4double zzP2K2 = (std::sqrt((e*gpo)/(2. + e*gmo))*
(-2. + e*(3. + 2.*e*gmo - gamma) + gamma))/(4.*f*e2*gamma);
phi3[0] += xxP2K2*pol1.x() + xyP2K2*pol1.y() + xzP2K2*pol1.z();
phi3[1] += yxP2K2*pol1.x() + yyP2K2*pol1.y() + yzP2K2*pol1.z();
phi3[2] += zxP2K2*pol1.x() + zyP2K2*pol1.y() + zzP2K2*pol1.z();
}
}
phi0 *= pref;
phi2 *= pref;
phi3 *= pref;
}
G4double G4PolarizedMollerCrossSection::XSection(const G4StokesVector & pol2,
const G4StokesVector & pol3)
{
G4double xs=0.;
xs+=phi0;
G4bool polarized=(!pol2.IsZero())||(!pol3.IsZero());
if (polarized) {
xs+=phi2*pol2 + phi3*pol3;
}
return xs;
}
G4double G4PolarizedMollerCrossSection::TotalXSection(
G4double xmin, G4double xmax, G4double gamma,
const G4StokesVector & pol0,const G4StokesVector & pol1)
{
G4double xs=0.;
G4double x=xmin;
if (xmax != 1./2.) G4cout<<" warning xmax expected to be 1/2 but is "<<xmax<< G4endl;
// re -> electron radius^2;
G4double re2 = classic_electr_radius * classic_electr_radius;
G4double gamma2=gamma*gamma;
G4double gmo2 = (gamma - 1.)*(gamma - 1.);
G4double logMEM = std::log(1./x - 1.);
G4double pref = twopi*gamma2*re2/(gmo2*(gamma + 1.0));
// unpolarise XS
G4double sigma0 = 0.;
sigma0 += (gmo2/gamma2)*(0.5 - x);
sigma0 += ((1. - 2.*gamma)/gamma2)*logMEM;
sigma0 += 1./x - 1./(1. - x);
// longitudinal part
G4double sigma2=0.;
sigma2 += ((gamma2 + 2.*gamma - 3.)/gamma2)*(0.5 - x);
sigma2 += (1./gamma - 2.)*logMEM;
// transverse part
G4double sigma3=0.;
sigma3 += (2.*(1. - gamma)/gamma2)*(0.5 - x);
sigma3 += (1. - 3.*gamma)/(2.*gamma2)*logMEM;
// total cross section
xs+=pref*(sigma0 + sigma2*pol0.z()*pol1.z() + sigma3*(pol0.x()*pol1.x()+pol0.y()*pol1.y()));
return xs;
}
G4StokesVector G4PolarizedMollerCrossSection::GetPol2()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi2;
}
G4StokesVector G4PolarizedMollerCrossSection::GetPol3()
{
// Note, mean polarization can not contain correlation
// effects.
return 1./phi0 * phi3;
}
@@ -1,166 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class file
//
//
// File name: G4PolarizedPEEffectCrossSection
//
// Author: Karim Laihem
//
// Creation date: 15.03.2007
//
// Modifications:
// 19-03-07 Modified to fit in g4.8.2 framework (A.Schaelicke)
//
// Class Description:
//
#include "G4PolarizedPEEffectCrossSection.hh"
#include "G4PhysicalConstants.hh"
using namespace std;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPEEffectCrossSection::G4PolarizedPEEffectCrossSection()
{
cout<<"G4PolarizedPEEffectCrossSection() init\n";
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPEEffectCrossSection::~G4PolarizedPEEffectCrossSection()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPEEffectCrossSection::Initialize(G4double aGammaE,
G4double aLept0E,
G4double sinTheta,
const G4StokesVector & beamPol,
const G4StokesVector & /*p1*/,
G4int /*flag*/)
{
// cout<<"G4PolarizedPEEffectCrossSection::Initialize()\n";
// G4StokesVector PolarizedPhotoElectricEffect::Transfer_G4StokesVector(
// G4double aGammaE, // Incoming Primary Gamma Energy.
// G4ThreeVector aGammaDir, // Incoming Primary Gamma Direction.
// G4StokesVector beamPol, // Incoming Primary Gamma polarization.
// G4double aLept0E, // The Lepton e- of interest Total energy.
// G4ThreeVector aParticl_01_Dir, // The Lepton e- of interest direction.
// G4double cos_aTetha_Angle // The lepton of interest Scattering angle.
// )
// ***********************************************************
// ************ added by Karim Polarization transfer to e- in PhotoelectricEffect.
// ************
// ***********************************************************
G4double Gfactor = aLept0E/electron_mass_c2+1.;
G4double Gfactor_2 = Gfactor * Gfactor;
G4double BETA = sqrt(1. - 1./(Gfactor_2));
G4double Stokes_P3 = beamPol.z() ;
G4double m0_c2 = electron_mass_c2;
G4double Lept0E = aLept0E/m0_c2+1., Lept0E2 = Lept0E * Lept0E ;
G4double GammaE = aGammaE/m0_c2;
// G4double cosTheta = cos_aTetha_Angle;
// G4double sinTheta = sqrt(1- cos_aTetha_Angle * cos_aTetha_Angle);
G4double cosTheta = std::sqrt(1. - sinTheta*sinTheta);
G4double D_Lepton0 = (1./GammaE) * ((2./(GammaE*Lept0E*(1-BETA*cosTheta)))-1.);
G4double I_Lepton0 = 1.0+D_Lepton0;
G4double A_Lepton0 = (Lept0E/(Lept0E+1))*(2.0/(GammaE*Lept0E)
+ BETA*cosTheta
+(2.0/((GammaE*Lept0E2)*(1.0-BETA*cosTheta)))) / I_Lepton0 ;
G4double B_Lepton0 = (Lept0E/(Lept0E+1.0)) * BETA * sinTheta * (2.0/(GammaE*Lept0E*(1-BETA*cosTheta))-1.0)/I_Lepton0;
G4double Stokes_S1 = (Stokes_P3 * B_Lepton0) ;
G4double Stokes_S2 = 0.;
G4double Stokes_S3 = (Stokes_P3 * A_Lepton0) ;
theFinalElectronPolarization.setX(Stokes_S1);
theFinalElectronPolarization.setY(Stokes_S2);
theFinalElectronPolarization.setZ(Stokes_S3);
if((theFinalElectronPolarization.x()*theFinalElectronPolarization.x()
+ theFinalElectronPolarization.y()* theFinalElectronPolarization.y()
+ theFinalElectronPolarization.z()* theFinalElectronPolarization.z())>1)
{
cout<<"Warning: PhotoelectricEffect Problem in pol-transfer photon to lepton:Px2 + Py2 + Pz2 > 1"<<endl;
cout<<"Polarization transfer forced to be total and similar as incoming Photo"<<endl;
// *KL* Surprising if it arrives (never seen it up to now)
theFinalElectronPolarization = beamPol; // suplement de securite
// cout<<"PhotoEffect okay :"
// <<"\t"<<(aLept0E-m0_c2)/aGammaE
// <<"\t"<<aGammaE
// <<"\t"<<aLept0E
// <<"\t"<<cos_aTetha_Angle
// <<"\t"<<beamPol
// <<"\t"<<theFinalElectronPolarization
// <<"\t"<<A_Lepton0
// <<endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedPEEffectCrossSection::XSection(const G4StokesVector & /*pol2*/,
const G4StokesVector & /*pol3*/)
{
cout<<"ERROR dummy routine G4PolarizedPEEffectCrossSection::XSection() called\n";
return 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedPEEffectCrossSection::GetPol2()
{
return theFinalElectronPolarization;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedPEEffectCrossSection::GetPol3()
{
return G4StokesVector();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -1,166 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedPEEffectModel
//
// Author: Andreas Schaelicke & Karim Laihem
//
// Creation date: 22.02.2007
//
// Modifications:
//
// Class Description:
//
// Implementation of Photo electric effect
// including polarization transfer from circularly polarised gammas
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#ifndef NOIONIZATIONAS
#include "G4PolarizedPEEffectModel.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "Randomize.hh"
#include "G4DataVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4PolarizedPEEffectCrossSection.hh"
#include "G4PolarizationHelper.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPEEffectModel::G4PolarizedPEEffectModel(const G4ParticleDefinition*,
const G4String& nam)
: G4PEEffectFluoModel(nam),
crossSectionCalculator(nullptr),
verboseLevel(0)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedPEEffectModel::~G4PolarizedPEEffectModel()
{
if (crossSectionCalculator) delete crossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedPEEffectModel::Initialise(const G4ParticleDefinition* pd,
const G4DataVector& dv)
{
G4PEEffectFluoModel::Initialise(pd,dv);
if (!crossSectionCalculator)
crossSectionCalculator = new G4PolarizedPEEffectCrossSection();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPEEffectModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmin,
G4double maxEnergy)
{
// std::vector<G4DynamicParticle*>* vdp =
G4PEEffectFluoModel::SampleSecondaries(vdp,couple, dp, tmin, maxEnergy);
if (verboseLevel >= 1) {
G4cout << "G4PolarizedPEEffectModel::SampleSecondaries" << G4endl;
}
if(vdp && vdp->size()>0) {
G4double gamEnergy0 = dp->GetKineticEnergy();
G4double lepEnergy1 = (*vdp)[0]->GetKineticEnergy();
G4double sintheta = dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if (sintheta>1.) sintheta=1.;
G4StokesVector beamPol = dp->GetPolarization();
beamPol.SetPhoton();
// G4cout<<" beamPol "<<beamPol<<G4endl;
// determine interaction plane
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(dp->GetMomentumDirection(),
(*vdp)[0]->GetMomentumDirection());
// G4cout<<" nInteractionFrame = "<<nInteractionFrame<<G4endl;
if (dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag()<1.e-10) {
// G4cout<<" nInteractionFrame not well defined "<<G4endl;
// G4cout<<" choosing random interaction frame "<<G4endl;
nInteractionFrame = G4PolarizationHelper::GetRandomFrame(dp->GetMomentumDirection());
// G4cout<<"new nInteractionFrame = "<<nInteractionFrame<<G4endl;
}
/*
else {
G4ThreeVector mom1=dp->GetMomentumDirection();
G4ThreeVector mom2=(*vdp)[0]->GetMomentumDirection();
G4cout<<" mom1 = "<<mom1<<G4endl;
G4cout<<" mom2 = "<<mom2<<G4endl;
G4ThreeVector x=mom1.cross(mom2);
G4cout<<" mom1 x mom2 = "<<x<<" "<<x.mag()<<G4endl;
G4cout<<" norm = "<<(1./x.mag()*x)<<" "<<G4endl;
}
*/
// transform polarization into interaction frame
beamPol.InvRotateAz(nInteractionFrame,dp->GetMomentumDirection());
// calulcate polarization transfer
crossSectionCalculator->SetMaterial(GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(),
GetCurrentElement()->GetfCoulomb());
crossSectionCalculator->Initialize(gamEnergy0, lepEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// deterimine final state polarization
G4StokesVector lep1Pol = crossSectionCalculator->GetPol2();
// G4cout<<" lepPol "<<lep1Pol<<G4endl;
lep1Pol.RotateAz(nInteractionFrame,(*vdp)[0]->GetMomentumDirection());
(*vdp)[0]->SetPolarization(lep1Pol.p1(),
lep1Pol.p2(),
lep1Pol.p3());
// G4cout<<" lepPol "<<lep1Pol<<G4endl;
size_t num = vdp->size();
if (num!=1) G4cout<<" WARNING "<<num<<" secondaries in polarized photo electric effect not supported!\n";
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif //NOIONIZATIONAS
@@ -1,205 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4PolarizedPairProductionCrossSection
//
// Author: Andreas Schaelicke on the base of Karim Laihems code
//
// Creation date: 16.08.2006
//
#include "G4PolarizedPairProductionCrossSection.hh"
#include "G4PhysicalConstants.hh"
G4bool G4PolarizedPairProductionCrossSection::scrnInitialized=false;
G4double G4PolarizedPairProductionCrossSection::SCRN [3][20];
// screening function lookup table;
void G4PolarizedPairProductionCrossSection::InitializeMe()
{
if (!scrnInitialized) {
SCRN [1][1]= 0.5 ; SCRN [2][1] = 0.0145;
SCRN [1][2]= 1.0 ; SCRN [2][2] = 0.0490;
SCRN [1][3]= 2.0 ; SCRN [2][3] = 0.1400;
SCRN [1][4]= 4.0 ; SCRN [2][4] = 0.3312;
SCRN [1][5]= 8.0 ; SCRN [2][5] = 0.6758;
SCRN [1][6]= 15.0 ; SCRN [2][6] = 1.126;
SCRN [1][7]= 20.0 ; SCRN [2][7] = 1.367;
SCRN [1][8]= 25.0 ; SCRN [2][8] = 1.564;
SCRN [1][9]= 30.0 ; SCRN [2][9] = 1.731;
SCRN [1][10]= 35.0 ; SCRN [2][10]= 1.875;
SCRN [1][11]= 40.0 ; SCRN [2][11]= 2.001;
SCRN [1][12]= 45.0 ; SCRN [2][12]= 2.114;
SCRN [1][13]= 50.0 ; SCRN [2][13]= 2.216;
SCRN [1][14]= 60.0 ; SCRN [2][14]= 2.393;
SCRN [1][15]= 70.0 ; SCRN [2][15]= 2.545;
SCRN [1][16]= 80.0 ; SCRN [2][16]= 2.676;
SCRN [1][17]= 90.0 ; SCRN [2][17]= 2.793;
SCRN [1][18]= 100.0 ; SCRN [2][18]= 2.897;
SCRN [1][19]= 120.0 ; SCRN [2][19]= 3.078;
scrnInitialized=true;
}
}
G4PolarizedPairProductionCrossSection::G4PolarizedPairProductionCrossSection()
{
InitializeMe();
}
void G4PolarizedPairProductionCrossSection::Initialize(G4double aGammaE,
G4double aLept0E,
G4double sintheta,
const G4StokesVector & beamPol,
const G4StokesVector & /*p1*/,
G4int /*flag*/)
{
G4double aLept1E = aGammaE - aLept0E;
G4double Stokes_P3 = beamPol.z() ;
// **************************************************************************
G4double m0_c2 = electron_mass_c2;
G4double Lept0E = aLept0E/m0_c2+1., Lept0E2 = Lept0E * Lept0E ;
G4double GammaE = aGammaE/m0_c2;
G4double Lept1E = aLept1E/m0_c2-1., Lept1E2 = Lept1E * Lept1E ;
// const G4Element* theSelectedElement = theModel->SelectedAtom();
// ******* Gamma Transvers Momentum
G4double TMom = std::sqrt(Lept0E2 -1.)* sintheta, u = TMom , u2 =u * u ;
G4double Xsi = 1./(1.+u2) , Xsi2 = Xsi * Xsi ;
// G4double theZ = theSelectedElement->GetZ();
// G4double fCoul = theSelectedElement->GetfCoulomb();
G4double delta = 12. * std::pow(theZ, 1./3.) * Lept0E * Lept1E * Xsi / (121. * GammaE);
G4double GG=0.;
if(delta < 0.5) {
GG = std::log(2.* Lept0E * Lept1E / GammaE) - 2. - fCoul;
}
else if ( delta < 120.) {
for (G4int j=2; j<=19; j++) {
if(SCRN[1][j] >= delta) {
GG =std::log(2. * Lept0E * Lept1E / GammaE) - 2. - fCoul
-(SCRN[2][j-1]+(delta-SCRN[1][j-1])*(SCRN[2][j]-SCRN[2][j-1])/(SCRN[1][j]-SCRN[1][j-1]));
break;
}
}
}
else {
G4double alpha_sc = (111. * std::pow(theZ, -1./3.)) / Xsi;
GG = std::log(alpha_sc)- 2. - fCoul;
}
if(GG<-1.) GG=-1.; // *KL* do we need this ?!
G4double I_Lepton = (Lept0E2 + Lept1E2)*(3+2*GG) + 2. * Lept0E * Lept1E * (1. + 4. * u2 * Xsi2 * GG);
// G4double D_Lepton1 = -8 * Lept0E * Lept1E * u2 * Xsi2 * GG / I_Lepton;
G4double L_Lepton1 = GammaE * ((Lept0E - Lept1E) * (3. + 2. * GG)+2 * Lept1E * (1. + 4. * u2 * Xsi2 * GG))/I_Lepton;
G4double T_Lepton1 = 4. * GammaE * Lept1E * Xsi * u * (1. - 2. * Xsi) * GG / I_Lepton ;
G4double Stokes_S1 = (Stokes_P3 * T_Lepton1) ;
G4double Stokes_S2 = 0.;
G4double Stokes_S3 = (Stokes_P3 * L_Lepton1) ;
theFinalElectronPolarization.setX(Stokes_S1);
theFinalElectronPolarization.setY(Stokes_S2);
theFinalElectronPolarization.setZ(Stokes_S3);
if(theFinalElectronPolarization.mag2()>1.) {
G4cout<<" WARNING in pol-conv theFinalElectronPolarization \n";
G4cout
<<"\t"<<theFinalElectronPolarization
<<"\t GG\t"<<GG
<<"\t delta\t"<<delta
<<G4endl;
theFinalElectronPolarization.setX(0.);
theFinalElectronPolarization.setY(0.);
theFinalElectronPolarization.setZ(Stokes_S3);
if(Stokes_S3>1.) theFinalElectronPolarization.setZ(1.);
}
G4double L_Lepton2 = GammaE * ((Lept1E - Lept0E) * (3. + 2. * GG)+2 * Lept0E * (1. + 4. * u2 * Xsi2 * GG))/I_Lepton;
G4double T_Lepton2 = 4. * GammaE * Lept0E * Xsi * u * (1. - 2. * Xsi) * GG / I_Lepton ;
G4double Stokes_SS1 = (Stokes_P3 * T_Lepton2) ;
G4double Stokes_SS2 = 0.;
G4double Stokes_SS3 = (Stokes_P3 * L_Lepton2) ;
theFinalPositronPolarization.SetPhoton();
theFinalPositronPolarization.setX(Stokes_SS1);
theFinalPositronPolarization.setY(Stokes_SS2);
theFinalPositronPolarization.setZ(Stokes_SS3);
if(theFinalPositronPolarization.mag2()>1.) {
G4cout<<" WARNING in pol-conv theFinalPositronPolarization \n";
G4cout
<<"\t"<<theFinalPositronPolarization
<<"\t GG\t"<<GG
<<"\t delta\t"<<delta
<<G4endl;
}
}
G4double G4PolarizedPairProductionCrossSection::XSection(const G4StokesVector & /*pol2*/,
const G4StokesVector & /*pol3*/)
{
G4cout<<"ERROR dummy routine G4PolarizedPairProductionCrossSection::XSection called \n";
return 0.;
}
// return expected mean polarisation
G4StokesVector G4PolarizedPairProductionCrossSection::GetPol2()
{
// electron/positron
return theFinalElectronPolarization;
}
G4StokesVector G4PolarizedPairProductionCrossSection::GetPol3()
{
// photon
return theFinalPositronPolarization;;
}
@@ -23,64 +23,54 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//------------------ G4PolarizedPhotoElectricEffect physics process --
//
//
// -----------------------------------------------------------------------------
//------------------ G4PolarizedPhotoElectric physics process --
#include "G4PolarizedPhotoElectricEffect.hh"
#include "G4PolarizedPEEffectModel.hh"
#include "G4PolarizedPhotoElectric.hh"
#include "G4PolarizedPhotoElectricModel.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "G4EmParameters.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4PolarizedPhotoElectricEffect::G4PolarizedPhotoElectricEffect(
const G4String& processName, G4ProcessType type)
: G4VEmProcess (processName, type), isInitialised(false)
G4PolarizedPhotoElectric::G4PolarizedPhotoElectric(const G4String& processName,
G4ProcessType type)
: G4VEmProcess(processName, type)
, fIsInitialised(false)
{
SetBuildTableFlag(false);
SetSecondaryParticle(G4Electron::Electron());
SetProcessSubType(fPhotoElectricEffect);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPhotoElectricEffect::~G4PolarizedPhotoElectricEffect()
{}
G4PolarizedPhotoElectric::~G4PolarizedPhotoElectric() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPhotoElectric::ProcessDescription(std::ostream& out) const
{
out << "Polarized model for photo-electric effect.\n";
G4bool
G4PolarizedPhotoElectricEffect::IsApplicable(const G4ParticleDefinition& p)
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4PolarizedPhotoElectric::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Gamma::Gamma());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4PolarizedPhotoElectricEffect::InitialiseProcess(const G4ParticleDefinition*)
void G4PolarizedPhotoElectric::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(!EmModel()) { SetEmModel(new G4PolarizedPEEffectModel); }
if(!fIsInitialised)
{
fIsInitialised = true;
if(!EmModel())
{
SetEmModel(new G4PolarizedPhotoElectricModel);
}
G4EmParameters* param = G4EmParameters::Instance();
EmModel()->SetLowEnergyLimit(param->MinKinEnergy());
EmModel()->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel());
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPhotoElectricEffect::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,128 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// Geant4 Class file
//
// File name: G4PolarizedPhotoElectricModel
//
// Author: Andreas Schaelicke & Karim Laihem
//
// Class Description:
// Implementation of Photo electric effect
// including polarization transfer from circularly polarised gammas
#include "G4PolarizedPhotoElectricModel.hh"
#include "G4DataVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizedPhotoElectricXS.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPhotoElectricModel::G4PolarizedPhotoElectricModel(
const G4ParticleDefinition*, const G4String& nam)
: G4PEEffectFluoModel(nam)
, fCrossSectionCalculator(nullptr)
, fVerboseLevel(0)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4PolarizedPhotoElectricModel::~G4PolarizedPhotoElectricModel()
{
if(fCrossSectionCalculator)
delete fCrossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4PolarizedPhotoElectricModel::Initialise(const G4ParticleDefinition* pd,
const G4DataVector& dv)
{
G4PEEffectFluoModel::Initialise(pd, dv);
if(!fCrossSectionCalculator)
fCrossSectionCalculator = new G4PolarizedPhotoElectricXS();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPhotoElectricModel::SampleSecondaries(
std::vector<G4DynamicParticle*>* vdp, const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp, G4double tmin, G4double maxEnergy)
{
G4PEEffectFluoModel::SampleSecondaries(vdp, couple, dp, tmin, maxEnergy);
if(fVerboseLevel >= 1)
{
G4cout << "G4PolarizedPhotoElectricModel::SampleSecondaries" << G4endl;
}
if(vdp && !vdp->empty())
{
G4double gamEnergy0 = dp->GetKineticEnergy();
G4double lepEnergy1 = (*vdp)[0]->GetKineticEnergy();
G4double sintheta =
dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if(sintheta > 1.)
sintheta = 1.;
G4StokesVector beamPol = G4StokesVector(dp->GetPolarization());
beamPol.SetPhoton();
// determine interaction plane
G4ThreeVector nInteractionFrame = G4PolarizationHelper::GetFrame(
dp->GetMomentumDirection(), (*vdp)[0]->GetMomentumDirection());
if(dp->GetMomentumDirection()
.cross((*vdp)[0]->GetMomentumDirection())
.mag() < 1.e-10)
{
nInteractionFrame =
G4PolarizationHelper::GetRandomFrame(dp->GetMomentumDirection());
}
// transform polarization into interaction frame
beamPol.InvRotateAz(nInteractionFrame, dp->GetMomentumDirection());
// calulcate polarization transfer
fCrossSectionCalculator->SetMaterial(
GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(), GetCurrentElement()->GetfCoulomb());
fCrossSectionCalculator->Initialize(gamEnergy0, lepEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// determine final state polarization
G4StokesVector lep1Pol = fCrossSectionCalculator->GetPol2();
lep1Pol.RotateAz(nInteractionFrame, (*vdp)[0]->GetMomentumDirection());
(*vdp)[0]->SetPolarization(lep1Pol.p1(), lep1Pol.p2(), lep1Pol.p3());
if(vdp->size() != 1)
{
G4ExceptionDescription ed;
ed << " WARNING " << vdp->size()
<< " secondaries in polarized photo electric effect not supported!\n";
G4Exception("G4PolarizedPhotoElectricModel::SampleSecondaries", "pol024",
JustWarning, ed);
}
}
}
@@ -0,0 +1,120 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Geant4 Class file
//
// File name: G4PolarizedPhotoElectricXS
//
// Author: Karim Laihem
#include "G4PolarizedPhotoElectricXS.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPhotoElectricXS::G4PolarizedPhotoElectricXS()
{
fFinalElectronPolarization = G4StokesVector::ZERO;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedPhotoElectricXS::~G4PolarizedPhotoElectricXS() {}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedPhotoElectricXS::Initialize(G4double aGammaE, G4double aLept0E,
G4double sinTheta,
const G4StokesVector& beamPol,
const G4StokesVector& /*p1*/,
G4int /*flag*/)
{
// Polarization transfer to e- in PhotoelectricEffect.
G4double Gfactor = aLept0E / CLHEP::electron_mass_c2 + 1.;
G4double Gfactor_2 = Gfactor * Gfactor;
G4double beta = std::sqrt(1. - 1. / (Gfactor_2));
G4double Stokes_P3 = beamPol.z();
G4double Lept0E = aLept0E / CLHEP::electron_mass_c2 + 1.;
G4double Lept0E2 = Lept0E * Lept0E;
G4double GammaE = aGammaE / CLHEP::electron_mass_c2;
G4double cosTheta = std::sqrt(1. - sinTheta * sinTheta);
G4double I_Lepton0 =
1.0 +
(1. / GammaE) * ((2. / (GammaE * Lept0E * (1 - beta * cosTheta))) - 1.);
G4double A_Lepton0 =
(Lept0E / (Lept0E + 1)) *
(2.0 / (GammaE * Lept0E) + beta * cosTheta +
(2.0 / ((GammaE * Lept0E2) * (1.0 - beta * cosTheta)))) /
I_Lepton0;
G4double B_Lepton0 = (Lept0E / (Lept0E + 1.0)) * beta * sinTheta *
(2.0 / (GammaE * Lept0E * (1 - beta * cosTheta)) - 1.0) /
I_Lepton0;
fFinalElectronPolarization.setX(Stokes_P3 * B_Lepton0);
fFinalElectronPolarization.setY(0.);
fFinalElectronPolarization.setZ(Stokes_P3 * A_Lepton0);
if((fFinalElectronPolarization.x() * fFinalElectronPolarization.x() +
fFinalElectronPolarization.y() * fFinalElectronPolarization.y() +
fFinalElectronPolarization.z() * fFinalElectronPolarization.z()) > 1.)
{
G4ExceptionDescription ed;
ed << "Warning: PhotoelectricEffect Problem in pol-transfer photon to "
"lepton:Px2 + Py2 + Pz2 > 1\n";
ed << "Polarization transfer forced to be total and similar as incoming "
"Photo\n";
G4Exception("G4PolarizedPhotoElectricXS::Initialize", "pol023", JustWarning,
ed);
fFinalElectronPolarization = beamPol; // to be safe
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedPhotoElectricXS::XSection(const G4StokesVector& /*pol2*/,
const G4StokesVector& /*pol3*/)
{
G4ExceptionDescription ed;
ed << "ERROR dummy routine G4PolarizedPhotoElectricXS::XSection() "
"called\n";
G4Exception("G4PolarizedPhotoElectricXS::XSection", "pol024", FatalException,
ed);
return 0.;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedPhotoElectricXS::GetPol2()
{
return fFinalElectronPolarization;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4StokesVector G4PolarizedPhotoElectricXS::GetPol3()
{
return G4StokesVector();
}
@@ -23,185 +23,196 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 Class file
//
// Geant4 Class file
//
// File name: G4StokesVector
//
// Author: Andreas Schaelicke
//
// Creation date: 01.05.2005
//
// Modifications:
//
// Class Description:
//
// Provides Stokesvector representation employed in polarized
// processes.
//
// Provides Stokes vector representation employed in polarized processes.
#include "G4StokesVector.hh"
#include "G4PolarizationHelper.hh"
#include "G4PhysicalConstants.hh"
#include "Randomize.hh"
const G4StokesVector G4StokesVector::ZERO=G4ThreeVector(0.,0.,0.);
const G4StokesVector G4StokesVector::P1=G4ThreeVector(1.,0.,0.);
const G4StokesVector G4StokesVector::P2=G4ThreeVector(0.,1.,0.);
const G4StokesVector G4StokesVector::P3=G4ThreeVector(0.,0.,1.);
const G4StokesVector G4StokesVector::M1=G4ThreeVector(-1.,0.,0.);
const G4StokesVector G4StokesVector::M2=G4ThreeVector(0.,-1.,0.);
const G4StokesVector G4StokesVector::M3=G4ThreeVector(0.,0.,-1.);
const G4StokesVector G4StokesVector::ZERO =
G4StokesVector(G4ThreeVector(0., 0., 0.));
const G4StokesVector G4StokesVector::P1 =
G4StokesVector(G4ThreeVector(1., 0., 0.));
const G4StokesVector G4StokesVector::P2 =
G4StokesVector(G4ThreeVector(0., 1., 0.));
const G4StokesVector G4StokesVector::P3 =
G4StokesVector(G4ThreeVector(0., 0., 1.));
const G4StokesVector G4StokesVector::M1 =
G4StokesVector(G4ThreeVector(-1., 0., 0.));
const G4StokesVector G4StokesVector::M2 =
G4StokesVector(G4ThreeVector(0., -1., 0.));
const G4StokesVector G4StokesVector::M3 =
G4StokesVector(G4ThreeVector(0., 0., -1.));
G4StokesVector::G4StokesVector()
: G4ThreeVector(),isPhoton(false)
{
}
: G4ThreeVector()
, fIsPhoton(false)
{}
G4StokesVector::G4StokesVector(const G4ThreeVector & v)
: G4ThreeVector(v),isPhoton(false)
{
}
G4StokesVector::G4StokesVector(const G4ThreeVector& v)
: G4ThreeVector(v)
, fIsPhoton(false)
{}
G4bool G4StokesVector::IsZero() const
{
return *this==ZERO;
}
G4bool G4StokesVector::IsZero() const { return *this == ZERO; }
void G4StokesVector::RotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection)
void G4StokesVector::RotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection)
{
G4ThreeVector yParticleFrame =
G4ThreeVector yParticleFrame =
G4PolarizationHelper::GetParticleFrameY(particleDirection);
G4double cosphi=yParticleFrame*nInteractionFrame;
if (cosphi>(1.+1.e-8) || cosphi<(-1.-1.e-8)) {
G4cout<<" warning G4StokesVector::RotateAz cosphi>1 or cosphi<-1\n"
<<" cosphi="<<cosphi<<"\n"
<<" zAxis="<<particleDirection<<" ("<<particleDirection.mag()<<")\n"
<<" yAxis="<<yParticleFrame<<" ("<<yParticleFrame.mag()<<")\n"
<<" nAxis="<<nInteractionFrame<<" ("
<<nInteractionFrame.mag()<<")"<<G4endl;
G4double cosphi = yParticleFrame * nInteractionFrame;
if(cosphi > (1. + 1.e-8) || cosphi < (-1. - 1.e-8))
{
G4ExceptionDescription ed;
ed << " warning G4StokesVector::RotateAz cosphi>1 or cosphi<-1\n"
<< " cosphi=" << cosphi << "\n"
<< " zAxis=" << particleDirection << " (" << particleDirection.mag()
<< ")\n"
<< " yAxis=" << yParticleFrame << " (" << yParticleFrame.mag() << ")\n"
<< " nAxis=" << nInteractionFrame << " (" << nInteractionFrame.mag()
<< ")\n";
G4Exception("G4StokesVector::RotateAz", "pol030", JustWarning, ed);
}
if (cosphi>1.) cosphi=1.;
else if (cosphi<-1.) cosphi=-1.;
if(cosphi > 1.)
cosphi = 1.;
else if(cosphi < -1.)
cosphi = -1.;
// G4cout<<" cosphi="<<cosphi<<"\n"
// <<" zAxis="<<particleDirection<<" ("<<particleDirection.mag()<<")\n"
// <<" yAxis="<<yParticleFrame<<" ("<<yParticleFrame.mag()<<","<<(yParticleFrame*particleDirection)<<")\n"
// <<" nAxis="<<nInteractionFrame<<" ("
// <<nInteractionFrame.mag()<<")"<<G4endl;
G4double hel =
(yParticleFrame.cross(nInteractionFrame) * particleDirection) > 0. ? 1.
: -1.;
// G4double hel=sgn(cross(yParticleFrame*nInteractionFrame)*zInteractionFrame);
// Why not particleDirection instead of zInteractionFrame ???!!!
// -> is the same, since SYSIN is called with p1, and p2 as first parameter!
G4double hel=(yParticleFrame.cross(nInteractionFrame)*particleDirection)>0?1.:-1.;
G4double sinphi = hel * std::sqrt(1. - cosphi * cosphi);
G4double sinphi=hel*std::sqrt(1.-cosphi*cosphi);
// G4cout<<" sin2 + cos2 -1 = "<<(sinphi*sinphi+cosphi*cosphi-1)<<"\n";
RotateAz(cosphi,sinphi);
RotateAz(cosphi, sinphi);
}
void G4StokesVector::InvRotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection)
void G4StokesVector::InvRotateAz(G4ThreeVector nInteractionFrame,
G4ThreeVector particleDirection)
{
// note if incomming particle is on z-axis,
// note if incoming particle is on z-axis,
// we might encounter some nummerical problems, since
// nInteratonFrame and yParticleFrame are actually (almost) the same momentum
// and the normalization is only good to 10^-12 !
G4ThreeVector yParticleFrame =
G4ThreeVector yParticleFrame =
G4PolarizationHelper::GetParticleFrameY(particleDirection);
G4double cosphi=yParticleFrame*nInteractionFrame;
G4double cosphi = yParticleFrame * nInteractionFrame;
if (cosphi>1.+1.e-8 || cosphi<-1.-1.e-8) {
G4cout<<" warning G4StokesVector::RotateAz cosphi>1 or cosphi<-1\n";
if(cosphi > 1. + 1.e-8 || cosphi < -1. - 1.e-8)
{
G4ExceptionDescription ed;
ed << " warning G4StokesVector::RotateAz cosphi>1 or cosphi<-1\n";
G4Exception("G4StokesVector::InvRotateAz", "pol030", JustWarning, ed);
}
if (cosphi>1.) cosphi=1.;
else if (cosphi<-1.)cosphi=-1.;
if(cosphi > 1.)
cosphi = 1.;
else if(cosphi < -1.)
cosphi = -1.;
// check sign once more!
G4double hel=(yParticleFrame.cross(nInteractionFrame)*particleDirection)>0?1.:-1.;
G4double sinphi=hel*std::sqrt(std::fabs(1.-cosphi*cosphi));
RotateAz(cosphi,-sinphi);
G4double hel =
(yParticleFrame.cross(nInteractionFrame) * particleDirection) > 0. ? 1.
: -1.;
G4double sinphi = hel * std::sqrt(std::fabs(1. - cosphi * cosphi));
RotateAz(cosphi, -sinphi);
}
void G4StokesVector::RotateAz(G4double cosphi, G4double sinphi)
void G4StokesVector::RotateAz(G4double cosphi, G4double sinphi)
{
if (!isPhoton) {
G4double xsi1= cosphi*p1() + sinphi*p2();
G4double xsi2= -sinphi*p1() + cosphi*p2();
if(!fIsPhoton)
{
G4double xsi1 = cosphi * p1() + sinphi * p2();
G4double xsi2 = -sinphi * p1() + cosphi * p2();
setX(xsi1);
setY(xsi2);
return;
}
G4double sin2phi=2.*cosphi*sinphi;
G4double cos2phi=cosphi*cosphi-sinphi*sinphi;
G4double sin2phi = 2. * cosphi * sinphi;
G4double cos2phi = cosphi * cosphi - sinphi * sinphi;
G4double xsi1= cos2phi*p1() + sin2phi*p2();
G4double xsi2= -sin2phi*p1() + cos2phi*p2();
G4double xsi1 = cos2phi * p1() + sin2phi * p2();
G4double xsi2 = -sin2phi * p1() + cos2phi * p2();
setX(xsi1);
setY(xsi2);
}
G4double G4StokesVector::GetBeta()
G4double G4StokesVector::GetBeta()
{
G4double bet=getPhi();
if (isPhoton) { bet *= 0.5; }
G4double bet = getPhi();
if(fIsPhoton)
{
bet *= 0.5;
}
return bet;
}
void G4StokesVector::DiceUniform()
void G4StokesVector::DiceUniform()
{
G4double costheta=2.*G4UniformRand()-1.;
G4double sintheta=std::sqrt(1.-costheta*costheta);
G4double aphi =2.*pi*G4UniformRand();
setX(std::sin(aphi)*sintheta);
setY(std::cos(aphi)*sintheta);
G4double costheta = 2. * G4UniformRand() - 1.;
G4double sintheta = std::sqrt(1. - costheta * costheta);
G4double aphi = 2. * CLHEP::pi * G4UniformRand();
setX(std::sin(aphi) * sintheta);
setY(std::cos(aphi) * sintheta);
setZ(costheta);
}
void G4StokesVector::DiceP1()
void G4StokesVector::DiceP1()
{
if (G4UniformRand()>0.5) setX(1.);
else setX(-1.);
if(G4UniformRand() > 0.5)
setX(1.);
else
setX(-1.);
setY(0.);
setZ(0.);
}
void G4StokesVector::DiceP2()
void G4StokesVector::DiceP2()
{
setX(0.);
if (G4UniformRand()>0.5) setY(1.);
else setY(-1.);
if(G4UniformRand() > 0.5)
setY(1.);
else
setY(-1.);
setZ(0.);
}
void G4StokesVector::DiceP3()
void G4StokesVector::DiceP3()
{
setX(0.);
setY(0.);
if (G4UniformRand()>0.5) setZ(1.);
else setZ(-1.);
if(G4UniformRand() > 0.5)
setZ(1.);
else
setZ(-1.);
}
void G4StokesVector::FlipP3()
{
setZ(-z());
}
void G4StokesVector::FlipP3() { setZ(-z()); }
G4ThreeVector G4StokesVector::PolError(const G4StokesVector & sum2, long n)
G4ThreeVector G4StokesVector::PolError(const G4StokesVector& sum2, long n)
{
// delta x = sqrt[ ( <x^2> - <x>^2 )/(n-1) ]
G4StokesVector mean=(1./n)*(*this);
return G4StokesVector((1./(n-1.)*((1./n)*sum2 - mean.PolSqr()))).PolSqrt();
G4ThreeVector mean = (1. / n) * G4ThreeVector(*this);
G4ThreeVector polsqr = G4StokesVector(mean).PolSqr();
G4ThreeVector result =
G4StokesVector((1. / (n - 1.) * ((1. / n) * sum2 - polsqr))).PolSqrt();
return result;
}
G4ThreeVector G4StokesVector::PolDiv(const G4StokesVector & b)
{return G4ThreeVector(b.x()!=0. ? x()/b.x() : 11111.,
b.y()!=0. ? y()/b.y() : 11111.,
b.z()!=0. ? z()/b.z() : 11111.);}
G4ThreeVector G4StokesVector::PolDiv(const G4StokesVector& b)
{
return G4ThreeVector(b.x() != 0. ? x() / b.x() : 11111.,
b.y() != 0. ? y() / b.y() : 11111.,
b.z() != 0. ? z() / b.z() : 11111.);
}
@@ -1,149 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// File name: G4VPolarizedCrossSection
//
// Author: Andreas Schaelicke
//
// Creation date: 15.05.2005
//
// Modifications:
//
// Class Description:
// (pure virtual) interface class
//
// provides readable but efficient routines to determine
// polarization for the final state of a given process
// empoying the differential cross section
//
#include "G4VPolarizedCrossSection.hh"
#include "Randomize.hh"
G4VPolarizedCrossSection::G4VPolarizedCrossSection() :
fXmin(0), fXmax(1.), fYmin(1.), theA(1), theZ(1), fCoul(0.)
{
}
G4VPolarizedCrossSection::~G4VPolarizedCrossSection()
{
}
void G4VPolarizedCrossSection::Initialize(G4double, G4double, G4double,
const G4StokesVector &,
const G4StokesVector &,
G4int )
{
}
G4StokesVector G4VPolarizedCrossSection::GetPol2()
{
// neglects correlation effects!
G4double invXsecTotal=1./XSection(G4StokesVector::ZERO,G4StokesVector::ZERO);
G4double xsPol1=XSection(G4StokesVector::P1,G4StokesVector::ZERO);
G4double xsPol2=XSection(G4StokesVector::P2,G4StokesVector::ZERO);
G4double xsPol3=XSection(G4StokesVector::P3,G4StokesVector::ZERO);
return G4ThreeVector(invXsecTotal*xsPol1,invXsecTotal*xsPol2,invXsecTotal*xsPol3);
}
G4StokesVector G4VPolarizedCrossSection::GetPol3()
{
// neglects correlation effects!
G4double invXsecTotal=1./XSection(G4StokesVector::ZERO,G4StokesVector::ZERO);
G4double xsPol1=XSection(G4StokesVector::ZERO,G4StokesVector::P1);
G4double xsPol2=XSection(G4StokesVector::ZERO,G4StokesVector::P2);
G4double xsPol3=XSection(G4StokesVector::ZERO,G4StokesVector::P3);
return G4ThreeVector(invXsecTotal*xsPol1,invXsecTotal*xsPol2,invXsecTotal*xsPol3);
}
// minimal energy fraction in TotalXSection
G4double G4VPolarizedCrossSection::GetXmin(G4double /*y*/)
{
return fXmin;
}
// maximal energy fraction in TotalXSection
G4double G4VPolarizedCrossSection::GetXmax(G4double /*y*/)
{
return fXmax;
}
/*
void G4VPolarizedCrossSection::DicePolarization()
{
// can respect correlation effects, but is limited to
// one quantization axis!
G4double sigma[4];
sigma[0]=XSection(G4StokesVector::P3,G4StokesVector::P3);
sigma[1]=XSection(G4StokesVector::P3,G4StokesVector::M3);
sigma[2]=XSection(G4StokesVector::M3,G4StokesVector::P3);
sigma[3]=XSection(G4StokesVector::M3,G4StokesVector::M3);
G4double sigma_max = 4. * XSection(G4StokesVector::ZERO,G4StokesVector::ZERO);
for (G4int i=0;i<4;++i) {
G4cout<<"sigma="<<sigma[i]<<" vs."<<(.25*sigma_max)<<G4endl;
if (sigma[i]<0 || sigma[i]>sigma_max) {
G4cout<<"ERROR G4VPolarizedCrossSection::DicePolarization(["<<i<<"]): "
<<sigma[i]<<" vs."<<sigma_max<<G4endl;
}
if (i>0) sigma[i]+=sigma[i-1];
}
G4int k = 0;
G4double disc = sigma[3]*G4UniformRand();
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
while (sigma[k]<disc && k<4) {
++k;
}
if ((k&2)==0) pol2=G4StokesVector::P3;
else pol2=G4StokesVector::M3;
if ((k&1)==0) pol3=G4StokesVector::P3;
else pol3=G4StokesVector::M3;
}
*/
/*
G4StokesVector G4VPolarizedCrossSection::DicedPol2()
{
return pol2;
}
G4StokesVector G4VPolarizedCrossSection::DicedPol3()
{
return pol3;
}
*/
G4double G4VPolarizedCrossSection::TotalXSection(G4double, G4double, G4double,
const G4StokesVector &,const G4StokesVector &)
{
G4cout << "WARNING virtual function G4VPolarizedCrossSection::TotalXSection() called" << G4endl;
return 0.;
}
@@ -0,0 +1,95 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// File name: G4VPolarizedXS
//
// Author: Andreas Schaelicke
//
// Class Description:
// (virtual) interface class
// provides readable but efficient routines to determine
// polarization for the final state of a given process
// empoying the differential cross section
#include "G4VPolarizedXS.hh"
#include "Randomize.hh"
G4VPolarizedXS::G4VPolarizedXS()
: fXmin(0)
, fXmax(1.)
, fYmin(1.)
, fA(1.)
, fZ(1.)
, fCoul(0.)
{}
G4VPolarizedXS::~G4VPolarizedXS() {}
void G4VPolarizedXS::Initialize(G4double, G4double, G4double,
const G4StokesVector&, const G4StokesVector&,
G4int)
{}
G4StokesVector G4VPolarizedXS::GetPol2()
{
// neglects correlation effects!
G4double invXsecTotal =
1. / XSection(G4StokesVector::ZERO, G4StokesVector::ZERO);
G4double xsPol1 = XSection(G4StokesVector::P1, G4StokesVector::ZERO);
G4double xsPol2 = XSection(G4StokesVector::P2, G4StokesVector::ZERO);
G4double xsPol3 = XSection(G4StokesVector::P3, G4StokesVector::ZERO);
return G4StokesVector(G4ThreeVector(
invXsecTotal * xsPol1, invXsecTotal * xsPol2, invXsecTotal * xsPol3));
}
G4StokesVector G4VPolarizedXS::GetPol3()
{
// neglects correlation effects!
G4double invXsecTotal =
1. / XSection(G4StokesVector::ZERO, G4StokesVector::ZERO);
G4double xsPol1 = XSection(G4StokesVector::ZERO, G4StokesVector::P1);
G4double xsPol2 = XSection(G4StokesVector::ZERO, G4StokesVector::P2);
G4double xsPol3 = XSection(G4StokesVector::ZERO, G4StokesVector::P3);
return G4StokesVector(G4ThreeVector(
invXsecTotal * xsPol1, invXsecTotal * xsPol2, invXsecTotal * xsPol3));
}
// minimal energy fraction in TotalXSection
G4double G4VPolarizedXS::GetXmin(G4double /*y*/) { return fXmin; }
// maximal energy fraction in TotalXSection
G4double G4VPolarizedXS::GetXmax(G4double /*y*/) { return fXmax; }
G4double G4VPolarizedXS::TotalXSection(G4double, G4double, G4double,
const G4StokesVector&,
const G4StokesVector&)
{
G4ExceptionDescription ed;
ed << "WARNING virtual function G4VPolarizedXS::TotalXSection() "
"called.\n";
G4Exception("G4VPolarizedXS::TotalXSection", "pol032", FatalException, ed);
return 0.;
}
@@ -1,134 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4ePolarizedBremsstrahlungModel
//
// Author: Karim Laihem
//
// Creation date: 12.03.2005
//
// Modifications:
// 19-08-06 addapted to accomodate geant481 structure
//
//
// Class Description:
//
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ePolarizedBremsstrahlungModel.hh"
#include "G4PolarizedBremsstrahlungCrossSection.hh"
#include "G4ParticleChangeForLoss.hh"
#include "G4PolarizationHelper.hh"
G4ePolarizedBremsstrahlungModel::G4ePolarizedBremsstrahlungModel(
const G4ParticleDefinition* p, const G4String& nam)
: G4SeltzerBergerModel(p,nam),
crossSectionCalculator(nullptr)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedBremsstrahlungModel::~G4ePolarizedBremsstrahlungModel()
{
if (crossSectionCalculator) delete crossSectionCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedBremsstrahlungModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& d)
{
G4SeltzerBergerModel::Initialise(p,d);
if (!crossSectionCalculator)
crossSectionCalculator = new G4PolarizedBremsstrahlungCrossSection();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedBremsstrahlungModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmin,
G4double maxEnergy)
{
G4SeltzerBergerModel::SampleSecondaries(vdp,couple,dp,tmin,maxEnergy);
G4int num = vdp->size();
if(num > 0) {
G4double lepEnergy0 = dp->GetKineticEnergy();
G4double gamEnergy1 = (*vdp)[0]->GetKineticEnergy();
G4double sintheta = dp->GetMomentumDirection().cross((*vdp)[0]->GetMomentumDirection()).mag();
if (sintheta>1.) sintheta=1.;
G4StokesVector beamPol = dp->GetPolarization();
// determine interaction plane
G4ThreeVector nInteractionFrame =
G4PolarizationHelper::GetFrame(dp->GetMomentumDirection(),
fParticleChange->GetProposedMomentumDirection());
// transform polarization into interaction frame
beamPol.InvRotateAz(nInteractionFrame,dp->GetMomentumDirection());
// calulcate polarization transfer
crossSectionCalculator->SetMaterial(GetCurrentElement()->GetN(), // number of nucleons
GetCurrentElement()->GetZ(),
GetCurrentElement()->GetfCoulomb());
crossSectionCalculator->Initialize(lepEnergy0, gamEnergy1, sintheta,
beamPol, G4StokesVector::ZERO);
// deterimine final state polarization
G4StokesVector newBeamPol = crossSectionCalculator->GetPol2();
newBeamPol.RotateAz(nInteractionFrame,
fParticleChange->GetProposedMomentumDirection());
fParticleChange->ProposePolarization(newBeamPol);
if (num!=1) G4cout<<" WARNING "<<num<<" secondaries in polarized bremsstrahlung not supported!\n";
for (G4int i=0; i<num; i++) {
G4StokesVector photonPol = crossSectionCalculator->GetPol3();
photonPol.SetPhoton();
photonPol.RotateAz(nInteractionFrame,(*vdp)[i]->GetMomentumDirection());
(*vdp)[i]->SetPolarization(photonPol.p1(),
photonPol.p2(),
photonPol.p3());
}
}
return;
}
// The emitted gamma energy is sampled using a parametrized formula
@@ -1,382 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4ePolarizedIonisation
//
// Author: A.Schaelicke on base of Vladimir Ivanchenko code
//
// Creation date: 10.11.2005
//
// Modifications:
//
// 10-11-05, include polarization description (A.Schaelicke)
// , create asymmetry table and determine interactionlength
// , update polarized differential cross section
//
// 20-08-06, modified interface (A.Schaelicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
//
// Class Description:
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4ePolarizedIonisation.hh"
#include "G4Electron.hh"
#include "G4UniversalFluctuation.hh"
#include "G4UnitsTable.hh"
#include "G4PolarizedMollerBhabhaModel.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4ProductionCutsTable.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4StokesVector.hh"
#include "G4EmParameters.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedIonisation::G4ePolarizedIonisation(const G4String& name)
: G4VEnergyLossProcess(name),
theElectron(G4Electron::Electron()),
isElectron(true),
isInitialised(false),
theTargetPolarization(0.,0.,0.),
theAsymmetryTable(nullptr),
theTransverseAsymmetryTable(nullptr)
{
verboseLevel=0;
SetProcessSubType(fIonisation);
SetSecondaryParticle(theElectron);
flucModel = nullptr;
emModel = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedIonisation::~G4ePolarizedIonisation()
{
CleanTables();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::CleanTables()
{
if(theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
}
if(theTransverseAsymmetryTable) {
theTransverseAsymmetryTable->clearAndDestroy();
delete theTransverseAsymmetryTable;
theTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4ePolarizedIonisation::MinPrimaryEnergy(const G4ParticleDefinition*,
const G4Material*, G4double cut)
{
G4double x = cut;
if(isElectron) { x += cut; }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4ePolarizedIonisation::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron() || &p == G4Positron::Positron());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::InitialiseEnergyLossProcess(
const G4ParticleDefinition* part,
const G4ParticleDefinition*)
{
if(!isInitialised) {
if(part == G4Positron::Positron()) { isElectron = false; }
if (!FluctModel()) { SetFluctModel(new G4UniversalFluctuation()); }
flucModel = FluctModel();
emModel = new G4PolarizedMollerBhabhaModel();
SetEmModel(emModel);
G4EmParameters* param = G4EmParameters::Instance();
emModel->SetLowEnergyLimit(param->MinKinEnergy());
emModel->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, emModel, flucModel);
isInitialised = true;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ePolarizedIonisation::GetMeanFreePath(const G4Track& track,
G4double step,
G4ForceCondition* cond)
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEnergyLossProcess::GetMeanFreePath(track, step, cond);
if(theAsymmetryTable && theTransverseAsymmetryTable && mfp < DBL_MAX) {
mfp *= ComputeSaturationFactor(track);
}
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::MeanFreePath: "
<< mfp / mm << " mm " << G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ePolarizedIonisation::PostStepGetPhysicalInteractionLength(const G4Track& track,
G4double step,
G4ForceCondition* cond)
{
// save previous values
G4double nLength = theNumberOfInteractionLengthLeft;
G4double iLength = currentInteractionLength;
// *** get unpolarised mean free path from lambda table ***
// this changes theNumberOfInteractionLengthLeft and currentInteractionLength
G4double x = G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(track, step, cond);
G4double x0 = x;
G4double satFact = 1.;
// *** add corrections on polarisation ***
if(theAsymmetryTable && theTransverseAsymmetryTable && x < DBL_MAX) {
satFact = ComputeSaturationFactor(track);
G4double curLength = currentInteractionLength*satFact;
G4double prvLength = iLength*satFact;
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - step/prvLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::PostStepGPIL: "
<< std::setprecision(8) << x/mm << " mm;" << G4endl
<< " unpolarized value: "
<< std::setprecision(8) << x0/mm << " mm." << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4ePolarizedIonisation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector volPolarization = polarizationManger->GetVolumePolarization(aLVolume);
G4double factor = 1.0;
if (volumeIsPolarized && !volPolarization.IsZero()) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPart = track.GetDynamicParticle();
const G4double energy = aDynamicPart->GetKineticEnergy();
const G4StokesVector polarization = track.GetPolarization();
const G4ParticleMomentum direction0 = aDynamicPart->GetMomentumDirection();
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::ComputeSaturationFactor: " << G4endl;
G4cout << " Energy(MeV) " << energy/MeV << G4endl;
G4cout << " Direction " << direction0 << G4endl;
G4cout << " Polarization " << polarization << G4endl;
G4cout << " MaterialPol. " << volPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < theAsymmetryTable->size()) {
aVector = (*theAsymmetryTable)(midx);
}
if(midx < theTransverseAsymmetryTable->size()) {
bVector = (*theTransverseAsymmetryTable)(midx);
}
if(aVector && bVector) {
G4double lAsymmetry = aVector->Value(energy);
G4double tAsymmetry = bVector->Value(energy);
G4double polZZ = polarization.z()*(volPolarization*direction0);
G4double polXX = polarization.x()*
(volPolarization*G4PolarizationHelper::GetParticleFrameX(direction0));
G4double polYY = polarization.y()*
(volPolarization*G4PolarizationHelper::GetParticleFrameY(direction0));
factor /= (1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry);
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4ePolarizedIonisation::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::BuildPhysicsTable(
const G4ParticleDefinition& part)
{
// *** build DEDX and (unpolarized) cross section tables
G4VEnergyLossProcess::BuildPhysicsTable(part);
G4bool master = true;
const G4ePolarizedIonisation* masterProcess =
static_cast<const G4ePolarizedIonisation*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { master = false; }
if(master) { BuildAsymmetryTables(part); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTables();
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
theTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
for (size_t j=0 ; j < numOfCouples; j++ ) {
// get cut value
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
G4double cut = (*theCoupleTable->GetEnergyCutsVector(1))[j];
//create physics vectors then fill it (same parameters as lambda vector)
G4PhysicsVector * ptrVectorA = LambdaPhysicsVector(couple,cut);
G4PhysicsVector * ptrVectorB = LambdaPhysicsVector(couple,cut);
size_t bins = ptrVectorA->GetVectorLength();
for (size_t i = 0 ; i < bins ; i++ ) {
G4double lowEdgeEnergy = ptrVectorA->Energy(i);
G4double tasm=0.;
G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, cut, tasm);
ptrVectorA->PutValue(i,asym);
ptrVectorB->PutValue(i,tasm);
}
theAsymmetryTable->insertAt( j , ptrVectorA ) ;
theTransverseAsymmetryTable->insertAt( j , ptrVectorB ) ;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4ePolarizedIonisation::ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle,
G4double cut,
G4double & tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
if (isElectron) { lAsymmetry = tAsymmetry = -1.0; }
// calculate polarized cross section
theTargetPolarization=G4ThreeVector(0.,0.,1.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate transversely polarized cross section
theTargetPolarization=G4ThreeVector(1.,0.,0.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate unpolarized cross section
theTargetPolarization=G4ThreeVector();
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma0 = emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// determine assymmetries
if (sigma0 > 0.) {
lAsymmetry=sigma2/sigma0 - 1.;
tAsymmetry=sigma3/sigma0 - 1.;
}
if (std::fabs(lAsymmetry)>1.) {
G4cout<<"G4ePolarizedIonisation::ComputeAsymmetry WARNING: E(MeV)= "
<< energy << " lAsymmetry= "<<lAsymmetry
<<" ("<<std::fabs(lAsymmetry)-1.<<")\n";
}
if (std::fabs(tAsymmetry)>1.) {
G4cout<<" energy="<<energy<<"\n";
G4cout<<"G4ePolarizedIonisation::ComputeAsymmetry WARNING: E(MeV)= "
<< energy << " tAsymmetry= "<<tAsymmetry
<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
}
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1,335 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eplusPolarizedAnnihilation
//
// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
//
// Creation date: 02.07.2006
//
// Modifications:
// 26-07-06 modified cross section (P. Starovoitov)
// 21-08-06 interface updated (A. Schaelicke)
// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
// 02-10-07, enable AtRest (V.Ivanchenko)
//
//
// Class Description:
//
// Polarized process of e+ annihilation into 2 gammas
//
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4eplusPolarizedAnnihilation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Gamma.hh"
#include "G4PhysicsVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PolarizedAnnihilationModel.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4ProductionCutsTable.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4StokesVector.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4eplusPolarizedAnnihilation::G4eplusPolarizedAnnihilation(const G4String& name)
: G4eplusAnnihilation(name), isInitialised(false),
theAsymmetryTable(nullptr),
theTransverseAsymmetryTable(nullptr)
{
emModel = new G4PolarizedAnnihilationModel();
SetEmModel(emModel);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4eplusPolarizedAnnihilation::~G4eplusPolarizedAnnihilation()
{
CleanTables();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::CleanTables()
{
if(theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
}
if(theTransverseAsymmetryTable) {
theTransverseAsymmetryTable->clearAndDestroy();
delete theTransverseAsymmetryTable;
theTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4eplusPolarizedAnnihilation::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
G4double mfp = G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
if(theAsymmetryTable && theTransverseAsymmetryTable && mfp < DBL_MAX) {
mfp *= ComputeSaturationFactor(track);
}
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::MeanFreePath: "
<< mfp / mm << " mm " << G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4eplusPolarizedAnnihilation::PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
// save previous values
G4double nLength = theNumberOfInteractionLengthLeft;
G4double iLength = currentInteractionLength;
// *** compute unpolarized step limit ***
// this changes theNumberOfInteractionLengthLeft and currentInteractionLength
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(track,
previousStepSize,
condition);
G4double x0 = x;
G4double satFact = 1.0;
// *** add corrections on polarisation ***
if(theAsymmetryTable && theTransverseAsymmetryTable && x < DBL_MAX) {
satFact = ComputeSaturationFactor(track);
G4double curLength = currentInteractionLength*satFact;
G4double prvLength = iLength*satFact;
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize/prvLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::PostStepGPIL: "
<< std::setprecision(8) << x/mm << " mm;" << G4endl
<< " unpolarized value: "
<< std::setprecision(8) << x0/mm << " mm." << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4eplusPolarizedAnnihilation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
G4double factor = 1.0;
if (volumeIsPolarized) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
const G4StokesVector positronPolarization = track.GetPolarization();
const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::ComputeSaturationFactor: " << G4endl;
G4cout << " Mom " << positronDirection0 << G4endl;
G4cout << " Polarization " << positronPolarization << G4endl;
G4cout << " MaterialPol. " << electronPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < theAsymmetryTable->size()) {
aVector = (*theAsymmetryTable)(midx);
}
if(midx < theTransverseAsymmetryTable->size()) {
bVector = (*theTransverseAsymmetryTable)(midx);
}
if(aVector && bVector) {
G4double lAsymmetry = aVector->Value(positronEnergy);
G4double tAsymmetry = bVector->Value(positronEnergy);
G4double polZZ = positronPolarization.z()*
(electronPolarization*positronDirection0);
G4double polXX = positronPolarization.x()*
(electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0));
G4double polYY = positronPolarization.y()*
(electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0));
factor /= (1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry);
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4eplusPolarizedAnnihilation::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::BuildPhysicsTable(
const G4ParticleDefinition& part)
{
G4VEmProcess::BuildPhysicsTable(part);
G4bool isMaster = true;
const G4eplusPolarizedAnnihilation* masterProcess =
static_cast<const G4eplusPolarizedAnnihilation*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { isMaster = false; }
if(isMaster) { BuildAsymmetryTables(part); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTables();
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
theTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
//G4cout<<" annih-numOfCouples="<<numOfCouples<<"\n";
for(size_t i=0; i<numOfCouples; ++i) {
//G4cout<<"annih- "<<i<<"/"<<numOfCouples<<"\n";
if (!theAsymmetryTable) break;
//G4cout<<"annih- "<<theAsymmetryTable->GetFlag(i)<<"\n";
if (theAsymmetryTable->GetFlag(i)) {
//G4cout<<" building pol-annih ... \n";
// create physics vector and fill it
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
// use same parameters as for lambda
G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
G4PhysicsVector* tVector = LambdaPhysicsVector(couple);
for (G4int j = 0 ; j < LambdaBinning() ; ++j ) {
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(j);
G4double tasm=0.;
G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, 0., tasm);
aVector->PutValue(j,asym);
tVector->PutValue(j,tasm);
}
G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, aVector);
G4PhysicsTableHelper::SetPhysicsVector(theTransverseAsymmetryTable, i, tVector);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4eplusPolarizedAnnihilation::ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle,
G4double cut,
G4double &tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
// calculate polarized cross section
theTargetPolarization=G4ThreeVector(0.,0.,1.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate transversely polarized cross section
theTargetPolarization=G4ThreeVector(1.,0.,0.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate unpolarized cross section
theTargetPolarization=G4ThreeVector();
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// determine assymmetries
if (sigma0>0.) {
lAsymmetry=sigma2/sigma0-1.;
tAsymmetry=sigma3/sigma0-1.;
}
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::PrintInfo()
{
G4cout << " Polarized model for annihilation into 2 photons"
<< G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....