Import Geant4 11.0.0.beta source tree
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# CMakeLists.txt
|
||||
# Module : G4emadjoint
|
||||
# Package: Geant4.src.G4processes.G4electromagnetic.G4emadjoint
|
||||
#
|
||||
# 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,39 +16,76 @@ committal in the CVS repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
---------------------------------------------------------
|
||||
|
||||
16 Apr 2021: B. Morgan (emadjoint-V10-07-05)
|
||||
- Migrate build to modular CMake API
|
||||
|
||||
28 Mar 2021: V. Ivanchenko (emadjoint-V10-07-04)
|
||||
- G4ContinuousGainOfEnergy - used updated signature for ion ionisation
|
||||
|
||||
22 Mar 2021: V. Ivanchenko (emadjoint-V10-07-03)
|
||||
- G4VEmAdjointModel - minor clean-up
|
||||
|
||||
12 Mar 2021: D. Sawkey (emadjoint-V10-07-02)
|
||||
- free resources in destructors
|
||||
- fix uninitialized variables
|
||||
|
||||
8 Mar 2021: D. Sawkey (emadjoint-V10-07-01)
|
||||
- Second large round of cleaning for v11 release
|
||||
- use 'virtual' and 'override' methods consistently
|
||||
- member variables start with f; shorten long names
|
||||
- remove unused variables; make class variables local where appropriate
|
||||
- order declarations of class variables
|
||||
- define class variables
|
||||
- removed unused functions
|
||||
- mark copy/assignment operators as 'delete'
|
||||
- add ProcessDescriptions
|
||||
- remove ChangeHistory from top of code
|
||||
- replace 2.*3.14... with CLHEP::twopi
|
||||
- remove more unused headers
|
||||
|
||||
20 Feb 2021: D. Sawkey (emadjoint-V10-07-00)
|
||||
- First pass on large cleaning for v11 release
|
||||
- apply clang-format style guidelines
|
||||
- apply C++11 codewords to method declarations: virtual, override, explicit
|
||||
- delete unused variables and methods
|
||||
- start naming class member variables with f
|
||||
- use nullptr instead of 0
|
||||
- remove unused headers
|
||||
- use constexpr for numbers
|
||||
|
||||
11 Mar 2019: G. Cosmo (emadjoint-V10-05-00)
|
||||
-Fixed typos in printouts and comments.
|
||||
|
||||
06 Nov 2017: V. Ivanchenko (emadjoint-V10-03-01)
|
||||
-Extended correction of occurrence of FPE in G4AdjointForcedInteractionForGamma.
|
||||
-G4eAdjointMultipleScattering - change index of the default accourding to recent
|
||||
-G4eAdjointMultipleScattering - change index of the default accourding to recent
|
||||
modifications in emutils
|
||||
|
||||
27 Jan 2017: L. Desorgher (emadjoint-V10-03-00)
|
||||
-Correction of occurrence of FPE in G4AdjointForcedInteractionForGamma.
|
||||
|
||||
|
||||
27 Octb 2016: L. Desorgher (emadjoint-V10-02-03)
|
||||
-Correction in G4AdjointForcedInteractionForGamma to avoid high weight of forced gamma
|
||||
when only the brem is used.
|
||||
-Modification in G4AdjointBremsstrahlungModel to use the direcet angular model to compute the direction of the
|
||||
-Modification in G4AdjointBremsstrahlungModel to use the direcet angular model to compute the direction of the
|
||||
adjoint secondary
|
||||
-Add G4UrbanAdjointMscModel.cc and G4eAdjointMultipleScattering.cc
|
||||
|
||||
|
||||
18 Octb 2016: L. Desorgher (emadjoint-V10-02-02)
|
||||
-Correct use of logical or in G4AdjointForcedInteractionForGamma for compilation
|
||||
error under windows.
|
||||
|
||||
error under windows.
|
||||
|
||||
17 Octb 2016: L. Desorgher (emadjoint-V10-02-01)
|
||||
-Correct G4AdjointForcedInteractionForGamma for compilation error under windows.
|
||||
-Correct G4AdjointForcedInteractionForGamma for compilation error under windows.
|
||||
|
||||
26 Sept 2016: L. Desorgher (emadjoint-V10-02-00)
|
||||
-Add new adjoint process G4AdjointForcedInteractionForGamma to force the
|
||||
-Add new adjoint process G4AdjointForcedInteractionForGamma to force the
|
||||
reverse interaction of adjoint gamma.
|
||||
-Slight modifications of G4VEmAdjointModel for new forced interaction
|
||||
-Some corrections in G4AdjointBremsstrahlungModel
|
||||
|
||||
24 Oct 2015: V.Ivanchenko (emadjoint-V10-01-03)
|
||||
- G4AdjointCSManager - use G4ThreadLocalSingleton pattern,
|
||||
- G4AdjointCSManager - use G4ThreadLocalSingleton pattern,
|
||||
fixed computation of A of an element, added initialisation
|
||||
of all class members in the constructor
|
||||
|
||||
@@ -61,12 +98,12 @@ committal in the CVS repository !
|
||||
G4AdjointCSManager - add checks for while loops
|
||||
|
||||
21 May 2015: V.Ivanchenko (emadjoint-V10-01-00)
|
||||
- G4AdjointhMultipleScattering - make it coherent with the forward
|
||||
- G4AdjointhMultipleScattering - make it coherent with the forward
|
||||
msc processes
|
||||
|
||||
10 Apr 2014: V.Ivanchenko (emadjoint-V10-00-00)
|
||||
- G4VAdjointReverseReaction - added protection against infinite
|
||||
loop in ReverseMC01 example: if cross section correction
|
||||
- G4VAdjointReverseReaction - added protection against infinite
|
||||
loop in ReverseMC01 example: if cross section correction
|
||||
exceed 100 the total cross section is set to zero
|
||||
|
||||
31 Oct 2013: L.Desorgher (emadjoint-V09-06-09)
|
||||
@@ -90,9 +127,9 @@ committal in the CVS repository !
|
||||
24 Jan 2013: V.Ivanchenko (emadjoint-V09-06-04)
|
||||
- G4AdjointPhotoElectricModel - define current G4MaterialCutsCouple
|
||||
for the direct model
|
||||
|
||||
|
||||
22 Feb 2013: L.Desorgher (emadjoint-V09-06-03)
|
||||
-Remove of unused variables detected by compilation warnings.
|
||||
-Remove of unused variables detected by compilation warnings.
|
||||
|
||||
23 Jan 2013: V.Ivanchenko (emadjoint-V09-06-02)
|
||||
11 Jan 2013: V.Ivanchenko (emadjoint-V09-06-01)
|
||||
@@ -109,9 +146,9 @@ committal in the CVS repository !
|
||||
26 Oct 2012: L.Desorgher (emadjoint-V09-05-03)
|
||||
-G4AdjointBremsstrahlungModel changed to use G4SeltzerBergerModel as forward model by default
|
||||
-Correct differential CS expression in G4VEmAdjointModel
|
||||
-Get the weight from PostStepPoint instead of from Track when correcting the step in along stepping actions of
|
||||
G4ContinuousGainOfEnergy and G4AdjointAlongStepWeightCorrection. THis is needed for a correct propagation
|
||||
of weight correction in different along step actions.
|
||||
-Get the weight from PostStepPoint instead of from Track when correcting the step in along stepping actions of
|
||||
G4ContinuousGainOfEnergy and G4AdjointAlongStepWeightCorrection. THis is needed for a correct propagation
|
||||
of weight correction in different along step actions.
|
||||
|
||||
10 Jul 2012: G.Cosmo (emadjoint-V09-05-02)
|
||||
- Explicitly use inclusion of headers for system of units and physical
|
||||
@@ -125,7 +162,7 @@ committal in the CVS repository !
|
||||
|
||||
24 Jun 2011: V.Ivanchenko (emadjoint-V09-04-03)
|
||||
- G4AdjointAlongStepWeightCorrection,G4ContinuousGainOfEnergy,
|
||||
G4VEmAdjointModel - fixed initialisation of currentCouple
|
||||
G4VEmAdjointModel - fixed initialisation of currentCouple
|
||||
class member in constructor (Valgrind report)
|
||||
|
||||
10 Jun 2011: G.Cosmo (emadjoint-V09-04-02)
|
||||
@@ -165,24 +202,24 @@ Coverity fixes
|
||||
-G4VEmAdjointModel
|
||||
-Comment dead code in GetAdjointCrossSection (defect 23168)
|
||||
-Neglect at the moment coverity bug 20612-20618.
|
||||
|
||||
|
||||
|
||||
|
||||
27 May 2011: L. Desorgher (emadjoint-V09-04-00)
|
||||
-Remove few unused variables to avoid compilation warning with gcc-4.6.0.
|
||||
|
||||
11 Nov 2010: L. Desorgher (emadjoint-V09-03-02)
|
||||
-G4AdjointBremsstrahlungModel: add a G4EmModelManager to initialise properly,
|
||||
the G4eBremsstrahlungModel used as forward model. This allows to fix the
|
||||
the G4eBremsstrahlungModel used as forward model. This allows to fix the
|
||||
floating point exception detected when compiling with G4FPE_DEBUG=1.
|
||||
-G4AdjointhIonisation:
|
||||
Remove a negative term in the expression of the adjoint
|
||||
Remove a negative term in the expression of the adjoint
|
||||
cross section (AdjointCrossSection method) and adapt the RapidSampleSecondaries method.
|
||||
-G4VEmAdjointModel:
|
||||
-G4VEmAdjointModel:
|
||||
Add a check on null cross section to avoid FPE.
|
||||
|
||||
3 Sep 2010: G.Cosmo (emadjoint-V09-03-01)
|
||||
- G4AdjointAlongStepWeightCorrection: get rid of call to non-Standard isnan(),
|
||||
replaced by explicit validity test.
|
||||
replaced by explicit validity test.
|
||||
|
||||
12 Apr 2010: V.Ivanchenko (emadjoint-V09-03-00)
|
||||
- G4AdjointhMultipleScattering: removed obsolete unused header.
|
||||
@@ -196,8 +233,8 @@ Coverity fixes
|
||||
10 Nov 2009: L.Desorgher (emadjoint-V09-02-00)
|
||||
- Commit of the electromagnetic adjoint processes for the release of the all adjoint machinery into Geant4.
|
||||
Compared to the first commit, all e- processes have been improved and adjoint proton and ion ionisation have been added.
|
||||
The use of adjoint cross section matrices can be now limited only to e- Ionisation and Ion ionisation.
|
||||
The GNUmakefile has been modified by adding -I$(G4BASE)/geometry/navigation/include in CPPFLAGS.
|
||||
The use of adjoint cross section matrices can be now limited only to e- Ionisation and Ion ionisation.
|
||||
The GNUmakefile has been modified by adding -I$(G4BASE)/geometry/navigation/include in CPPFLAGS.
|
||||
|
||||
14 Nov 2008: G.Cosmo (emadjoint-V09-01-00)
|
||||
- First commit.
|
||||
|
||||
+46
-79
@@ -23,114 +23,81 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointAlongStepWeightCorrection
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// Class: G4AdjointAlongStepWeightCorrection
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 10 May 2007 creation by L. Desorgher
|
||||
// October 2009 implementation of the mode where the total adjoint and forward cross sections are equivalent. L. Desorgher
|
||||
// Documentation:
|
||||
//
|
||||
// Continuous processes act on adjoint particles to continuously correct their
|
||||
// weight during the adjoint reverse tracking. This process is needed when
|
||||
// the adjoint cross sections are not scaled such that the total adjoint cross
|
||||
// section matches the total forward cross section. By default the mode where
|
||||
// the total adjoint cross section is equal to the total forward cross section
|
||||
// is used and therefore this along step weightcorrection factor is 1. However
|
||||
// in some cases (some energy ranges) the total forward cross section or the
|
||||
// total adjoint cross section can be zero. In this case the along step weight
|
||||
// correction is needed and is given by exp(-(Sigma_tot_adj-Sigma_tot_fwd).dx)
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Continuous processes acting on adjoint particles to correct continuously their weight during the adjoint reverse tracking.
|
||||
// Thi process is needed whene the adjoint cross section are not scaled such that the total adjoint cross section match the total forward cross section.
|
||||
// By default the mode where the total adjoint cross section is equal to the total forward cross section is used an therefore this along step weight
|
||||
// correction factor is 1.
|
||||
// However in some cases (some energy ranges) the total forward cross section or the total adjoint cross section can be null, in this case the along step
|
||||
// weight correction is neede and is given by exp(-(Sigma_tot_adj-Sigma_tot_fwd).dx)
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef G4AdjointAlongStepWeightCorrection_h
|
||||
#define G4AdjointAlongStepWeightCorrection_h 1
|
||||
|
||||
#include "G4VContinuousProcess.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4VContinuousProcess.hh"
|
||||
|
||||
class G4Step;
|
||||
class G4AdjointCSManager;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleDefinition;
|
||||
|
||||
|
||||
class G4ParticleChange;
|
||||
class G4Step;
|
||||
class G4Track;
|
||||
|
||||
class G4AdjointAlongStepWeightCorrection : public G4VContinuousProcess
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4AdjointAlongStepWeightCorrection(
|
||||
const G4String& name = "ContinuousWeightCorrection",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
G4AdjointAlongStepWeightCorrection(const G4String& name = "ContinuousWeightCorrection",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
~G4AdjointAlongStepWeightCorrection() override;
|
||||
|
||||
virtual ~G4AdjointAlongStepWeightCorrection();
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&) override;
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
protected:
|
||||
virtual G4double GetContinuousStepLimit(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety);
|
||||
|
||||
G4AdjointAlongStepWeightCorrection(G4AdjointAlongStepWeightCorrection&) =
|
||||
delete;
|
||||
G4AdjointAlongStepWeightCorrection& operator=(
|
||||
const G4AdjointAlongStepWeightCorrection& right) = delete;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Generic methods common to all processes
|
||||
//------------------------------------------------------------------------
|
||||
public:
|
||||
|
||||
void PreparePhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&);
|
||||
|
||||
|
||||
private:
|
||||
protected:
|
||||
G4double GetContinuousStepLimit(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety) override;
|
||||
|
||||
private:
|
||||
void DefineMaterial(const G4MaterialCutsCouple* couple);
|
||||
|
||||
|
||||
|
||||
G4AdjointAlongStepWeightCorrection(G4AdjointAlongStepWeightCorrection &);
|
||||
G4AdjointAlongStepWeightCorrection & operator=(const G4AdjointAlongStepWeightCorrection &right);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const G4MaterialCutsCouple* fCurrentCouple = nullptr;
|
||||
G4AdjointCSManager* fCSManager = nullptr;
|
||||
G4ParticleChange* fParticleChange;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const G4Material* currentMaterial;
|
||||
const G4MaterialCutsCouple* currentCouple;
|
||||
size_t currentMaterialIndex;
|
||||
G4double preStepKinEnergy;
|
||||
|
||||
|
||||
G4double fPreStepKinEnergy = 1.;
|
||||
};
|
||||
|
||||
inline void G4AdjointAlongStepWeightCorrection::DefineMaterial(
|
||||
const G4MaterialCutsCouple* couple)
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
if(couple != currentCouple) {
|
||||
currentCouple = couple;
|
||||
currentMaterial = couple->GetMaterial();
|
||||
currentMaterialIndex = couple->GetIndex();
|
||||
|
||||
if(couple != fCurrentCouple)
|
||||
{
|
||||
fCurrentCouple = couple;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,93 +23,73 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointBremsstrahlungModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointBremsstrahlungModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 15 June 2007 creation by L. Desorgher. Adapted from G4eBremsstrahlungModel
|
||||
// 20-10-2009 Remove all the screening effect that are not considered in the direct models blow 10 GeV. L.Desorgher
|
||||
// 4-11-2009 Implement the use of a simple biased differential cross section (C(Z)/Egamma) allowing a rapid computation of adjoint CS
|
||||
// and rapid sampling of adjoint secondaries. By this way cross section matrices are not used anymore, avoiding a rather
|
||||
// time consuming computation of adjoint brem cross section matrices for each material at initialisation. This mode is switch on/off
|
||||
// by selecting SetUseMatrix(false)/ SetUseMatrix(true) in the constructor. L.Desorgher
|
||||
//
|
||||
// Adjoint Model for e- Bremsstrahlung.Adapted from G4eBremsstrahlungModel
|
||||
// Use of a simple biased differential cross section (C(Z)/Egamma) allowing a
|
||||
// rapid computation of adjoint CS and rapid sampling of adjoint secondaries.
|
||||
// In this way cross section matrices are not used anymore, avoiding a long
|
||||
// computation of adjoint brem cross section matrices for each material
|
||||
// at initialisation. This mode can be switched on/off by selecting
|
||||
// SetUseMatrix(false)/ SetUseMatrix(true) in the constructor.
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint Model for e- Bremsstrahlung
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef G4AdjointBremsstrahlungModel_h
|
||||
#define G4AdjointBremsstrahlungModel_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4VEmAngularDistribution.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4EmModelManager.hh"
|
||||
class G4Timer;
|
||||
class G4AdjointBremsstrahlungModel: public G4VEmAdjointModel
|
||||
|
||||
class G4AdjointCSManager;
|
||||
class G4EmModelManager;
|
||||
class G4ParticleDefinition;
|
||||
|
||||
class G4AdjointBremsstrahlungModel : public G4VEmAdjointModel
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4AdjointBremsstrahlungModel(G4VEmModel* aModel);
|
||||
|
||||
G4AdjointBremsstrahlungModel(G4VEmModel* aModel);
|
||||
G4AdjointBremsstrahlungModel();
|
||||
~G4AdjointBremsstrahlungModel();
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
void RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
virtual G4double DiffCrossSectionPerVolumePrimToSecond(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
);
|
||||
G4double DiffCrossSectionPerVolumePrimToSecondApproximated1(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
);
|
||||
G4double DiffCrossSectionPerVolumePrimToSecondApproximated2(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
);
|
||||
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
virtual G4double GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
|
||||
// private void InitialiseFwdModels();
|
||||
|
||||
~G4AdjointBremsstrahlungModel() override;
|
||||
|
||||
private:
|
||||
G4VEmModel* theDirectStdBremModel;
|
||||
G4EmModelManager* theEmModelManagerForFwdModels;
|
||||
G4bool isDirectModelInitialised ;
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
G4double highKinEnergy;
|
||||
G4double lowKinEnergy, lastCZ;
|
||||
std::vector<G4DataVector*> partialSumSigma;
|
||||
std::vector<float> SigmaPerAtom;
|
||||
|
||||
void RapidSampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange);
|
||||
|
||||
G4double DiffCrossSectionPerVolumePrimToSecond(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before
|
||||
// the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
) override;
|
||||
|
||||
G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
G4AdjointBremsstrahlungModel(G4AdjointBremsstrahlungModel&) = delete;
|
||||
G4AdjointBremsstrahlungModel& operator=(
|
||||
const G4AdjointBremsstrahlungModel& right) = delete;
|
||||
|
||||
private:
|
||||
void Initialize();
|
||||
|
||||
G4EmModelManager* fEmModelManagerForFwdModels;
|
||||
G4AdjointCSManager* fCSManager;
|
||||
G4ParticleDefinition* fElectron;
|
||||
G4ParticleDefinition* fGamma;
|
||||
|
||||
G4double fLastCZ = 0.;
|
||||
|
||||
G4bool fIsDirectModelInitialised = false;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,245 +23,220 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointCSManager
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointCSManager
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 1st April 2007 creation by L. Desorgher
|
||||
//
|
||||
// September-October 2009. Implementation of the mode where the adjoint cross sections are scaled such that the total used adjoint cross sections is in
|
||||
// most of the cases equal to the total forward cross section. L.Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Is responsible for the management of all adjoint cross sections matrices, and for the computation of the total forward and adjoint cross sections.
|
||||
// Total adjoint and forward cross sections are needed to correct the weight of a particle after a tracking step or after the occurrence of a reverse reaction.
|
||||
// It is also used to sample an adjoint secondary from a given adjoint cross section matrix.
|
||||
// Class is responsible for the management of all adjoint cross section
|
||||
// matrices, and for the computation of the total forward and adjoint cross
|
||||
// sections. Total adjoint and forward cross sections are needed to correct the
|
||||
// weight of a particle after a tracking step or after the occurrence of a
|
||||
// reverse reaction. It is also used to sample an adjoint secondary from a
|
||||
// given adjoint cross section matrix.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointCSManager_h
|
||||
#define G4AdjointCSManager_h 1
|
||||
|
||||
#include"globals.hh"
|
||||
#include<vector>
|
||||
#include"G4AdjointCSMatrix.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
#include "G4ThreadLocalSingleton.hh"
|
||||
|
||||
class G4VEmAdjointModel;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4Material;
|
||||
class G4ParticleDefinition;
|
||||
class G4Element;
|
||||
class G4VEmProcess;
|
||||
class G4VEnergyLossProcess;
|
||||
class G4PhysicsTable;
|
||||
#include <vector>
|
||||
|
||||
class G4Element;
|
||||
class G4Material;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleDefinition;
|
||||
class G4PhysicsTable;
|
||||
class G4VEmProcess;
|
||||
class G4VEmAdjointModel;
|
||||
class G4VEnergyLossProcess;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class G4AdjointCSManager
|
||||
{
|
||||
|
||||
friend class G4ThreadLocalSingleton<G4AdjointCSManager>;
|
||||
|
||||
public:
|
||||
~G4AdjointCSManager();
|
||||
static G4AdjointCSManager* GetAdjointCSManager();
|
||||
|
||||
public:
|
||||
G4int GetNbProcesses();
|
||||
|
||||
//Registration of the different models and processes
|
||||
|
||||
size_t RegisterEmAdjointModel(G4VEmAdjointModel*);
|
||||
|
||||
void RegisterEmProcess(G4VEmProcess* aProcess, G4ParticleDefinition* aPartDef);
|
||||
|
||||
void RegisterEnergyLossProcess(G4VEnergyLossProcess* aProcess, G4ParticleDefinition* aPartDef);
|
||||
|
||||
void RegisterAdjointParticle(G4ParticleDefinition* aPartDef);
|
||||
|
||||
//Building of the CS Matrices and Total Forward and Adjoint LambdaTables
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void BuildCrossSectionMatrices();
|
||||
void BuildTotalSigmaTables();
|
||||
|
||||
|
||||
//Get TotalCrossSections form Total Lambda Tables, Needed for Weight correction and scaling of the
|
||||
//-------------------------------------------------
|
||||
G4double GetTotalAdjointCS(G4ParticleDefinition* aPartDef, G4double Ekin,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
G4double GetTotalForwardCS(G4ParticleDefinition* aPartDef, G4double Ekin,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
|
||||
G4double GetAdjointSigma(G4double Ekin_nuc, size_t index_model,G4bool is_scat_proj_to_proj,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
|
||||
void GetEminForTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple, G4double& emin_adj, G4double& emin_fwd);
|
||||
void GetMaxFwdTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple, G4double& e_sigma_max, G4double& sigma_max);
|
||||
void GetMaxAdjTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple, G4double& e_sigma_max, G4double& sigma_max);
|
||||
|
||||
|
||||
|
||||
//CrossSection Correction 1 or FwdCS/AdjCS following the G4boolean value of forward_CS_is_used and forward_CS_mode
|
||||
//-------------------------------------------------
|
||||
G4double GetCrossSectionCorrection(G4ParticleDefinition* aPartDef,G4double PreStepEkin,const G4MaterialCutsCouple* aCouple, G4bool& fwd_is_used, G4double& fwd_TotCS);
|
||||
|
||||
|
||||
//Cross section mode
|
||||
//------------------
|
||||
inline void SetFwdCrossSectionMode(G4bool aBool){forward_CS_mode=aBool;}
|
||||
|
||||
|
||||
//Weight correction
|
||||
//------------------
|
||||
|
||||
G4double GetContinuousWeightCorrection(G4ParticleDefinition* aPartDef, G4double PreStepEkin,G4double AfterStepEkin,
|
||||
const G4MaterialCutsCouple* aCouple, G4double step_length);
|
||||
G4double GetPostStepWeightCorrection();
|
||||
|
||||
|
||||
|
||||
|
||||
//Method Called by the adjoint model to get there CS, if not precised otherwise
|
||||
//-------------------------------
|
||||
|
||||
G4double ComputeAdjointCS(G4Material* aMaterial,
|
||||
G4VEmAdjointModel* aModel,
|
||||
G4double PrimEnergy,
|
||||
G4double Tcut,
|
||||
G4bool IsScatProjToProjCase,
|
||||
std::vector<G4double>&
|
||||
AdjointCS_for_each_element);
|
||||
|
||||
//Method Called by the adjoint model to sample the secondary energy form the CS matrix
|
||||
//--------------------------------------------------------------------------------
|
||||
G4Element* SampleElementFromCSMatrices(G4Material* aMaterial,
|
||||
G4VEmAdjointModel* aModel,
|
||||
G4double PrimEnergy,
|
||||
G4double Tcut,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
|
||||
//Total Adjoint CS is computed at initialisation phase
|
||||
//-----------------------------------------------------
|
||||
G4double ComputeTotalAdjointCS(const G4MaterialCutsCouple* aMatCutCouple,G4ParticleDefinition* aPart,G4double PrimEnergy);
|
||||
|
||||
|
||||
|
||||
|
||||
G4ParticleDefinition* GetAdjointParticleEquivalent(G4ParticleDefinition* theFwdPartDef);
|
||||
G4ParticleDefinition* GetForwardParticleEquivalent(G4ParticleDefinition* theAdjPartDef);
|
||||
|
||||
//inline
|
||||
inline void SetTmin(G4double aVal){Tmin=aVal;}
|
||||
inline void SetTmax(G4double aVal){Tmax=aVal;}
|
||||
inline void SetNbins(G4int aInt){nbins=aInt;}
|
||||
inline void SetIon(G4ParticleDefinition* adjIon,
|
||||
G4ParticleDefinition* fwdIon) {theAdjIon=adjIon; theFwdIon =fwdIon;}
|
||||
|
||||
|
||||
private:
|
||||
static G4ThreadLocal G4AdjointCSManager* theInstance;
|
||||
std::vector< std::vector<G4AdjointCSMatrix*> > theAdjointCSMatricesForScatProjToProj; //x dim is for G4VAdjointEM*, y dim is for elements
|
||||
std::vector< std::vector<G4AdjointCSMatrix*> > theAdjointCSMatricesForProdToProj;
|
||||
std::vector< G4VEmAdjointModel*> listOfAdjointEMModel;
|
||||
|
||||
std::vector<G4AdjointCSMatrix*>
|
||||
BuildCrossSectionsMatricesForAGivenModelAndElement(G4VEmAdjointModel* aModel,
|
||||
G4int Z,
|
||||
G4int A,
|
||||
G4int nbin_pro_decade);
|
||||
|
||||
std::vector<G4AdjointCSMatrix*>
|
||||
BuildCrossSectionsMatricesForAGivenModelAndMaterial(G4VEmAdjointModel* aModel,
|
||||
G4Material* aMaterial,
|
||||
G4int nbin_pro_decade);
|
||||
|
||||
|
||||
G4Material* lastMaterial;
|
||||
G4double lastPrimaryEnergy;
|
||||
G4double lastTcut;
|
||||
std::vector< size_t> listOfIndexOfAdjointEMModelInAction;
|
||||
std::vector< G4bool> listOfIsScatProjToProjCase;
|
||||
std::vector< std::vector<G4double> > lastAdjointCSVsModelsAndElements;
|
||||
G4bool CrossSectionMatrixesAreBuilt;
|
||||
size_t currentParticleIndex;
|
||||
G4ParticleDefinition* currentParticleDef;
|
||||
|
||||
//total adjoint and total forward cross section table in function of material and in function of adjoint particle type
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
std::vector<G4PhysicsTable*> theTotalForwardSigmaTableVector;
|
||||
std::vector<G4PhysicsTable*> theTotalAdjointSigmaTableVector;
|
||||
std::vector< std::vector<G4double> > EminForFwdSigmaTables;
|
||||
std::vector< std::vector<G4double> > EminForAdjSigmaTables;
|
||||
std::vector< std::vector<G4double> > EkinofFwdSigmaMax;
|
||||
std::vector< std::vector<G4double> > EkinofAdjSigmaMax;
|
||||
G4bool TotalSigmaTableAreBuilt;
|
||||
|
||||
//Sigma tavle for each G4VAdjointEMModel
|
||||
std::vector<G4PhysicsTable*> listSigmaTableForAdjointModelScatProjToProj;
|
||||
std::vector<G4PhysicsTable*> listSigmaTableForAdjointModelProdToProj;
|
||||
|
||||
//list of forward G4VEMLossProcess and of G4VEMProcess for the different adjoint particle
|
||||
//--------------------------------------------------------------
|
||||
std::vector< std::vector<G4VEmProcess*>* > listOfForwardEmProcess;
|
||||
std::vector< std::vector<G4VEnergyLossProcess*>* > listOfForwardEnergyLossProcess;
|
||||
|
||||
//list of adjoint particles considered
|
||||
//--------------------------------------------------------------
|
||||
std::vector< G4ParticleDefinition*> theListOfAdjointParticlesInAction;
|
||||
|
||||
G4double Tmin,Tmax;
|
||||
G4int nbins;
|
||||
|
||||
//Current material
|
||||
//----------------
|
||||
G4MaterialCutsCouple* currentCouple;
|
||||
G4Material* currentMaterial;
|
||||
size_t currentMatIndex;
|
||||
|
||||
G4int verbose;
|
||||
|
||||
//Two CS mode are possible :forward_CS_mode = false the Adjoint CS are used as it is implying a AlongStep Weight Correction.
|
||||
// :forward_CS_mode = true the Adjoint CS are scaled to have the total adjoint CS eual to the fwd one implying a PostStep Weight Correction.
|
||||
// For energy range where the total FwdCS or the total adjoint CS are null, the scaling is not possble and
|
||||
// forward_CS_is_used is set to false
|
||||
//--------------------------------------------
|
||||
G4bool forward_CS_is_used;
|
||||
G4bool forward_CS_mode;
|
||||
|
||||
//Adj and Fwd CS values for re-use
|
||||
//------------------------
|
||||
|
||||
G4double PreadjCS,PostadjCS;
|
||||
G4double PrefwdCS,PostfwdCS;
|
||||
G4double LastEkinForCS;
|
||||
G4double LastCSCorrectionFactor;
|
||||
G4ParticleDefinition* lastPartDefForCS;
|
||||
|
||||
//Ion
|
||||
//----------------
|
||||
G4ParticleDefinition* theAdjIon; //at the moment Only one ion can be considered by simulation
|
||||
G4ParticleDefinition* theFwdIon;
|
||||
G4double massRatio;
|
||||
|
||||
private:
|
||||
G4AdjointCSManager();
|
||||
void DefineCurrentMaterial(const G4MaterialCutsCouple* couple);
|
||||
void DefineCurrentParticle(const G4ParticleDefinition* aPartDef);
|
||||
G4double ComputeAdjointCS(G4double aPrimEnergy, G4AdjointCSMatrix* anAdjointCSMatrix, G4double Tcut);
|
||||
size_t eindex;
|
||||
public:
|
||||
~G4AdjointCSManager();
|
||||
static G4AdjointCSManager* GetAdjointCSManager();
|
||||
|
||||
G4int GetNbProcesses();
|
||||
|
||||
// Registration of the different models and processes
|
||||
|
||||
size_t RegisterEmAdjointModel(G4VEmAdjointModel*);
|
||||
|
||||
void RegisterEmProcess(G4VEmProcess* aProcess,
|
||||
G4ParticleDefinition* aPartDef);
|
||||
|
||||
void RegisterEnergyLossProcess(G4VEnergyLossProcess* aProcess,
|
||||
G4ParticleDefinition* aPartDef);
|
||||
|
||||
void RegisterAdjointParticle(G4ParticleDefinition* aPartDef);
|
||||
|
||||
// Building of the CS Matrices and Total Forward and Adjoint LambdaTables
|
||||
void BuildCrossSectionMatrices();
|
||||
|
||||
void BuildTotalSigmaTables();
|
||||
|
||||
// Get TotalCrossSections form Total Lambda Tables, Needed for Weight
|
||||
// correction and scaling of the
|
||||
G4double GetTotalAdjointCS(G4ParticleDefinition* aPartDef, G4double Ekin,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
|
||||
G4double GetTotalForwardCS(G4ParticleDefinition* aPartDef, G4double Ekin,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
|
||||
G4double GetAdjointSigma(G4double Ekin_nuc, size_t index_model,
|
||||
G4bool is_scat_proj_to_proj,
|
||||
const G4MaterialCutsCouple* aCouple);
|
||||
|
||||
void GetEminForTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple,
|
||||
G4double& emin_adj, G4double& emin_fwd);
|
||||
|
||||
void GetMaxFwdTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple,
|
||||
G4double& e_sigma_max, G4double& sigma_max);
|
||||
|
||||
void GetMaxAdjTotalCS(G4ParticleDefinition* aPartDef,
|
||||
const G4MaterialCutsCouple* aCouple,
|
||||
G4double& e_sigma_max, G4double& sigma_max);
|
||||
|
||||
// CrossSection Correction 1 or FwdCS/AdjCS following the G4boolean value of
|
||||
// forward_CS_is_used and forward_CS_mode
|
||||
G4double GetCrossSectionCorrection(G4ParticleDefinition* aPartDef,
|
||||
G4double PreStepEkin,
|
||||
const G4MaterialCutsCouple* aCouple,
|
||||
G4bool& fwd_is_used);
|
||||
|
||||
// Cross section mode
|
||||
inline void SetFwdCrossSectionMode(G4bool aBool) { fForwardCSMode = aBool; }
|
||||
|
||||
// Weight correction
|
||||
G4double GetContinuousWeightCorrection(G4ParticleDefinition* aPartDef,
|
||||
G4double PreStepEkin,
|
||||
G4double AfterStepEkin,
|
||||
const G4MaterialCutsCouple* aCouple,
|
||||
G4double step_length);
|
||||
|
||||
G4double GetPostStepWeightCorrection();
|
||||
|
||||
// called by the adjoint model to get the CS, if not otherwise specified
|
||||
G4double ComputeAdjointCS(G4Material* aMaterial, G4VEmAdjointModel* aModel,
|
||||
G4double PrimEnergy, G4double Tcut,
|
||||
G4bool isScatProjToProj,
|
||||
std::vector<G4double>& AdjointCS_for_each_element);
|
||||
|
||||
// called by the adjoint model to sample secondary energy from the CS matrix
|
||||
G4Element* SampleElementFromCSMatrices(G4Material* aMaterial,
|
||||
G4VEmAdjointModel* aModel,
|
||||
G4double PrimEnergy, G4double Tcut,
|
||||
G4bool isScatProjToProj);
|
||||
|
||||
// Total Adjoint CS is computed at initialisation phase
|
||||
G4double ComputeTotalAdjointCS(const G4MaterialCutsCouple* aMatCutCouple,
|
||||
G4ParticleDefinition* aPart,
|
||||
G4double PrimEnergy);
|
||||
|
||||
G4ParticleDefinition* GetAdjointParticleEquivalent(
|
||||
G4ParticleDefinition* theFwdPartDef);
|
||||
|
||||
G4ParticleDefinition* GetForwardParticleEquivalent(
|
||||
G4ParticleDefinition* theAdjPartDef);
|
||||
|
||||
// inline
|
||||
inline void SetIon(G4ParticleDefinition* adjIon, G4ParticleDefinition* fwdIon)
|
||||
{
|
||||
fAdjIon = adjIon;
|
||||
fFwdIon = fwdIon;
|
||||
}
|
||||
|
||||
private:
|
||||
G4AdjointCSManager();
|
||||
|
||||
void DefineCurrentMaterial(const G4MaterialCutsCouple* couple);
|
||||
|
||||
void DefineCurrentParticle(const G4ParticleDefinition* aPartDef);
|
||||
|
||||
G4double ComputeAdjointCS(G4double aPrimEnergy,
|
||||
G4AdjointCSMatrix* anAdjointCSMatrix,
|
||||
G4double Tcut);
|
||||
|
||||
std::vector<G4AdjointCSMatrix*> BuildCrossSectionsModelAndElement(
|
||||
G4VEmAdjointModel* aModel, G4int Z, G4int A, G4int nbin_pro_decade);
|
||||
|
||||
std::vector<G4AdjointCSMatrix*> BuildCrossSectionsModelAndMaterial(
|
||||
G4VEmAdjointModel* aModel, G4Material* aMaterial, G4int nbin_pro_decade);
|
||||
|
||||
static constexpr G4double fTmin = 0.1 * CLHEP::keV;
|
||||
static constexpr G4double fTmax = 100. * CLHEP::TeV;
|
||||
// fNbins chosen to avoid error
|
||||
// in the CS value close to CS jump. (For example at Tcut)
|
||||
static constexpr G4int fNbins = 320;
|
||||
|
||||
static G4ThreadLocal G4AdjointCSManager* fInstance;
|
||||
|
||||
// only one ion can be considered by simulation
|
||||
G4ParticleDefinition* fAdjIon = nullptr;
|
||||
G4ParticleDefinition* fFwdIon = nullptr;
|
||||
|
||||
G4MaterialCutsCouple* fCurrentCouple = nullptr;
|
||||
G4Material* fCurrentMaterial = nullptr;
|
||||
|
||||
// x dim is for G4VAdjointEM*, y dim is for elements
|
||||
std::vector<std::vector<G4AdjointCSMatrix*>>
|
||||
fAdjointCSMatricesForScatProjToProj;
|
||||
|
||||
std::vector<std::vector<G4AdjointCSMatrix*>> fAdjointCSMatricesForProdToProj;
|
||||
|
||||
std::vector<G4VEmAdjointModel*> fAdjointModels;
|
||||
|
||||
std::vector<size_t> fIndexOfAdjointEMModelInAction;
|
||||
std::vector<G4bool> fIsScatProjToProj;
|
||||
std::vector<std::vector<G4double>> fLastAdjointCSVsModelsAndElements;
|
||||
|
||||
// total adjoint and total forward cross section table in function of material
|
||||
// and in function of adjoint particle type
|
||||
std::vector<G4PhysicsTable*> fTotalFwdSigmaTable;
|
||||
std::vector<G4PhysicsTable*> fTotalAdjSigmaTable;
|
||||
|
||||
// Sigma table for each G4VAdjointEMModel
|
||||
std::vector<G4PhysicsTable*> fSigmaTableForAdjointModelScatProjToProj;
|
||||
std::vector<G4PhysicsTable*> fSigmaTableForAdjointModelProdToProj;
|
||||
|
||||
std::vector<std::vector<G4double>> fEminForFwdSigmaTables;
|
||||
std::vector<std::vector<G4double>> fEminForAdjSigmaTables;
|
||||
std::vector<std::vector<G4double>> fEkinofFwdSigmaMax;
|
||||
std::vector<std::vector<G4double>> fEkinofAdjSigmaMax;
|
||||
|
||||
// list of forward G4VEmProcess and of G4VEnergyLossProcess for the different
|
||||
// adjoint particle
|
||||
std::vector<std::vector<G4VEmProcess*>*> fForwardProcesses;
|
||||
std::vector<std::vector<G4VEnergyLossProcess*>*> fForwardLossProcesses;
|
||||
|
||||
// list of adjoint particles considered
|
||||
std::vector<G4ParticleDefinition*> fAdjointParticlesInAction;
|
||||
|
||||
G4double fMassRatio = 1.; // ion
|
||||
G4double fLastCSCorrectionFactor = 1.;
|
||||
|
||||
size_t fCurrentParticleIndex = 0;
|
||||
size_t fCurrentMatIndex = 0;
|
||||
|
||||
G4bool fCSMatricesBuilt = false;
|
||||
G4bool fSigmaTableBuilt = false;
|
||||
G4bool fForwardCSUsed = true;
|
||||
G4bool fForwardCSMode = true;
|
||||
// Two CS mode are possible:
|
||||
// 1) fForwardCSMode = false, the Adjoint CS are used as it is implying
|
||||
// an AlongStep Weight Correction.
|
||||
// 2) fForwardCSMode = true, the Adjoint CS are scaled to have the total
|
||||
// adjoint CS equal to the fwd one implying a PostStep Weight Correction.
|
||||
// For energies where the total Fwd CS or the total adjoint CS are zero,
|
||||
// the scaling is not possible and fForwardCSUsed is set to false
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -23,82 +23,78 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointCSMatrix
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointCSMatrix.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 1st April 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// An adjoint CS matrix is used by the model of a reverse process to sample an adjoint secondary (being equivalent to a forward primary).
|
||||
// It represents the integration over the energy of the adjoint secondary (therefore the forward primary) of the differential cross section
|
||||
// of the equiavlent forward discrete process (Ionisation, Brem, PE effect, Compton,..) . Each reverse model has its own cross section matrix for a given cut,
|
||||
// material couple. It is therefore recompute after a modification of the cuts by the user.
|
||||
//
|
||||
//
|
||||
// An adjoint CS matrix is used by the model of a reverse process to sample
|
||||
// an adjoint secondary (being equivalent to a forward primary). It represents
|
||||
// the integration over the energy of the adjoint secondary (therefore the
|
||||
// forward primary) of the differential cross section of the equivalent forward
|
||||
// discrete process (Ionisation, Brem, PE effect, Compton,..). Each reverse
|
||||
// model has its own cross section matrix for a given cut, material couple. It
|
||||
// is therefore recomputed after a modification of the cuts by the user.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointCSMatrix_h
|
||||
#define G4AdjointCSMatrix_h 1
|
||||
|
||||
#include"globals.hh"
|
||||
#include<vector>
|
||||
#include"G4ParticleDefinition.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class G4AdjointCSMatrix
|
||||
{
|
||||
////////////////////////////////
|
||||
// Constructors and Destructor
|
||||
////////////////////////////////
|
||||
public:
|
||||
G4AdjointCSMatrix(G4bool aBool);
|
||||
~G4AdjointCSMatrix();
|
||||
public:
|
||||
G4AdjointCSMatrix(G4bool aBool);
|
||||
~G4AdjointCSMatrix();
|
||||
|
||||
//////////////
|
||||
// Methods //
|
||||
//////////////
|
||||
void Clear();
|
||||
void AddData(G4double aPrimEnergy,G4double aCS, std::vector< double>* aLogSecondEnergyVector,
|
||||
std::vector< double>* aLogProbVector,size_t n_pro_decade=0);
|
||||
|
||||
G4bool GetData(unsigned int i, G4double& aPrimEnergy,G4double& aCS,G4double& log0, std::vector< double>*& aLogSecondEnergyVector,
|
||||
std::vector< double>*& aLogProbVector,
|
||||
std::vector< size_t>*& aLogProbVectorIndex);
|
||||
|
||||
inline std::vector< double>* GetLogPrimEnergyVector(){return &theLogPrimEnergyVector;}
|
||||
inline std::vector< double>* GetLogCrossSectionvector(){return &theLogCrossSectionVector;}
|
||||
inline G4double GetDlog(){return dlog;}
|
||||
inline G4bool IsScatProjToProjCase(){return is_scat_proj_to_proj_case;}
|
||||
void Write(G4String file_name);
|
||||
void Read(G4String file_name);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
|
||||
// we did first try to use G4PhysicsOrderedVector but they are not general enough for our purpose
|
||||
|
||||
std::vector< double> theLogPrimEnergyVector;
|
||||
std::vector< double> theLogCrossSectionVector; //Adjoint Cross sections in function of primary energy
|
||||
std::vector< std::vector< double>* > theLogSecondEnergyMatrix;
|
||||
std::vector< std::vector< double>* > theLogProbMatrix; //Each column represents the integrated probability of getting a secondary
|
||||
// in function of their energy
|
||||
std::vector< std::vector< size_t >* > theLogProbMatrixIndex; //index of equidistant LogProb
|
||||
std::vector< double> log0Vector;
|
||||
|
||||
unsigned int nb_of_PrimEnergy;
|
||||
G4bool is_scat_proj_to_proj_case;
|
||||
G4double dlog;
|
||||
|
||||
void AddData(G4double aPrimEnergy, G4double aCS,
|
||||
std::vector<double>* aLogSecondEnergyVector,
|
||||
std::vector<double>* aLogProbVector, size_t n_pro_decade = 0);
|
||||
|
||||
G4bool GetData(unsigned int i, G4double& aPrimEnergy, G4double& aCS,
|
||||
G4double& log0, std::vector<double>*& aLogSecondEnergyVector,
|
||||
std::vector<double>*& aLogProbVector,
|
||||
std::vector<size_t>*& aLogProbVectorIndex);
|
||||
|
||||
inline std::vector<double>* GetLogPrimEnergyVector()
|
||||
{
|
||||
return &fLogPrimEnergyVector;
|
||||
}
|
||||
|
||||
inline std::vector<double>* GetLogCrossSectionvector()
|
||||
{
|
||||
return &fLogCrossSectionVector;
|
||||
}
|
||||
|
||||
inline G4bool IsScatProjToProj() { return fScatProjToProj; }
|
||||
|
||||
void Write(G4String file_name);
|
||||
|
||||
void Read(G4String file_name);
|
||||
|
||||
private:
|
||||
std::vector<double> fLogPrimEnergyVector;
|
||||
// Adjoint Cross sections as functions of primary energy
|
||||
std::vector<double> fLogCrossSectionVector;
|
||||
|
||||
std::vector<std::vector<double>*> fLogSecondEnergyMatrix;
|
||||
std::vector<std::vector<double>*> fLogProbMatrix;
|
||||
// Each column represents the integrated probability of
|
||||
// getting a secondary
|
||||
|
||||
// index of equidistant LogProb
|
||||
std::vector<std::vector<size_t>*> fLogProbMatrixIndex;
|
||||
std::vector<double> fLog0Vector;
|
||||
|
||||
size_t fNbPrimEnergy = 0;
|
||||
|
||||
G4bool fScatProjToProj;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -23,81 +23,64 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointComptonModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointComptonModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 1 September 2007 creation by L. Desorgher
|
||||
// 11 November 2009 Implement the use of approximated diffCS as an alternative of CSMatrix.
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Model for the adjoint compton scattering.
|
||||
//
|
||||
// Model for the adjoint compton scattering.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointComptonModel_h
|
||||
#define G4AdjointComptonModel_h 1
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
class G4AdjointComptonModel: public G4VEmAdjointModel
|
||||
|
||||
class G4VEmProcess;
|
||||
|
||||
class G4AdjointComptonModel : public G4VEmAdjointModel
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
G4AdjointComptonModel();
|
||||
~G4AdjointComptonModel();
|
||||
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
void RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToScatPrim(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyScatProj, // kinetic energy of the primary particle after the interaction
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy);
|
||||
|
||||
|
||||
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
virtual G4double GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
~G4AdjointComptonModel() override;
|
||||
|
||||
|
||||
|
||||
inline void SetDirectProcess(G4VEmProcess* aProcess){theDirectEMProcess = aProcess;};
|
||||
|
||||
private:
|
||||
G4VEmProcess* theDirectEMProcess;
|
||||
G4double G4direct_CS;
|
||||
|
||||
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
void RapidSampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange);
|
||||
|
||||
G4double DiffCrossSectionPerAtomPrimToScatPrim(
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyScatProj, // kin energy of primary after interaction
|
||||
G4double Z, G4double A = 0.) override;
|
||||
|
||||
G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd, // kin energy of secondary particle
|
||||
G4double Z, G4double A = 0.) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy) override;
|
||||
G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy) override;
|
||||
|
||||
G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
inline void SetDirectProcess(G4VEmProcess* aProcess)
|
||||
{
|
||||
fDirectProcess = aProcess;
|
||||
};
|
||||
|
||||
G4AdjointComptonModel(G4AdjointComptonModel&) = delete;
|
||||
G4AdjointComptonModel& operator=(const G4AdjointComptonModel& right) = delete;
|
||||
|
||||
private:
|
||||
G4VEmProcess* fDirectProcess = nullptr;
|
||||
|
||||
G4double fDirectCS = 0.;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+58
-78
@@ -23,109 +23,89 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4AdjointForcedInteractionForGamma
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// Class: G4AdjointForcedInteractionForGamma
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
// Class for the forced interaction of reverse gamma
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 12 September 2016 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Class for the forced interaction of reverse gamma
|
||||
//
|
||||
|
||||
#ifndef G4AdjointForcedInteractionForGamma_h
|
||||
#define G4AdjointForcedInteractionForGamma_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VContinuousDiscreteProcess.hh"
|
||||
#include"G4PhysicsOrderedFreeVector.hh"
|
||||
|
||||
|
||||
class G4PhysicsTable;
|
||||
class G4Region;
|
||||
class G4VParticleChange;
|
||||
class G4ParticleChange;
|
||||
class G4ParticleDefinition;
|
||||
class G4Track;
|
||||
class G4VEmAdjointModel;
|
||||
class G4AdjointCSMatrix;
|
||||
class G4AdjointCSManager;
|
||||
class G4Material;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4Navigator;
|
||||
|
||||
class G4AdjointForcedInteractionForGamma : public G4VContinuousDiscreteProcess
|
||||
{
|
||||
public:
|
||||
explicit G4AdjointForcedInteractionForGamma(G4String process_name);
|
||||
|
||||
public:
|
||||
~G4AdjointForcedInteractionForGamma() override;
|
||||
|
||||
G4AdjointForcedInteractionForGamma(G4String process_name);
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&) override;
|
||||
|
||||
virtual ~G4AdjointForcedInteractionForGamma();
|
||||
|
||||
public:
|
||||
void PreparePhysicsTable(const G4ParticleDefinition&);
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
virtual G4double PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition);
|
||||
virtual G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
|
||||
virtual G4VParticleChange* AlongStepDoIt(const G4Track& track,const G4Step& step);
|
||||
inline void RegisterAdjointComptonModel(G4VEmAdjointModel* aAdjointComptonModel){theAdjointComptonModel = aAdjointComptonModel;}
|
||||
inline void RegisterAdjointBremModel(G4VEmAdjointModel* aAdjointBremModel){theAdjointBremModel = aAdjointBremModel;}
|
||||
|
||||
protected :// with description
|
||||
G4double PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize,
|
||||
G4ForceCondition* condition) override;
|
||||
|
||||
virtual G4double GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition);
|
||||
virtual G4double GetContinuousStepLimit(const G4Track& aTrack,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety
|
||||
);
|
||||
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&) override;
|
||||
|
||||
private:
|
||||
G4VEmAdjointModel* theAdjointComptonModel;
|
||||
G4VEmAdjointModel* theAdjointBremModel;
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& step) override;
|
||||
|
||||
G4ParticleChange* fParticleChange;
|
||||
G4AdjointCSManager* theAdjointCSManager;
|
||||
|
||||
private:
|
||||
G4double lastAdjCS,lastFwdCS;
|
||||
inline void RegisterAdjointComptonModel(G4VEmAdjointModel* adjModel)
|
||||
{
|
||||
fAdjointComptonModel = adjModel;
|
||||
}
|
||||
|
||||
G4int trackid;
|
||||
G4int nstep;
|
||||
G4bool is_free_flight_gamma;
|
||||
G4bool copy_gamma_for_forced_interaction;
|
||||
G4int last_free_flight_trackid;
|
||||
inline void RegisterAdjointBremModel(G4VEmAdjointModel* adjModel)
|
||||
{
|
||||
fAdjointBremModel = adjModel;
|
||||
}
|
||||
|
||||
G4double acc_track_length;
|
||||
G4double total_acc_nb_adj_interaction_length;
|
||||
G4double total_acc_nb_fwd_interaction_length;
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4AdjointForcedInteractionForGamma(G4AdjointForcedInteractionForGamma&) =
|
||||
delete;
|
||||
G4AdjointForcedInteractionForGamma& operator=(
|
||||
const G4AdjointForcedInteractionForGamma& right) = delete;
|
||||
|
||||
G4double acc_nb_adj_interaction_length;
|
||||
G4double acc_nb_fwd_interaction_length;
|
||||
G4bool continue_gamma_as_new_free_flight;
|
||||
};
|
||||
protected:
|
||||
G4double GetMeanFreePath(const G4Track& track, G4double previousStepSize,
|
||||
G4ForceCondition* condition) override;
|
||||
|
||||
G4double GetContinuousStepLimit(const G4Track& aTrack,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety) override;
|
||||
|
||||
private:
|
||||
G4VEmAdjointModel* fAdjointComptonModel;
|
||||
G4VEmAdjointModel* fAdjointBremModel;
|
||||
|
||||
G4ParticleChange* fParticleChange;
|
||||
G4AdjointCSManager* fCSManager;
|
||||
|
||||
G4double fLastAdjCS = 0.;
|
||||
|
||||
G4double fAccTrackLength = 0.;
|
||||
G4double fTotNbAdjIntLength = 0.;
|
||||
|
||||
G4double fNbAdjIntLength = 0.;
|
||||
|
||||
G4bool fContinueGammaAsNewFreeFlight = false;
|
||||
G4bool fFreeFlightGamma = false;
|
||||
G4bool fCopyGammaForForced = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,77 +23,67 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointInterpolator
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4AdjointInterpolator
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 1st April 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Used by G4AdjointCSManager for interpolation purpose.
|
||||
//
|
||||
// Used by G4AdjointCSManager for interpolation purpose.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointInterpolator_h
|
||||
#define G4AdjointInterpolator_h 1
|
||||
|
||||
#include"globals.hh"
|
||||
#include<vector>
|
||||
#include "globals.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class G4AdjointInterpolator
|
||||
{
|
||||
|
||||
public:
|
||||
static G4AdjointInterpolator* GetAdjointInterpolator();
|
||||
static G4AdjointInterpolator* GetInstance();
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////
|
||||
// Constructors and Destructor
|
||||
////////////////////////////////
|
||||
|
||||
|
||||
~G4AdjointInterpolator();
|
||||
public:
|
||||
static G4AdjointInterpolator* GetAdjointInterpolator();
|
||||
static G4AdjointInterpolator* GetInstance();
|
||||
|
||||
////////////
|
||||
// Methods
|
||||
////////////
|
||||
|
||||
//Caution everywher it is considere thta x_vec increase monotically
|
||||
|
||||
G4double LinearInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2);
|
||||
G4double LogarithmicInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2);
|
||||
G4double ExponentialInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2);
|
||||
G4double Interpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double &y2,G4String InterPolMethod="Log");
|
||||
|
||||
|
||||
size_t FindPosition(G4double& x,std::vector<G4double>& x_vec,size_t ind_min=0, size_t ind_max=0);
|
||||
|
||||
size_t FindPositionForLogVector(G4double& x,std::vector<G4double>& x_vec);
|
||||
|
||||
G4double Interpolate(G4double& x,std::vector<G4double>& x_vec,std::vector<G4double>& y_vec,G4String InterPolMethod="Log"); //xvec should monotically increase
|
||||
|
||||
G4double InterpolateWithIndexVector(G4double& x,std::vector<G4double>& x_vec,std::vector<G4double>& y_vec,
|
||||
std::vector<size_t>& index_vec, G4double x0,G4double dx); //xvec should monotically increase
|
||||
|
||||
|
||||
G4double InterpolateForLogVector(G4double& x,std::vector<G4double>& x_vec,std::vector<G4double>& y_vec);
|
||||
|
||||
private:
|
||||
static G4ThreadLocal G4AdjointInterpolator* theInstance;
|
||||
|
||||
private:
|
||||
G4AdjointInterpolator();
|
||||
|
||||
~G4AdjointInterpolator();
|
||||
|
||||
// Caution: everywhere it is considered that x_vec increases monotically
|
||||
|
||||
G4double LinearInterpolation(G4double& x, G4double& x1, G4double& x2,
|
||||
G4double& y1, G4double& y2);
|
||||
|
||||
G4double LogarithmicInterpolation(G4double& x, G4double& x1, G4double& x2,
|
||||
G4double& y1, G4double& y2);
|
||||
|
||||
G4double ExponentialInterpolation(G4double& x, G4double& x1, G4double& x2,
|
||||
G4double& y1, G4double& y2);
|
||||
|
||||
G4double Interpolation(G4double& x, G4double& x1, G4double& x2, G4double& y1,
|
||||
G4double& y2, G4String InterPolMethod = "Log");
|
||||
|
||||
size_t FindPosition(G4double& x, std::vector<G4double>& x_vec,
|
||||
size_t ind_min = 0, size_t ind_max = 0);
|
||||
|
||||
size_t FindPositionForLogVector(G4double& x, std::vector<G4double>& x_vec);
|
||||
|
||||
// xvec should monotically increase
|
||||
G4double Interpolate(G4double& x, std::vector<G4double>& x_vec,
|
||||
std::vector<G4double>& y_vec,
|
||||
G4String InterPolMethod = "Log");
|
||||
|
||||
G4double InterpolateWithIndexVector(
|
||||
G4double& x, std::vector<G4double>& x_vec, std::vector<G4double>& y_vec,
|
||||
std::vector<size_t>& index_vec, G4double x0,
|
||||
G4double dx); // xvec should monotically increase
|
||||
|
||||
G4double InterpolateForLogVector(G4double& x, std::vector<G4double>& x_vec,
|
||||
std::vector<G4double>& y_vec);
|
||||
|
||||
G4AdjointInterpolator(G4AdjointInterpolator&) = delete;
|
||||
G4AdjointInterpolator& operator=(const G4AdjointInterpolator& right) = delete;
|
||||
|
||||
private:
|
||||
G4AdjointInterpolator();
|
||||
|
||||
static G4ThreadLocal G4AdjointInterpolator* fInstance;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -23,124 +23,82 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4IonIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// Class: G4IonIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
// Adjoint EM model for discrete reverse ion ionisation
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 26th August 2009 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint EM model for discrete reverse ion ionisation
|
||||
//
|
||||
|
||||
#ifndef G4AdjointIonIonisationModel_h
|
||||
#define G4AdjointIonIonisationModel_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
class G4PhysicsTable;
|
||||
class G4Region;
|
||||
class G4VParticleChange;
|
||||
class G4ParticleChange;
|
||||
|
||||
class G4Track;
|
||||
class G4AdjointCSMatrix;
|
||||
class G4ParticleChange;
|
||||
class G4ParticleDefinition;
|
||||
class G4VEmModel;
|
||||
class G4VParticleChange;
|
||||
|
||||
|
||||
class G4AdjointIonIonisationModel: public G4VEmAdjointModel
|
||||
class G4AdjointIonIonisationModel : public G4VEmAdjointModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
G4AdjointIonIonisationModel();
|
||||
|
||||
virtual ~G4AdjointIonIonisationModel();
|
||||
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
~G4AdjointIonIonisationModel() override;
|
||||
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z, G4double A = 0.) override;
|
||||
|
||||
void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight, G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMinForScatProjToProj(G4double primAdjEnergy,
|
||||
G4double tcut = 0.) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy) override;
|
||||
|
||||
inline void SetUseOnlyBragg(G4bool aBool) { fUseOnlyBragg = aBool; }
|
||||
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
|
||||
virtual void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight,
|
||||
G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
//Set/Get methods
|
||||
//------------------
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForScatProjToProjCase(G4double PrimAdjEnergy,G4double Tcut=0);
|
||||
virtual G4double GetSecondAdjEnergyMaxForProdToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy);
|
||||
|
||||
inline void SetUseOnlyBragg(G4bool aBool){use_only_bragg =aBool;}
|
||||
|
||||
|
||||
void SetIon(G4ParticleDefinition* adj_ion, G4ParticleDefinition* fwd_ion);
|
||||
|
||||
|
||||
private: //Methods
|
||||
|
||||
|
||||
G4AdjointIonIonisationModel(G4AdjointIonIonisationModel&) = delete;
|
||||
G4AdjointIonIonisationModel& operator=(
|
||||
const G4AdjointIonIonisationModel& right) = delete;
|
||||
|
||||
private:
|
||||
void DefineProjectileProperty();
|
||||
|
||||
//projectile property
|
||||
G4double mass;
|
||||
G4double tlimit;
|
||||
G4double spin;
|
||||
G4double magMoment2;
|
||||
G4double chargeSquare;
|
||||
G4double massRatio;
|
||||
|
||||
G4double ratio, ratio2;
|
||||
G4double one_plus_ratio_2;
|
||||
G4double formfact;
|
||||
G4bool isIon;
|
||||
G4double one_minus_ratio_2;
|
||||
|
||||
G4bool use_only_bragg;
|
||||
|
||||
|
||||
G4VEmModel* theBraggIonDirectEMModel;
|
||||
G4VEmModel* theBetheBlochDirectEMModel;
|
||||
|
||||
|
||||
G4VEmModel* fBraggIonDirectEMModel;
|
||||
G4VEmModel* fBetheBlochDirectEMModel;
|
||||
|
||||
|
||||
|
||||
// projectile properties
|
||||
G4double fMass = 0.;
|
||||
G4double fSpin = 0.;
|
||||
G4double fMagMoment2 = 0.;
|
||||
G4double fChargeSquare = 0.;
|
||||
G4double fMassRatio = 0.;
|
||||
G4double fRatio = 0.;
|
||||
G4double fOnePlusRatio2 = 0.;
|
||||
G4double fOneMinusRatio2 = 0.;
|
||||
G4double fFormFact = 0.;
|
||||
|
||||
|
||||
G4bool fUseOnlyBragg = false;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,96 +23,72 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointPhotoElectricModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4AdjointPhotoElectricModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// -1 September 2007 creation by L. Desorgher
|
||||
//
|
||||
// -January 2009. L. Desorgher
|
||||
// Put a higher limit on the CS to avoid a high rate of Inverse Photo e- effect at low energy. The very high adjoint CS of the reverse
|
||||
// photo electric reaction produce a high rate of reverse photo electric reaction in the inner side of a shielding for eaxmple, the correction of this occurrence
|
||||
// by weight correction in the StepDoIt method is not statistically sufficient at small energy. The problem is partially solved by setting an higher CS limit
|
||||
// and compensating it by an extra weight correction factor. However when coupling it with other reverse processes the reverse photo-electric is still
|
||||
// the source of very occasional high weight that decrease the efficiency of the computation. A way to solve this problemn is still needed but is difficult
|
||||
// to find as it happens in rarea case but does give a weighrt that is outside the noemal distribution. (Very Tricky!)
|
||||
//
|
||||
// -October 2009 Correction of Element sampling. L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Model for the adjoint photo electric process
|
||||
// Model for the adjoint photo electric process.
|
||||
// Put a higher limit on the CS to avoid a high rate of Inverse Photo e-effect
|
||||
// at low energy. The very high adjoint CS of the reverse photo electric
|
||||
// reaction produce a high rate of reverse photo electric reaction in the inner
|
||||
// side of a shielding for eaxmple, the correction of this occurrence by weight
|
||||
// correction in the StepDoIt method is not statistically sufficient at small
|
||||
// energy. The problem is partially solved by setting a higher CS limit and
|
||||
// compensating it by an extra weight correction factor. However when coupling
|
||||
// it with other reverse processes the reverse photo-electric is still the
|
||||
// source of very occasional high weights that decrease the efficiency of the
|
||||
// computation. A way to solve this problemn is still needed but is difficult
|
||||
// to find as it happens in rare cases but does give a weight that is outside
|
||||
// the normal distribution. (Very Tricky!)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointPhotoElectricModel_h
|
||||
#define G4AdjointPhotoElectricModel_h 1
|
||||
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4PEEffectFluoModel.hh"
|
||||
class G4AdjointPhotoElectricModel: public G4VEmAdjointModel
|
||||
|
||||
class G4AdjointPhotoElectricModel : public G4VEmAdjointModel
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
G4AdjointPhotoElectricModel();
|
||||
~G4AdjointPhotoElectricModel();
|
||||
|
||||
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
virtual G4double GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
G4double AdjointCrossSectionPerAtom(const G4Element* anElement,G4double electronEnergy);
|
||||
|
||||
|
||||
|
||||
inline void SetTheDirectPEEffectModel(G4PEEffectFluoModel* aModel){theDirectPEEffectModel = aModel;
|
||||
DefineDirectEMModel(aModel);}
|
||||
|
||||
virtual void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight,
|
||||
G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
|
||||
private:
|
||||
G4double xsec[40];
|
||||
G4double totAdjointCS;
|
||||
G4double totBiasedAdjointCS;
|
||||
G4double factorCSBiasing;
|
||||
G4double pre_step_AdjointCS;
|
||||
G4double post_step_AdjointCS;
|
||||
|
||||
|
||||
G4double shell_prob[40][40];
|
||||
|
||||
|
||||
G4PEEffectFluoModel* theDirectPEEffectModel;
|
||||
size_t index_element;
|
||||
G4double current_eEnergy;
|
||||
|
||||
|
||||
private:
|
||||
void DefineCurrentMaterialAndElectronEnergy(const G4MaterialCutsCouple* aCouple,
|
||||
G4double eEnergy);
|
||||
|
||||
~G4AdjointPhotoElectricModel() override;
|
||||
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
G4double AdjointCrossSectionPerAtom(const G4Element* anElement,
|
||||
G4double electronEnergy);
|
||||
|
||||
G4AdjointPhotoElectricModel(G4AdjointPhotoElectricModel&) = delete;
|
||||
G4AdjointPhotoElectricModel& operator=(
|
||||
const G4AdjointPhotoElectricModel& right) = delete;
|
||||
|
||||
protected:
|
||||
void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight, G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
private:
|
||||
void DefineCurrentMaterialAndElectronEnergy(
|
||||
const G4MaterialCutsCouple* aCouple, G4double eEnergy);
|
||||
|
||||
G4double fShellProb[40][40];
|
||||
G4double fXsec[40];
|
||||
G4double fTotAdjointCS = 0.;
|
||||
G4double fFactorCSBiasing = 1.;
|
||||
G4double fPreStepAdjointCS = 0.;
|
||||
G4double fPostStepAdjointCS = 0.;
|
||||
G4double fCurrenteEnergy = 0.;
|
||||
|
||||
size_t fIndexElement = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+49
-121
@@ -23,149 +23,77 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointProcessEquivalentToDirectProcess
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// Class: G4AdjointProcessEquivalentToDirectProcess
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
// Adjoint process equivalent to direct process, used for some multiple
|
||||
// scattering.
|
||||
// A virtual class for wrapper process objects.
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 25 Sept. 2009 Created by L.Desorgher. Inspired from G4WrapperProcess
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint process equivalent to direct process, used for some multiple scattering
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef G4AdjointProcessEquivalentToDirectProcess_h
|
||||
#ifndef G4AdjointProcessEquivalentToDirectProcess_h
|
||||
#define G4AdjointProcessEquivalentToDirectProcess_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4VProcess.hh"
|
||||
|
||||
class G4AdjointProcessEquivalentToDirectProcess : public G4VProcess
|
||||
{
|
||||
// A virtual class for wrapper process objects.
|
||||
public:
|
||||
explicit G4AdjointProcessEquivalentToDirectProcess(
|
||||
const G4String& aName, G4VProcess* aProcess,
|
||||
G4ParticleDefinition* fwd_particle_def);
|
||||
|
||||
public: // with description
|
||||
// constructor requires the process name and type
|
||||
G4AdjointProcessEquivalentToDirectProcess(const G4String& aName, G4VProcess* aProcess,G4ParticleDefinition* fwd_particle_def);
|
||||
~G4AdjointProcessEquivalentToDirectProcess() override;
|
||||
|
||||
|
||||
G4VParticleChange* PostStepDoIt(const G4Track& track,
|
||||
const G4Step& stepData) override;
|
||||
|
||||
public:
|
||||
// destructor
|
||||
virtual ~G4AdjointProcessEquivalentToDirectProcess();
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& stepData) override;
|
||||
G4VParticleChange* AtRestDoIt(const G4Track& track,
|
||||
const G4Step& stepData) override;
|
||||
|
||||
|
||||
public: // with description
|
||||
////////////////////////////
|
||||
// DoIt /////////////////
|
||||
///////////////////////////
|
||||
virtual G4VParticleChange* PostStepDoIt(
|
||||
const G4Track& track,
|
||||
const G4Step& stepData
|
||||
);
|
||||
G4double AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize,
|
||||
G4double currentMinimumStep, G4double& proposedSafety,
|
||||
G4GPILSelection* selection) override;
|
||||
|
||||
virtual G4VParticleChange* AlongStepDoIt(
|
||||
const G4Track& track,
|
||||
const G4Step& stepData
|
||||
);
|
||||
virtual G4VParticleChange* AtRestDoIt(
|
||||
const G4Track& track,
|
||||
const G4Step& stepData
|
||||
);
|
||||
//////////////////////////
|
||||
// GPIL //////////////
|
||||
/////////////////////////
|
||||
virtual G4double AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& proposedSafety,
|
||||
G4GPILSelection* selection);
|
||||
G4double AtRestGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4ForceCondition* condition) override;
|
||||
|
||||
virtual G4double AtRestGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4ForceCondition* condition
|
||||
);
|
||||
G4double PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize,
|
||||
G4ForceCondition* condition) override;
|
||||
|
||||
virtual G4double PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition
|
||||
) ;
|
||||
|
||||
//////////////////////
|
||||
virtual G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
// Returns true if this process object is applicable to
|
||||
// the particle type
|
||||
// Process will not be registered to a particle if IsApplicable is false
|
||||
G4bool IsApplicable(const G4ParticleDefinition&) override;
|
||||
|
||||
virtual void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
// Messaged by the Particle definition (via the Process manager)
|
||||
// whenever cross section tables have to be rebuilt (i.e. if new
|
||||
// materials have been defined).
|
||||
// It is overloaded by individual processes when they need physics
|
||||
// tables.
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&) override;
|
||||
|
||||
// Processes which Build (for example in their
|
||||
// constructors) physics tables independent of cuts
|
||||
// should preferably use a
|
||||
// private void BuildThePhysicsTable()
|
||||
// function. Not another BuildPhysicsTable, please.
|
||||
|
||||
virtual void PreparePhysicsTable(const G4ParticleDefinition&);
|
||||
// Messaged by the Particle definition (via the Process manager)
|
||||
// whenever cross section tables have to be prepare for rebuilt
|
||||
// (i.e. if new materials have been defined).
|
||||
// It is overloaded by individual processes when they need physics
|
||||
// tables.
|
||||
void PreparePhysicsTable(const G4ParticleDefinition&) override;
|
||||
|
||||
// Processes which Build physics tables independent of cuts
|
||||
// (for example in their constructors)
|
||||
// should preferably use private
|
||||
// void BuildThePhysicsTable() and void PreparePhysicsTable().
|
||||
// Not another BuildPhysicsTable, please.
|
||||
G4bool StorePhysicsTable(const G4ParticleDefinition*,
|
||||
const G4String& directory,
|
||||
G4bool ascii = false) override;
|
||||
|
||||
G4bool RetrievePhysicsTable(const G4ParticleDefinition*,
|
||||
const G4String& directory,
|
||||
G4bool ascii = false) override;
|
||||
|
||||
virtual G4bool StorePhysicsTable(const G4ParticleDefinition* ,
|
||||
const G4String& directory,
|
||||
G4bool ascii = false);
|
||||
// Store PhysicsTable in a file.
|
||||
// (return false in case of failure at I/O )
|
||||
|
||||
virtual G4bool RetrievePhysicsTable( const G4ParticleDefinition* ,
|
||||
const G4String& directory,
|
||||
G4bool ascii = false);
|
||||
// Retrieve Physics from a file.
|
||||
// (return true if the Physics Table can be build by using file)
|
||||
// (return false if the process has no functionality or in case of failure)
|
||||
// File name should be defined by each process
|
||||
// and the file should be placed under the directory specified by the argument.
|
||||
////////////////////////////
|
||||
virtual void StartTracking(G4Track*);
|
||||
virtual void EndTracking();
|
||||
// inform Start/End of tracking for each track to the physics process
|
||||
|
||||
|
||||
|
||||
public:
|
||||
virtual void ResetNumberOfInteractionLengthLeft();
|
||||
// reset (determine the value of)NumberOfInteractionLengthLeft
|
||||
private:
|
||||
G4ParticleDefinition* theFwdParticleDef;
|
||||
G4VProcess* theDirectProcess;
|
||||
void StartTracking(G4Track*) override;
|
||||
void EndTracking() override;
|
||||
|
||||
void ResetNumberOfInteractionLengthLeft() override;
|
||||
|
||||
G4AdjointProcessEquivalentToDirectProcess(G4AdjointProcessEquivalentToDirectProcess&) =
|
||||
delete;
|
||||
G4AdjointProcessEquivalentToDirectProcess& operator=(
|
||||
const G4AdjointProcessEquivalentToDirectProcess& right) = delete;
|
||||
|
||||
private:
|
||||
G4ParticleDefinition* fFwdParticleDef;
|
||||
G4VProcess* fDirectProcess;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,24 +23,14 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointeIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
// Adjoint EM model for discrete reverse e- ionisation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4AdjointeIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// September 2009 creation by L. Desorgher. Separate the concrete ionisation stuff from G4VEMAdjointModel
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint EM model for discrete reverse e- ionisation
|
||||
//
|
||||
|
||||
#ifndef G4AdjointeIonisationModel_h
|
||||
#define G4AdjointeIonisationModel_h 1
|
||||
@@ -48,35 +38,29 @@
|
||||
#include "globals.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
class G4AdjointeIonisationModel: public G4VEmAdjointModel
|
||||
class G4AdjointeIonisationModel : public G4VEmAdjointModel
|
||||
{
|
||||
|
||||
public: //methods
|
||||
|
||||
//Constructor, destructor
|
||||
public:
|
||||
G4AdjointeIonisationModel();
|
||||
|
||||
virtual ~G4AdjointeIonisationModel();
|
||||
~G4AdjointeIonisationModel() override;
|
||||
|
||||
//Concrete implementation or virtual methods
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
|
||||
private:
|
||||
G4double DiffCrossSectionMoller(G4double kinEnergyProj,G4double kinEnergyProd);
|
||||
private: //attributes
|
||||
G4bool WithRapidSampling;
|
||||
|
||||
G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kin energy of particle before interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z, G4double A = 0.) override;
|
||||
|
||||
G4AdjointeIonisationModel(G4AdjointeIonisationModel&) = delete;
|
||||
G4AdjointeIonisationModel& operator=(const G4AdjointeIonisationModel& right) =
|
||||
delete;
|
||||
|
||||
private:
|
||||
G4double DiffCrossSectionMoller(G4double kinEnergyProj,
|
||||
G4double kinEnergyProd);
|
||||
|
||||
G4bool fWithRapidSampling = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,115 +23,76 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointhIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4AdjointhIonisationModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 13th February 2009 creation by L. Desorgher
|
||||
// 10 November 2009 Implementation of the rapid sampling.
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint EM model for discrete reverse hadron ionisation. Tested at the moment only for protons.
|
||||
//
|
||||
// Adjoint EM model for discrete reverse hadron ionisation.
|
||||
// Tested only for protons.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointhIonisationModel_h
|
||||
#define G4AdjointhIonisationModel_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
class G4PhysicsTable;
|
||||
class G4Region;
|
||||
class G4VParticleChange;
|
||||
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleChange;
|
||||
class G4ParticleDefinition;
|
||||
class G4Track;
|
||||
class G4AdjointCSMatrix;
|
||||
class G4VEmModel;
|
||||
|
||||
|
||||
class G4AdjointhIonisationModel: public G4VEmAdjointModel
|
||||
class G4AdjointhIonisationModel : public G4VEmAdjointModel
|
||||
{
|
||||
public:
|
||||
explicit G4AdjointhIonisationModel(G4ParticleDefinition* pDef);
|
||||
|
||||
public:
|
||||
~G4AdjointhIonisationModel() override;
|
||||
|
||||
G4AdjointhIonisationModel(G4ParticleDefinition* projectileDefinition);
|
||||
void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) override;
|
||||
|
||||
virtual ~G4AdjointhIonisationModel();
|
||||
void RapidSampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange);
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
void RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange);
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
|
||||
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
//Set/Get methods
|
||||
//------------------
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForScatProjToProjCase(G4double PrimAdjEnergy,G4double Tcut=0);
|
||||
virtual G4double GetSecondAdjEnergyMaxForProdToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy);
|
||||
|
||||
G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z, G4double A = 0.) override;
|
||||
|
||||
private: //Methods
|
||||
|
||||
|
||||
G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool isScatProjToProj) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMinForScatProjToProj(G4double primAdjEnergy,
|
||||
G4double tcut = 0.) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy) override;
|
||||
|
||||
G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy) override;
|
||||
|
||||
G4AdjointhIonisationModel(G4AdjointhIonisationModel&) = delete;
|
||||
G4AdjointhIonisationModel& operator=(const G4AdjointhIonisationModel& right) =
|
||||
delete;
|
||||
|
||||
private:
|
||||
void DefineProjectileProperty();
|
||||
|
||||
//projectile property
|
||||
G4double mass;
|
||||
G4double tlimit;
|
||||
G4double spin;
|
||||
G4double magMoment2;
|
||||
G4double chargeSquare;
|
||||
G4double ratio, ratio2;
|
||||
G4double one_plus_ratio_2;
|
||||
G4double formfact;
|
||||
G4bool isIon;
|
||||
G4double one_minus_ratio_2;
|
||||
|
||||
|
||||
|
||||
G4VEmModel* theBraggDirectEMModel;
|
||||
//G4double term_Cross1, term_Cross2;
|
||||
G4VEmModel* fBraggDirectEMModel;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// projectile properties
|
||||
G4double fMass = 0.;
|
||||
G4double fSpin = 0.;
|
||||
G4double fMagMoment2 = 0.;
|
||||
G4double fMassRatio = 0.;
|
||||
G4double fFormFact = 0.;
|
||||
G4double fOnePlusRatio2 = 0.;
|
||||
G4double fOneMinusRatio2 = 0.;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,78 +23,48 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointhMultipleScattering
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4AdjointhMultipleScattering
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4AdjointhMultipleScattering
|
||||
//
|
||||
// Author: Desorgher Laurent
|
||||
//
|
||||
// Creation date: 03.06.2009 cloned from G4hMultipleScattering by U.Laszlo with slight modification for adjoint_ion.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 03.06.2009 Creation by L. Desorgher. Cloned from G4hMultipleScattering by U.Laszlo with slight modifications.
|
||||
// 09.11.2009 Remove AlongStepGetPhysicalInteractionLength, to call the one of the base class.
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// The class simulates the multiple scattering for adjoint proton of charged particle. In this approximate implementation the reverse multiple scattering
|
||||
// is the same than the foward one. This should be changed in the future to have the MultipleScaterring computed for the energy at the end of the step
|
||||
// and not before the step.
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
// The class simulates the multiple scattering for adjoint proton of charged
|
||||
// particle. In this approximate implementation the reverse multiple scattering
|
||||
// is the same as the forward one. This should be changed in the future to
|
||||
// have the MultipleScattering computed for the energy at the end of the step
|
||||
// and not before the step.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4AdjointhMultipleScattering_h
|
||||
#define G4AdjointhMultipleScattering_h 1
|
||||
|
||||
#include "G4VMultipleScattering.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4VMscModel;
|
||||
|
||||
class G4AdjointhMultipleScattering : public G4VMultipleScattering
|
||||
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
explicit G4AdjointhMultipleScattering(const G4String& processName = "msc");
|
||||
|
||||
G4AdjointhMultipleScattering(const G4String& processName="msc");
|
||||
|
||||
virtual ~G4AdjointhMultipleScattering();
|
||||
~G4AdjointhMultipleScattering() override;
|
||||
|
||||
// returns true for charged particles, false otherwise
|
||||
G4bool IsApplicable (const G4ParticleDefinition& p);
|
||||
G4bool IsApplicable(const G4ParticleDefinition& p) override;
|
||||
|
||||
// PrG4int few lines of informations about the process: validity range,
|
||||
void PrintInfo();
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
void StreamProcessInfo(std::ostream& out) const override;
|
||||
|
||||
protected:
|
||||
G4AdjointhMultipleScattering(G4AdjointhMultipleScattering&) = delete;
|
||||
G4AdjointhMultipleScattering& operator=(
|
||||
const G4AdjointhMultipleScattering& right) = delete;
|
||||
|
||||
// This function initialise models
|
||||
void InitialiseProcess(const G4ParticleDefinition*);
|
||||
protected:
|
||||
void InitialiseProcess(const G4ParticleDefinition*) override;
|
||||
|
||||
private: // data members
|
||||
|
||||
G4bool isInitialized;
|
||||
private:
|
||||
G4bool fIsInitialized = false;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,167 +23,99 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4ContinuousGainOfEnergy
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4ContinuousGainOfEnergy
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// -10 May 2007 creation by L. Desorgher
|
||||
// -February-March 2009 Update for protons by L.Desorgher
|
||||
// -July August 2009 Update for ion by L.Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Continuous process acting on adjoint particles to compute the continuous gain of energy of charged particles when they are tracked back!
|
||||
//
|
||||
//
|
||||
// Continuous process acting on adjoint particles to compute the continuous
|
||||
// gain of energy of charged particles when they are tracked back.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4ContinuousGainOfEnergy_h
|
||||
#define G4ContinuousGainOfEnergy_h 1
|
||||
|
||||
#include "G4VContinuousProcess.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4VEnergyLossProcess.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4VContinuousProcess.hh"
|
||||
|
||||
|
||||
class G4Step;
|
||||
class G4Material;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleChange;
|
||||
class G4ParticleDefinition;
|
||||
class G4Step;
|
||||
class G4Track;
|
||||
class G4VEmModel;
|
||||
class G4VEmFluctuationModel;
|
||||
|
||||
|
||||
class G4VEnergyLossProcess;
|
||||
|
||||
class G4ContinuousGainOfEnergy : public G4VContinuousProcess
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4ContinuousGainOfEnergy(const G4String& name = "EnergyGain",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
G4ContinuousGainOfEnergy(const G4String& name = "EnergyGain",
|
||||
G4ProcessType type = fElectromagnetic);
|
||||
|
||||
virtual ~G4ContinuousGainOfEnergy();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Methods with standard implementation; may be overwritten if needed
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
|
||||
|
||||
virtual G4double GetContinuousStepLimit(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Generic methods common to all processes
|
||||
//------------------------------------------------------------------------
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void PreparePhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&);
|
||||
~G4ContinuousGainOfEnergy() override;
|
||||
|
||||
G4VParticleChange* AlongStepDoIt(const G4Track&, const G4Step&) override;
|
||||
|
||||
void SetLossFluctuations(G4bool val);
|
||||
inline void SetIsIntegral(G4bool val){is_integral= val;}
|
||||
|
||||
inline void SetDirectEnergyLossProcess(G4VEnergyLossProcess* aProcess){theDirectEnergyLossProcess=aProcess;};
|
||||
|
||||
|
||||
inline void SetDirectEnergyLossProcess(G4VEnergyLossProcess* aProcess)
|
||||
{
|
||||
fDirectEnergyLossProcess = aProcess;
|
||||
};
|
||||
|
||||
void SetDirectParticle(G4ParticleDefinition* p);
|
||||
|
||||
protected:
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
|
||||
|
||||
G4ContinuousGainOfEnergy(G4ContinuousGainOfEnergy&) = delete;
|
||||
G4ContinuousGainOfEnergy& operator=(const G4ContinuousGainOfEnergy& right) =
|
||||
delete;
|
||||
|
||||
private:
|
||||
protected:
|
||||
G4double GetContinuousStepLimit(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety) override;
|
||||
|
||||
private:
|
||||
void DefineMaterial(const G4MaterialCutsCouple* couple);
|
||||
void SetDynamicMassCharge(const G4Track& track, G4double energy);
|
||||
|
||||
|
||||
// hide assignment operator
|
||||
|
||||
G4ContinuousGainOfEnergy(G4ContinuousGainOfEnergy &);
|
||||
G4ContinuousGainOfEnergy & operator=(const G4ContinuousGainOfEnergy &right);
|
||||
const G4Material* fCurrentMaterial = nullptr;
|
||||
const G4MaterialCutsCouple* fCurrentCouple = nullptr;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const G4Material* currentMaterial;
|
||||
const G4MaterialCutsCouple* currentCouple;
|
||||
size_t currentMaterialIndex;
|
||||
size_t currentCoupleIndex;
|
||||
G4double currentTcut;
|
||||
G4double currentCutInRange;
|
||||
G4double preStepKinEnergy;
|
||||
|
||||
|
||||
|
||||
G4double linLossLimit;
|
||||
G4bool lossFluctuationFlag;
|
||||
G4bool lossFluctuationArePossible;
|
||||
|
||||
G4VEnergyLossProcess* theDirectEnergyLossProcess;
|
||||
G4ParticleDefinition* theDirectPartDef;
|
||||
|
||||
|
||||
G4bool is_integral;
|
||||
|
||||
//adding for Ions
|
||||
//----------------
|
||||
G4bool IsIon;
|
||||
G4double massRatio;
|
||||
G4double chargeSqRatio;
|
||||
G4VEmModel* currentModel;
|
||||
G4double preStepChargeSqRatio;
|
||||
G4double preStepScaledKinEnergy;
|
||||
G4double preStepRange;
|
||||
G4VEmModel* fCurrentModel = nullptr;
|
||||
G4VEnergyLossProcess* fDirectEnergyLossProcess = nullptr;
|
||||
G4ParticleDefinition* fDirectPartDef = nullptr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
G4double fCurrentTcut = 0.;
|
||||
G4double fPreStepKinEnergy = 1.;
|
||||
G4double fLinLossLimit = 0.05;
|
||||
G4double fMassRatio = 1.;
|
||||
|
||||
size_t fCurrentCoupleIndex = 9999999;
|
||||
|
||||
G4bool fIsIon = false;
|
||||
G4bool fLossFluctuationFlag = true;
|
||||
G4bool fLossFluctuationArePossible = true;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
inline void G4ContinuousGainOfEnergy::DefineMaterial(
|
||||
const G4MaterialCutsCouple* couple)
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
if(couple != currentCouple) {
|
||||
currentCouple = couple;
|
||||
currentMaterial = couple->GetMaterial();
|
||||
currentCoupleIndex = couple->GetIndex();
|
||||
currentMaterialIndex = currentMaterial->GetIndex();
|
||||
|
||||
size_t idx=1;
|
||||
const std::vector<G4double>* aVec = G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(idx);
|
||||
currentTcut=(*aVec)[currentCoupleIndex];
|
||||
currentCutInRange = couple->GetProductionCuts()->GetProductionCut(theDirectPartDef->GetParticleName());
|
||||
//G4cout<<"Define Material"<<G4endl;
|
||||
//if(!meanFreePath) ResetNumberOfInteractionLengthLeft();
|
||||
if(couple != fCurrentCouple)
|
||||
{
|
||||
fCurrentCouple = couple;
|
||||
fCurrentMaterial = couple->GetMaterial();
|
||||
fCurrentCoupleIndex = couple->GetIndex();
|
||||
|
||||
const std::vector<G4double>* aVec =
|
||||
G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(1);
|
||||
fCurrentTcut = (*aVec)[fCurrentCoupleIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,41 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4InversePEEffect
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4InversePEEffect.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 25 October 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse photo electric process
|
||||
//
|
||||
// Adjoint/reverse photo electric process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4InversePEEffect_h
|
||||
#define G4InversePEEffect_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
|
||||
class G4AdjointPhotoElectricModel;
|
||||
class G4InversePEEffect: public G4VAdjointReverseReaction
|
||||
|
||||
class G4InversePEEffect : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4InversePEEffect(G4String process_name,
|
||||
G4AdjointPhotoElectricModel* aModel);
|
||||
~G4InversePEEffect() override;
|
||||
|
||||
G4InversePEEffect(G4String process_name, G4AdjointPhotoElectricModel* aModel);
|
||||
~G4InversePEEffect();
|
||||
|
||||
private:
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4InversePEEffect(G4InversePEEffect&) = delete;
|
||||
G4InversePEEffect& operator=(const G4InversePEEffect& right) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,42 +23,35 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4IonInverseIonisation
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4IonInverseIonisation
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 25 August 2009 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse discrete ionisation for ions
|
||||
//
|
||||
// Adjoint/reverse discrete ionisation for ions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4IonInverseIonisation_h
|
||||
#define G4IonInverseIonisation_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4AdjointIonIonisationModel.hh"
|
||||
class G4IonInverseIonisation: public G4VAdjointReverseReaction
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
|
||||
class G4AdjointIonIonisationModel;
|
||||
|
||||
class G4IonInverseIonisation : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4IonInverseIonisation(G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointIonIonisationModel* aEmAdjointModel);
|
||||
~G4IonInverseIonisation() override;
|
||||
|
||||
G4IonInverseIonisation(G4bool whichScatCase, G4String process_name, G4AdjointIonIonisationModel* aEmAdjointModel);
|
||||
~G4IonInverseIonisation();
|
||||
|
||||
private:
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4IonInverseIonisation(G4IonInverseIonisation&) = delete;
|
||||
G4IonInverseIonisation& operator=(const G4IonInverseIonisation& right) =
|
||||
delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,91 +23,69 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
//
|
||||
// File name: G4UrbanAdjointMscModel
|
||||
//
|
||||
// Author: Laszlo Urban
|
||||
//
|
||||
// Creation date: 19.02.2013
|
||||
//
|
||||
// Created from G4UrbanAdjointMscModel96
|
||||
//
|
||||
// New parametrization for theta0
|
||||
// Correction for very small step length
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of the model of multiple scattering based on
|
||||
// H.W.Lewis Phys Rev 78 (1950) 526 and L.Urban model
|
||||
|
||||
// Implementation of the model of multiple scattering based on
|
||||
// H.W.Lewis Phys Rev 78 (1950) 526 and L.Urban model
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef G4UrbanAdjointMscModel_h
|
||||
#define G4UrbanAdjointMscModel_h 1
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include <CLHEP/Units/SystemOfUnits.h>
|
||||
|
||||
#include "G4VMscModel.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Exp.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4VMscModel.hh"
|
||||
|
||||
|
||||
class G4ParticleChangeForMSC;
|
||||
class G4SafetyHelper;
|
||||
class G4LossTableManager;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleChangeForMSC;
|
||||
class G4ParticleDefinition;
|
||||
class G4SafetyHelper;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4UrbanAdjointMscModel : public G4VMscModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
explicit G4UrbanAdjointMscModel(const G4String& nam = "UrbanMsc");
|
||||
|
||||
virtual ~G4UrbanAdjointMscModel();
|
||||
~G4UrbanAdjointMscModel() override;
|
||||
|
||||
virtual void Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&) override;
|
||||
void Initialise(const G4ParticleDefinition*, const G4DataVector&) override;
|
||||
|
||||
virtual void StartTracking(G4Track*) override;
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
virtual G4double
|
||||
ComputeCrossSectionPerAtom(const G4ParticleDefinition* particle,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,
|
||||
G4double AtomicWeight=0.,
|
||||
G4double cut =0.,
|
||||
G4double emax=DBL_MAX) override;
|
||||
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition* particle,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,
|
||||
G4double AtomicWeight = 0.,
|
||||
G4double cut = 0.,
|
||||
G4double emax = DBL_MAX) override;
|
||||
|
||||
virtual G4ThreeVector& SampleScattering(const G4ThreeVector&,
|
||||
G4double safety) override;
|
||||
G4ThreeVector& SampleScattering(const G4ThreeVector&,
|
||||
G4double safety) override;
|
||||
|
||||
virtual G4double
|
||||
ComputeTruePathLengthLimit(const G4Track& track,
|
||||
G4double& currentMinimalStep) override;
|
||||
G4double ComputeTruePathLengthLimit(const G4Track& track,
|
||||
G4double& currentMinimalStep) override;
|
||||
|
||||
virtual G4double ComputeGeomPathLength(G4double truePathLength) override;
|
||||
G4double ComputeGeomPathLength(G4double truePathLength) override;
|
||||
|
||||
virtual G4double ComputeTrueStepLength(G4double geomStepLength) override;
|
||||
G4double ComputeTrueStepLength(G4double geomStepLength) override;
|
||||
|
||||
G4double ComputeTheta0(G4double truePathLength, G4double KineticEnergy);
|
||||
|
||||
inline void SetNewDisplacementFlag(G4bool);
|
||||
|
||||
private:
|
||||
G4UrbanAdjointMscModel& operator=(const G4UrbanAdjointMscModel& right) =
|
||||
delete;
|
||||
G4UrbanAdjointMscModel(const G4UrbanAdjointMscModel&) = delete;
|
||||
|
||||
private:
|
||||
G4double SampleCosineTheta(G4double trueStepLength, G4double KineticEnergy);
|
||||
|
||||
void SampleDisplacement(G4double sinTheta, G4double phi);
|
||||
@@ -119,25 +97,21 @@ private:
|
||||
inline void UpdateCache();
|
||||
|
||||
inline G4double Randomizetlimit();
|
||||
|
||||
|
||||
inline G4double SimpleScattering(G4double xmeanth, G4double x2meanth);
|
||||
|
||||
// hide assignment operator
|
||||
G4UrbanAdjointMscModel & operator=(const G4UrbanAdjointMscModel &right) = delete;
|
||||
G4UrbanAdjointMscModel(const G4UrbanAdjointMscModel&) = delete;
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngineMod;
|
||||
CLHEP::HepRandomEngine* rndmEngineMod;
|
||||
|
||||
const G4ParticleDefinition* particle;
|
||||
const G4ParticleDefinition* positron;
|
||||
G4ParticleChangeForMSC* fParticleChange;
|
||||
G4ParticleChangeForMSC* fParticleChange;
|
||||
|
||||
const G4MaterialCutsCouple* couple;
|
||||
G4LossTableManager* theManager;
|
||||
G4LossTableManager* theManager;
|
||||
|
||||
G4double mass;
|
||||
G4double charge,ChargeSquare;
|
||||
G4double masslimite,lambdalimit,fr;
|
||||
G4double charge, ChargeSquare;
|
||||
G4double masslimite, lambdalimit, fr;
|
||||
|
||||
G4double taubig;
|
||||
G4double tausmall;
|
||||
@@ -145,7 +119,7 @@ private:
|
||||
G4double currentTau;
|
||||
G4double tlimit;
|
||||
G4double tlimitmin;
|
||||
G4double tlimitminfix,tlimitminfix2;
|
||||
G4double tlimitminfix, tlimitminfix2;
|
||||
G4double tgeom;
|
||||
|
||||
G4double geombig;
|
||||
@@ -160,122 +134,119 @@ private:
|
||||
G4double lambdaeff;
|
||||
G4double tPathLength;
|
||||
G4double zPathLength;
|
||||
G4double par1,par2,par3;
|
||||
G4double par1, par2, par3;
|
||||
|
||||
G4double stepmin;
|
||||
|
||||
G4double currentKinEnergy;
|
||||
G4double currentRange;
|
||||
G4double currentRange;
|
||||
G4double rangeinit;
|
||||
G4double currentRadLength;
|
||||
|
||||
G4int currentMaterialIndex;
|
||||
|
||||
G4double Zold;
|
||||
G4double Zeff,Z2,Z23,lnZ;
|
||||
G4double coeffth1,coeffth2;
|
||||
G4double coeffc1,coeffc2,coeffc3,coeffc4;
|
||||
|
||||
G4bool firstStep;
|
||||
G4bool insideskin;
|
||||
|
||||
G4bool latDisplasmentbackup ;
|
||||
G4bool displacementFlag;
|
||||
G4double Zeff, Z2, Z23, lnZ;
|
||||
G4double coeffth1, coeffth2;
|
||||
G4double coeffc1, coeffc2, coeffc3, coeffc4;
|
||||
|
||||
G4double rangecut;
|
||||
G4double drr,finalr;
|
||||
G4double drr, finalr;
|
||||
|
||||
G4int currentMaterialIndex;
|
||||
|
||||
G4bool firstStep;
|
||||
G4bool insideskin;
|
||||
|
||||
G4bool latDisplasmentbackup;
|
||||
G4bool displacementFlag;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline void G4UrbanAdjointMscModel::SetNewDisplacementFlag(G4bool val)
|
||||
{
|
||||
displacementFlag = val;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4UrbanAdjointMscModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{ const G4ParticleDefinition* p1 =p;
|
||||
inline void G4UrbanAdjointMscModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
const G4ParticleDefinition* p1 = p;
|
||||
|
||||
if (p->GetParticleName() =="adj_e-") p1= G4Electron::Electron();
|
||||
if(p->GetParticleName() == "adj_e-")
|
||||
p1 = G4Electron::Electron();
|
||||
|
||||
if (p1 != particle) {
|
||||
particle = p1;
|
||||
mass = p1->GetPDGMass();
|
||||
charge = p1->GetPDGCharge()/CLHEP::eplus;
|
||||
ChargeSquare = charge*charge;
|
||||
if(p1 != particle)
|
||||
{
|
||||
particle = p1;
|
||||
mass = p1->GetPDGMass();
|
||||
charge = p1->GetPDGCharge() / CLHEP::eplus;
|
||||
ChargeSquare = charge * charge;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline G4double G4UrbanAdjointMscModel::Randomizetlimit()
|
||||
{
|
||||
G4double temptlimit = tlimit;
|
||||
if(tlimit > tlimitmin)
|
||||
{
|
||||
G4double delta = tlimit-tlimitmin;
|
||||
do {
|
||||
temptlimit = G4RandGauss::shoot(rndmEngineMod,tlimit,0.1*delta);
|
||||
// Loop checking, 10-Apr-2016, Laszlo Urban
|
||||
} while ((temptlimit < tlimit-delta) ||
|
||||
(temptlimit > tlimit+delta));
|
||||
G4double delta = tlimit - tlimitmin;
|
||||
do
|
||||
{
|
||||
temptlimit = G4RandGauss::shoot(rndmEngineMod, tlimit, 0.1 * delta);
|
||||
// Loop checking, 10-Apr-2016, Laszlo Urban
|
||||
} while((temptlimit < tlimit - delta) || (temptlimit > tlimit + delta));
|
||||
}
|
||||
else
|
||||
{
|
||||
temptlimit = tlimitmin;
|
||||
}
|
||||
else { temptlimit = tlimitmin; }
|
||||
|
||||
return temptlimit;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline void G4UrbanAdjointMscModel::UpdateCache()
|
||||
{
|
||||
lnZ = G4Log(Zeff);
|
||||
// correction in theta0 formula
|
||||
G4double w = G4Exp(lnZ/6.);
|
||||
G4double facz = 0.990395+w*(-0.168386+w*0.093286) ;
|
||||
coeffth1 = facz*(1. - 8.7780e-2/Zeff);
|
||||
coeffth2 = facz*(4.0780e-2 + 1.7315e-4*Zeff);
|
||||
G4double w = G4Exp(lnZ / 6.);
|
||||
G4double facz = 0.990395 + w * (-0.168386 + w * 0.093286);
|
||||
coeffth1 = facz * (1. - 8.7780e-2 / Zeff);
|
||||
coeffth2 = facz * (4.0780e-2 + 1.7315e-4 * Zeff);
|
||||
|
||||
// tail parameters
|
||||
G4double Z13 = w*w;
|
||||
coeffc1 = 2.3785 - Z13*(4.1981e-1 - Z13*6.3100e-2);
|
||||
coeffc2 = 4.7526e-1 + Z13*(1.7694 - Z13*3.3885e-1);
|
||||
coeffc3 = 2.3683e-1 - Z13*(1.8111 - Z13*3.2774e-1);
|
||||
coeffc4 = 1.7888e-2 + Z13*(1.9659e-2 - Z13*2.6664e-3);
|
||||
G4double Z13 = w * w;
|
||||
coeffc1 = 2.3785 - Z13 * (4.1981e-1 - Z13 * 6.3100e-2);
|
||||
coeffc2 = 4.7526e-1 + Z13 * (1.7694 - Z13 * 3.3885e-1);
|
||||
coeffc3 = 2.3683e-1 - Z13 * (1.8111 - Z13 * 3.2774e-1);
|
||||
coeffc4 = 1.7888e-2 + Z13 * (1.9659e-2 - Z13 * 2.6664e-3);
|
||||
|
||||
Z2 = Zeff * Zeff;
|
||||
Z23 = Z13 * Z13;
|
||||
|
||||
Z2 = Zeff*Zeff;
|
||||
Z23 = Z13*Z13;
|
||||
|
||||
Zold = Zeff;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline
|
||||
G4double G4UrbanAdjointMscModel::SimpleScattering(G4double xmeanth, G4double x2meanth)
|
||||
inline G4double G4UrbanAdjointMscModel::SimpleScattering(G4double xmeanth,
|
||||
G4double x2meanth)
|
||||
{
|
||||
// 'large angle scattering'
|
||||
// 2 model functions with correct xmean and x2mean
|
||||
G4double a = (2.*xmeanth+9.*x2meanth-3.)/(2.*xmeanth-3.*x2meanth+1.);
|
||||
G4double prob = (a+2.)*xmeanth/a;
|
||||
G4double a =
|
||||
(2. * xmeanth + 9. * x2meanth - 3.) / (2. * xmeanth - 3. * x2meanth + 1.);
|
||||
G4double prob = (a + 2.) * xmeanth / a;
|
||||
|
||||
// sampling
|
||||
G4double cth = 1.;
|
||||
if(rndmEngineMod->flat() < prob) {
|
||||
cth = -1.+2.*G4Exp(G4Log(rndmEngineMod->flat())/(a+1.));
|
||||
} else {
|
||||
cth = -1.+2.*rndmEngineMod->flat();
|
||||
if(rndmEngineMod->flat() < prob)
|
||||
{
|
||||
cth = -1. + 2. * G4Exp(G4Log(rndmEngineMod->flat()) / (a + 1.));
|
||||
}
|
||||
else
|
||||
{
|
||||
cth = -1. + 2. * rndmEngineMod->flat();
|
||||
}
|
||||
return cth;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,100 +23,60 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4VAdjointReverseReaction
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4VAdjointReverseReaction
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 1st April 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Abstract class for adjoint/reverse discrete scattering
|
||||
//
|
||||
// Abstract class for adjoint/reverse discrete scattering
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4VAdjointReverseReaction_h
|
||||
#define G4VAdjointReverseReaction_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VDiscreteProcess.hh"
|
||||
|
||||
|
||||
|
||||
class G4PhysicsTable;
|
||||
class G4Region;
|
||||
class G4VParticleChange;
|
||||
class G4AdjointCSManager;
|
||||
class G4ParticleChange;
|
||||
class G4ParticleDefinition;
|
||||
class G4Track;
|
||||
class G4VEmAdjointModel;
|
||||
class G4AdjointCSMatrix;
|
||||
class G4AdjointCSManager;
|
||||
class G4Material;
|
||||
class G4MaterialCutsCouple;
|
||||
|
||||
class G4VParticleChange;
|
||||
|
||||
class G4VAdjointReverseReaction : public G4VDiscreteProcess
|
||||
{
|
||||
public:
|
||||
explicit G4VAdjointReverseReaction(G4String process_name,
|
||||
G4bool whichScatCase);
|
||||
|
||||
public:
|
||||
~G4VAdjointReverseReaction() override;
|
||||
|
||||
G4VAdjointReverseReaction(G4String process_name,G4bool whichScatCase);
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&) override;
|
||||
|
||||
virtual ~G4VAdjointReverseReaction();
|
||||
|
||||
public:
|
||||
void PreparePhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
void BuildPhysicsTable(const G4ParticleDefinition&);
|
||||
|
||||
virtual G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&);
|
||||
inline void SetIntegralMode(G4bool aBool){IsIntegralModeUsed = aBool;}
|
||||
|
||||
protected :// with description
|
||||
|
||||
virtual G4double GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition);
|
||||
G4VParticleChange* PostStepDoIt(const G4Track&,
|
||||
const G4Step&) override;
|
||||
|
||||
protected:
|
||||
G4VEmAdjointModel* theAdjointEMModel;
|
||||
G4ParticleChange* fParticleChange;
|
||||
G4AdjointCSManager* theAdjointCSManager;
|
||||
G4bool IsScatProjToProjCase;
|
||||
|
||||
|
||||
G4VAdjointReverseReaction(G4VAdjointReverseReaction&) = delete;
|
||||
G4VAdjointReverseReaction& operator=(
|
||||
const G4VAdjointReverseReaction& right) = delete;
|
||||
|
||||
private:
|
||||
G4double lastCS;
|
||||
std::vector<G4double> CS_Vs_Element;
|
||||
G4bool IsFwdCSUsed;
|
||||
|
||||
//For integral mode
|
||||
//------------------
|
||||
G4bool IsIntegralModeUsed;
|
||||
|
||||
|
||||
G4int trackid;
|
||||
G4int nstep;
|
||||
protected:
|
||||
G4double GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition) override;
|
||||
|
||||
|
||||
G4VEmAdjointModel* fAdjointModel = nullptr;
|
||||
G4bool fIsScatProjToProj;
|
||||
|
||||
};
|
||||
private:
|
||||
|
||||
G4ParticleChange* fParticleChange;
|
||||
G4AdjointCSManager* fCSManager;
|
||||
|
||||
G4int fTrackId = 0;
|
||||
|
||||
G4bool fIsFwdCSUsed = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,328 +23,290 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4VEMAdjointModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4VEMAdjointModel
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 10 September 2009 Move to a virtual class. L. Desorgher
|
||||
// 1st April 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Base class for Adjoint EM model. It is based on the use of direct G4VEmModel.
|
||||
//
|
||||
|
||||
// Base class for Adjoint EM model. It is based on the use of direct
|
||||
// G4VEmModel.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4VEmAdjointModel_h
|
||||
#define G4VEmAdjointModel_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
class G4PhysicsTable;
|
||||
class G4Region;
|
||||
class G4VParticleChange;
|
||||
class G4ParticleChange;
|
||||
class G4Track;
|
||||
class G4AdjointCSMatrix;
|
||||
class G4AdjointCSManager;
|
||||
class G4Material;
|
||||
class G4MaterialCutsCouple;
|
||||
class G4ParticleChange;
|
||||
class G4Region;
|
||||
class G4Track;
|
||||
|
||||
class G4VEmAdjointModel
|
||||
{
|
||||
|
||||
public: // public methods
|
||||
|
||||
G4VEmAdjointModel(const G4String& nam);
|
||||
public:
|
||||
explicit G4VEmAdjointModel(const G4String& nam);
|
||||
|
||||
virtual ~G4VEmAdjointModel();
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Virtual methods to be implemented for the sample secondaries concrete model
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//virtual void Initialise()=0;
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)=0;
|
||||
|
||||
|
||||
virtual void SampleSecondaries(const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Methods for adjoint processes; may be overwritten if needed;
|
||||
// Methods for adjoint processes
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
virtual G4double GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
G4double primEnergy,
|
||||
G4bool isScatProjToProj);
|
||||
|
||||
// The implementation of the DiffCrossSection... here are correct for
|
||||
// energy loss process. For the photoelectric and Compton scattering
|
||||
// the method should be redefined
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToScatPrim(
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyScatProj, // kinetic energy of the primary particle after the interaction
|
||||
G4double Z,
|
||||
G4double A = 0.);
|
||||
|
||||
|
||||
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd, // kinetic energy of the secondary particle
|
||||
G4double Z, G4double A = 0.);
|
||||
|
||||
virtual G4double DiffCrossSectionPerAtomPrimToScatPrim(
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyScatProj, // kin energy of primary after interaction
|
||||
G4double Z, G4double A = 0.);
|
||||
|
||||
virtual G4double DiffCrossSectionPerVolumePrimToSecond(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
);
|
||||
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd // kinetic energy of secondary particle
|
||||
);
|
||||
|
||||
virtual G4double DiffCrossSectionPerVolumePrimToScatPrim(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyScatProj // kinetic energy of the primary particle after the interaction
|
||||
);
|
||||
|
||||
|
||||
//Energy limits of adjoint secondary
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyScatProj // kinetic energy of primary after interaction
|
||||
);
|
||||
|
||||
// Energy limits of adjoint secondary
|
||||
//------------------
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForScatProjToProjCase(G4double PrimAdjEnergy,G4double Tcut=0);
|
||||
virtual G4double GetSecondAdjEnergyMaxForProdToProjCase(G4double PrimAdjEnergy);
|
||||
virtual G4double GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy);
|
||||
|
||||
|
||||
|
||||
//Other Methods
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy);
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMinForScatProjToProj(
|
||||
G4double primAdjEnergy, G4double tcut = 0.);
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy);
|
||||
|
||||
virtual G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy);
|
||||
|
||||
// Other Methods
|
||||
//---------------
|
||||
|
||||
void DefineCurrentMaterial(const G4MaterialCutsCouple* couple);
|
||||
|
||||
|
||||
std::vector< std::vector< double>* > ComputeAdjointCrossSectionVectorPerAtomForSecond(
|
||||
G4double kinEnergyProd,
|
||||
G4double Z,
|
||||
G4double A = 0.,
|
||||
G4int nbin_pro_decade=10
|
||||
);
|
||||
std::vector< std::vector< double>* > ComputeAdjointCrossSectionVectorPerAtomForScatProj(
|
||||
G4double kinEnergyProd,
|
||||
G4double Z,
|
||||
G4double A = 0.,
|
||||
G4int nbin_pro_decade=10
|
||||
);
|
||||
|
||||
std::vector< std::vector< double>* > ComputeAdjointCrossSectionVectorPerVolumeForSecond(
|
||||
G4Material* aMaterial,
|
||||
G4double kinEnergyProd,
|
||||
G4int nbin_pro_decade=10
|
||||
);
|
||||
std::vector< std::vector< double>* > ComputeAdjointCrossSectionVectorPerVolumeForScatProj(
|
||||
G4Material* aMaterial,
|
||||
G4double kinEnergyProd,
|
||||
G4int nbin_pro_decade=10
|
||||
);
|
||||
|
||||
|
||||
|
||||
inline void SetCSMatrices(std::vector< G4AdjointCSMatrix* >* Vec1CSMatrix, std::vector< G4AdjointCSMatrix* >* Vec2CSMatrix){
|
||||
pOnCSMatrixForProdToProjBackwardScattering = Vec1CSMatrix;
|
||||
pOnCSMatrixForScatProjToProjBackwardScattering = Vec2CSMatrix;
|
||||
|
||||
|
||||
void DefineCurrentMaterial(const G4MaterialCutsCouple* couple);
|
||||
|
||||
std::vector<std::vector<double>*>
|
||||
ComputeAdjointCrossSectionVectorPerAtomForSecond(G4double kinEnergyProd,
|
||||
G4double Z, G4double A = 0.,
|
||||
G4int nbin_pro_decade = 10);
|
||||
|
||||
std::vector<std::vector<double>*>
|
||||
ComputeAdjointCrossSectionVectorPerAtomForScatProj(
|
||||
G4double kinEnergyProd, G4double Z, G4double A = 0.,
|
||||
G4int nbin_pro_decade = 10);
|
||||
|
||||
std::vector<std::vector<double>*>
|
||||
ComputeAdjointCrossSectionVectorPerVolumeForSecond(
|
||||
G4Material* aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade = 10);
|
||||
|
||||
std::vector<std::vector<double>*>
|
||||
ComputeAdjointCrossSectionVectorPerVolumeForScatProj(
|
||||
G4Material* aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade = 10);
|
||||
|
||||
inline void SetCSMatrices(std::vector<G4AdjointCSMatrix*>* Vec1CSMatrix,
|
||||
std::vector<G4AdjointCSMatrix*>* Vec2CSMatrix)
|
||||
{
|
||||
fCSMatrixProdToProjBackScat = Vec1CSMatrix;
|
||||
fCSMatrixProjToProjBackScat = Vec2CSMatrix;
|
||||
};
|
||||
|
||||
inline G4ParticleDefinition* GetAdjointEquivalentOfDirectPrimaryParticleDefinition(){return theAdjEquivOfDirectPrimPartDef;}
|
||||
|
||||
inline G4ParticleDefinition* GetAdjointEquivalentOfDirectSecondaryParticleDefinition(){return theAdjEquivOfDirectSecondPartDef;}
|
||||
|
||||
inline G4double GetHighEnergyLimit(){return HighEnergyLimit;}
|
||||
|
||||
inline G4double GetLowEnergyLimit(){return LowEnergyLimit;}
|
||||
|
||||
void SetHighEnergyLimit(G4double aVal);
|
||||
|
||||
void SetLowEnergyLimit(G4double aVal);
|
||||
|
||||
inline void DefineDirectEMModel(G4VEmModel* aModel){theDirectEMModel = aModel;}
|
||||
|
||||
void SetAdjointEquivalentOfDirectPrimaryParticleDefinition(G4ParticleDefinition* aPart);
|
||||
|
||||
inline void SetAdjointEquivalentOfDirectSecondaryParticleDefinition(G4ParticleDefinition* aPart){
|
||||
theAdjEquivOfDirectSecondPartDef =aPart;
|
||||
|
||||
inline G4ParticleDefinition*
|
||||
GetAdjointEquivalentOfDirectPrimaryParticleDefinition()
|
||||
{
|
||||
return fAdjEquivDirectPrimPart;
|
||||
}
|
||||
|
||||
inline void SetSecondPartOfSameType(G4bool aBool){second_part_of_same_type =aBool;}
|
||||
|
||||
inline G4bool GetSecondPartOfSameType(){return second_part_of_same_type;}
|
||||
|
||||
inline void SetUseMatrix(G4bool aBool) { UseMatrix = aBool;}
|
||||
|
||||
inline void SetUseMatrixPerElement(G4bool aBool){ UseMatrixPerElement = aBool;}
|
||||
inline void SetUseOnlyOneMatrixForAllElements(G4bool aBool){ UseOnlyOneMatrixForAllElements = aBool;}
|
||||
|
||||
inline void SetApplyCutInRange(G4bool aBool){ ApplyCutInRange = aBool;}
|
||||
inline G4bool GetUseMatrix() {return UseMatrix;}
|
||||
inline G4bool GetUseMatrixPerElement(){ return UseMatrixPerElement;}
|
||||
inline G4bool GetUseOnlyOneMatrixForAllElements(){ return UseOnlyOneMatrixForAllElements;}
|
||||
inline G4bool GetApplyCutInRange(){ return ApplyCutInRange;}
|
||||
|
||||
inline G4String GetName(){ return name;}
|
||||
inline virtual void SetCSBiasingFactor(G4double aVal) {CS_biasing_factor = aVal;}
|
||||
|
||||
inline void SetCorrectWeightForPostStepInModel(G4bool aBool) {correct_weight_for_post_step_in_model = aBool;}
|
||||
inline void SetAdditionalWeightCorrectionFactorForPostStepOutsideModel(G4double factor) {additional_weight_correction_factor_for_post_step_outside_model = factor;}
|
||||
inline G4ParticleDefinition*
|
||||
GetAdjointEquivalentOfDirectSecondaryParticleDefinition()
|
||||
{
|
||||
return fAdjEquivDirectSecondPart;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline G4double GetHighEnergyLimit() { return fHighEnergyLimit; }
|
||||
|
||||
//Some of them can be overriden by daughter classes
|
||||
|
||||
|
||||
inline G4double GetLowEnergyLimit() { return fLowEnergyLimit; }
|
||||
|
||||
void SetHighEnergyLimit(G4double aVal);
|
||||
|
||||
void SetLowEnergyLimit(G4double aVal);
|
||||
|
||||
inline void DefineDirectEMModel(G4VEmModel* aModel) { fDirectModel = aModel; }
|
||||
|
||||
void SetAdjointEquivalentOfDirectPrimaryParticleDefinition(
|
||||
G4ParticleDefinition* aPart);
|
||||
|
||||
inline void SetAdjointEquivalentOfDirectSecondaryParticleDefinition(
|
||||
G4ParticleDefinition* aPart)
|
||||
{
|
||||
fAdjEquivDirectSecondPart = aPart;
|
||||
}
|
||||
|
||||
inline void SetSecondPartOfSameType(G4bool aBool)
|
||||
{
|
||||
fSecondPartSameType = aBool;
|
||||
}
|
||||
|
||||
inline G4bool GetSecondPartOfSameType() { return fSecondPartSameType; }
|
||||
|
||||
inline void SetUseMatrix(G4bool aBool) { fUseMatrix = aBool; }
|
||||
|
||||
inline void SetUseMatrixPerElement(G4bool aBool)
|
||||
{
|
||||
fUseMatrixPerElement = aBool;
|
||||
}
|
||||
|
||||
inline void SetUseOnlyOneMatrixForAllElements(G4bool aBool)
|
||||
{
|
||||
fOneMatrixForAllElements = aBool;
|
||||
}
|
||||
|
||||
inline void SetApplyCutInRange(G4bool aBool) { fApplyCutInRange = aBool; }
|
||||
|
||||
inline G4bool GetUseMatrix() { return fUseMatrix; }
|
||||
|
||||
inline G4bool GetUseMatrixPerElement() { return fUseMatrixPerElement; }
|
||||
|
||||
inline G4bool GetUseOnlyOneMatrixForAllElements()
|
||||
{
|
||||
return fOneMatrixForAllElements;
|
||||
}
|
||||
|
||||
inline G4bool GetApplyCutInRange() { return fApplyCutInRange; }
|
||||
|
||||
inline G4String GetName() { return fName; }
|
||||
|
||||
inline virtual void SetCSBiasingFactor(G4double aVal)
|
||||
{
|
||||
fCsBiasingFactor = aVal;
|
||||
}
|
||||
|
||||
inline void SetCorrectWeightForPostStepInModel(G4bool aBool)
|
||||
{
|
||||
fInModelWeightCorr = aBool;
|
||||
}
|
||||
|
||||
inline void SetAdditionalWeightCorrectionFactorForPostStepOutsideModel(
|
||||
G4double factor)
|
||||
{
|
||||
fOutsideWeightFactor = factor;
|
||||
}
|
||||
|
||||
G4VEmAdjointModel(G4VEmAdjointModel&) = delete;
|
||||
G4VEmAdjointModel& operator=(const G4VEmAdjointModel& right) = delete;
|
||||
|
||||
protected:
|
||||
G4double DiffCrossSectionFunction1(G4double kinEnergyProj);
|
||||
|
||||
G4double DiffCrossSectionFunction2(G4double kinEnergyProj);
|
||||
G4double DiffCrossSectionPerVolumeFunctionForIntegrationOverEkinProj(G4double EkinProd);
|
||||
|
||||
|
||||
|
||||
//General methods to sample secondary energy
|
||||
//--------------------------------------
|
||||
G4double SampleAdjSecEnergyFromCSMatrix(size_t MatrixIndex,G4double prim_energy,G4bool IsScatProjToProjCase);
|
||||
G4double SampleAdjSecEnergyFromCSMatrix(G4double prim_energy,G4bool IsScatProjToProjCase);
|
||||
void SelectCSMatrix(G4bool IsScatProjToProjCase);
|
||||
|
||||
virtual G4double SampleAdjSecEnergyFromDiffCrossSectionPerAtom(G4double prim_energy,G4bool IsScatProjToProjCase);
|
||||
|
||||
|
||||
|
||||
//Post Step weight correction
|
||||
//----------------------------
|
||||
virtual void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight,
|
||||
G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool IsScatProjToProjCase);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected: //attributes
|
||||
|
||||
G4VEmModel* theDirectEMModel;
|
||||
G4VParticleChange* pParticleChange;
|
||||
|
||||
|
||||
// General methods to sample secondary energy
|
||||
G4double SampleAdjSecEnergyFromCSMatrix(size_t MatrixIndex,
|
||||
G4double prim_energy,
|
||||
G4bool isScatProjToProj);
|
||||
|
||||
|
||||
//Name
|
||||
//-----
|
||||
|
||||
const G4String name;
|
||||
|
||||
//Needed for CS integration at the initialisation phase
|
||||
//-----------------------------------------------------
|
||||
|
||||
G4int ASelectedNucleus;
|
||||
G4int ZSelectedNucleus;
|
||||
G4Material* SelectedMaterial;
|
||||
G4double kinEnergyProdForIntegration;
|
||||
G4double kinEnergyScatProjForIntegration;
|
||||
G4double kinEnergyProjForIntegration;
|
||||
G4double SampleAdjSecEnergyFromCSMatrix(G4double prim_energy,
|
||||
G4bool isScatProjToProj);
|
||||
|
||||
//for the adjoint simulation we need for each element or material:
|
||||
//an adjoint CS Matrix
|
||||
//-----------------------------
|
||||
|
||||
std::vector< G4AdjointCSMatrix* >* pOnCSMatrixForProdToProjBackwardScattering;
|
||||
std::vector< G4AdjointCSMatrix* >* pOnCSMatrixForScatProjToProjBackwardScattering;
|
||||
std::vector<G4double> CS_Vs_ElementForScatProjToProjCase;
|
||||
std::vector<G4double> CS_Vs_ElementForProdToProjCase;
|
||||
|
||||
G4double lastCS;
|
||||
G4double lastAdjointCSForScatProjToProjCase;
|
||||
G4double lastAdjointCSForProdToProjCase;
|
||||
|
||||
//particle definition
|
||||
//------------------
|
||||
|
||||
G4ParticleDefinition* theAdjEquivOfDirectPrimPartDef;
|
||||
G4ParticleDefinition* theAdjEquivOfDirectSecondPartDef;
|
||||
G4ParticleDefinition* theDirectPrimaryPartDef;
|
||||
G4bool second_part_of_same_type;
|
||||
|
||||
//Prestep energy
|
||||
//-------------
|
||||
G4double preStepEnergy;
|
||||
|
||||
//Current couple material
|
||||
//----------------------
|
||||
G4Material* currentMaterial;
|
||||
G4MaterialCutsCouple* currentCouple;
|
||||
size_t currentMaterialIndex;
|
||||
size_t currentCoupleIndex;
|
||||
G4double currentTcutForDirectPrim;
|
||||
G4double currentTcutForDirectSecond;
|
||||
G4bool ApplyCutInRange;
|
||||
|
||||
//For ions
|
||||
//---------
|
||||
G4double mass_ratio_product;
|
||||
G4double mass_ratio_projectile;
|
||||
void SelectCSMatrix(G4bool isScatProjToProj);
|
||||
|
||||
//Energy limits
|
||||
//-------------
|
||||
|
||||
G4double HighEnergyLimit;
|
||||
G4double LowEnergyLimit;
|
||||
virtual G4double SampleAdjSecEnergyFromDiffCrossSectionPerAtom(
|
||||
G4double prim_energy, G4bool isScatProjToProj);
|
||||
|
||||
//Cross Section biasing factor
|
||||
//---------------------------
|
||||
G4double CS_biasing_factor;
|
||||
|
||||
//Type of Model with Matrix or not
|
||||
//--------------------------------
|
||||
G4bool UseMatrix;
|
||||
G4bool UseMatrixPerElement; //other possibility is per Material
|
||||
G4bool UseOnlyOneMatrixForAllElements;
|
||||
|
||||
//Index of Cross section matrices to be used
|
||||
//------------
|
||||
size_t indexOfUsedCrossSectionMatrix;
|
||||
|
||||
size_t model_index;
|
||||
|
||||
//This is needed for the forced interaction where part of the weight correction
|
||||
// is given outside the model while the secondary are created in the model
|
||||
//The weight should be fixed before adding the secondary
|
||||
G4bool correct_weight_for_post_step_in_model;
|
||||
G4double additional_weight_correction_factor_for_post_step_outside_model;
|
||||
// Post Step weight correction
|
||||
virtual void CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight,
|
||||
G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy,
|
||||
G4bool isScatProjToProj);
|
||||
|
||||
G4AdjointCSManager* fCSManager;
|
||||
G4VEmModel* fDirectModel = nullptr;
|
||||
|
||||
const G4String fName;
|
||||
|
||||
G4Material* fSelectedMaterial = nullptr;
|
||||
G4Material* fCurrentMaterial = nullptr;
|
||||
G4MaterialCutsCouple* fCurrentCouple = nullptr;
|
||||
|
||||
// particle definition
|
||||
G4ParticleDefinition* fAdjEquivDirectPrimPart = nullptr;
|
||||
G4ParticleDefinition* fAdjEquivDirectSecondPart = nullptr;
|
||||
G4ParticleDefinition* fDirectPrimaryPart = nullptr;
|
||||
|
||||
// adjoint CS matrix for each element or material
|
||||
std::vector<G4AdjointCSMatrix*>* fCSMatrixProdToProjBackScat = nullptr;
|
||||
std::vector<G4AdjointCSMatrix*>* fCSMatrixProjToProjBackScat = nullptr;
|
||||
|
||||
std::vector<G4double> fElementCSScatProjToProj;
|
||||
std::vector<G4double> fElementCSProdToProj;
|
||||
|
||||
G4double fKinEnergyProdForIntegration = 0.;
|
||||
G4double fKinEnergyScatProjForIntegration = 0.;
|
||||
|
||||
G4double fLastCS = 0.;
|
||||
G4double fLastAdjointCSForScatProjToProj = 0.;
|
||||
G4double fLastAdjointCSForProdToProj = 0.;
|
||||
|
||||
G4double fPreStepEnergy = 0.;
|
||||
|
||||
G4double fTcutPrim = 0.;
|
||||
G4double fTcutSecond = 0.;
|
||||
|
||||
// Energy limits
|
||||
G4double fHighEnergyLimit = 0.;
|
||||
G4double fLowEnergyLimit = 0.;
|
||||
|
||||
// Cross Section biasing factor
|
||||
G4double fCsBiasingFactor = 1.;
|
||||
|
||||
// [1] This is needed for the forced interaction where part of the weight
|
||||
// correction is given outside the model while the secondary are created in
|
||||
// the model. The weight should be fixed before adding the secondary
|
||||
G4double fOutsideWeightFactor = 1.;
|
||||
|
||||
// Needed for CS integration at the initialisation phase
|
||||
G4int fASelectedNucleus = 0;
|
||||
G4int fZSelectedNucleus = 0;
|
||||
|
||||
size_t fCSMatrixUsed = 0; // Index of crosssection matrices used
|
||||
|
||||
G4bool fSecondPartSameType = false;
|
||||
G4bool fInModelWeightCorr =
|
||||
false; // correct_weight_for_post_step_in_model, see [1]
|
||||
|
||||
G4bool fApplyCutInRange = true;
|
||||
|
||||
// Type of Model with Matrix or not
|
||||
G4bool fUseMatrix = false;
|
||||
G4bool fUseMatrixPerElement = false; // other possibility is per Material
|
||||
G4bool fOneMatrixForAllElements = false;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,68 +23,47 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
// File name: G4eAdjointMultipleScattering
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 10 March 2001
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// The class simulates the multiple scattering for e+ and e-
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// class description
|
||||
//
|
||||
// The class simulates the multiple scattering for e+ and e-
|
||||
//
|
||||
// class description - end
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifndef G4eAdjointMultipleScattering_h
|
||||
#define G4eAdjointMultipleScattering_h 1
|
||||
|
||||
#include "G4VMultipleScattering.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4eAdjointMultipleScattering : public G4VMultipleScattering
|
||||
|
||||
{
|
||||
public: // with description
|
||||
|
||||
public:
|
||||
explicit G4eAdjointMultipleScattering(const G4String& processName = "msc");
|
||||
|
||||
virtual ~G4eAdjointMultipleScattering();
|
||||
~G4eAdjointMultipleScattering() override;
|
||||
|
||||
// This is called in the beginning of tracking for a new track
|
||||
void StartTracking(G4Track*) override;
|
||||
|
||||
// returns true for charged particles, false otherwise
|
||||
G4bool IsApplicable (const G4ParticleDefinition& p) final;
|
||||
G4bool IsApplicable(const G4ParticleDefinition& p) override;
|
||||
|
||||
// Print few lines of informations about the process: validity range,
|
||||
void PrintInfo() override;
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
void StreamProcessInfo(std::ostream& outFile) const override;
|
||||
|
||||
protected:
|
||||
G4eAdjointMultipleScattering(G4eAdjointMultipleScattering&) = delete;
|
||||
G4eAdjointMultipleScattering& operator =(
|
||||
const G4eAdjointMultipleScattering& right) = delete;
|
||||
|
||||
// This function initialise models
|
||||
protected:
|
||||
void InitialiseProcess(const G4ParticleDefinition*) override;
|
||||
|
||||
private: // data members
|
||||
|
||||
G4bool isInitialized;
|
||||
|
||||
private:
|
||||
G4bool fIsInitialized = false;
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,44 +23,35 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4eInverseBremstrahlung.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4eInverseBremstrahlung.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 25 October 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse bremstrahlung
|
||||
//
|
||||
|
||||
// Adjoint/reverse bremsstrahlung
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4eInverseBremsstrahlung_h
|
||||
#define G4eInverseBremsstrahlung_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
|
||||
class G4VEmAdjointModel;
|
||||
class G4eInverseBremsstrahlung: public G4VAdjointReverseReaction
|
||||
|
||||
class G4eInverseBremsstrahlung : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4eInverseBremsstrahlung(G4bool whichScatCase, G4String process_name,
|
||||
G4VEmAdjointModel* aEmAdjointModel);
|
||||
~G4eInverseBremsstrahlung() override;
|
||||
|
||||
G4eInverseBremsstrahlung(G4bool whichScatCase, G4String process_name,
|
||||
G4VEmAdjointModel* aEmAdjointModel);
|
||||
~G4eInverseBremsstrahlung();
|
||||
|
||||
private:
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4eInverseBremsstrahlung(G4eInverseBremsstrahlung&) = delete;
|
||||
G4eInverseBremsstrahlung& operator=(const G4eInverseBremsstrahlung& right) =
|
||||
delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,43 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4eInverseCompton.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4eInverseCompton.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 25 October 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse Compton
|
||||
//
|
||||
|
||||
// Adjoint/reverse Compton
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4eInverseCompton_h
|
||||
#define G4eInverseCompton_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
|
||||
class G4AdjointComptonModel;
|
||||
class G4eInverseCompton: public G4VAdjointReverseReaction
|
||||
|
||||
class G4eInverseCompton : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4eInverseCompton(G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointComptonModel* aEmAdjointModel);
|
||||
~G4eInverseCompton() override;
|
||||
|
||||
G4eInverseCompton(G4bool whichScatCase, G4String process_name, G4AdjointComptonModel* aEmAdjointModel);
|
||||
~G4eInverseCompton();
|
||||
|
||||
private:
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4eInverseCompton(G4eInverseCompton&) = delete;
|
||||
G4eInverseCompton& operator=(const G4eInverseCompton& right) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,42 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4eInverseIonisation.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4eInverseIonisation.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 15 April 2007 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse discrete ionisation
|
||||
// Adjoint/reverse discrete ionisation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4eInverseIonisation_h
|
||||
#define G4eInverseIonisation_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
class G4eInverseIonisation: public G4VAdjointReverseReaction
|
||||
|
||||
class G4VEmAdjointModel;
|
||||
|
||||
class G4eInverseIonisation : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
|
||||
G4eInverseIonisation(G4bool whichScatCase, G4String process_name, G4VEmAdjointModel* aEmAdjointModel);
|
||||
public:
|
||||
G4eInverseIonisation(G4bool whichScatCase, G4String process_name,
|
||||
G4VEmAdjointModel* aEmAdjointModel);
|
||||
~G4eInverseIonisation();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
void DumpInfo() const override { ProcessDescription(G4cout); };
|
||||
|
||||
G4eInverseIonisation(G4eInverseIonisation&) = delete;
|
||||
G4eInverseIonisation& operator=(const G4eInverseIonisation& right) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,42 +23,31 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class: G4hInverseIonisation
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Module: G4hInverseIonisation.hh
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// ChangeHistory:
|
||||
// 15 February 2009 creation by L. Desorgher
|
||||
//
|
||||
//-------------------------------------------------------------
|
||||
// Documentation:
|
||||
// Adjoint/reverse discrete ionisation for proton
|
||||
//
|
||||
// Adjoint/reverse discrete ionisation for proton
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4hInverseIonisation_h
|
||||
#define G4hInverseIonisation_h 1
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4AdjointhIonisationModel.hh"
|
||||
class G4hInverseIonisation: public G4VAdjointReverseReaction
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
|
||||
class G4AdjointhIonisationModel;
|
||||
|
||||
class G4hInverseIonisation : public G4VAdjointReverseReaction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit G4hInverseIonisation(G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointhIonisationModel* aEmAdjointModel);
|
||||
~G4hInverseIonisation() override;
|
||||
|
||||
G4hInverseIonisation(G4bool whichScatCase, G4String process_name, G4AdjointhIonisationModel* aEmAdjointModel);
|
||||
~G4hInverseIonisation();
|
||||
|
||||
private:
|
||||
|
||||
G4hInverseIonisation(G4hInverseIonisation&) = delete;
|
||||
G4hInverseIonisation& operator=(const G4hInverseIonisation& right) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,102 +1,73 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# sources.cmake
|
||||
# Module : G4emadjoint
|
||||
# Package: Geant4.src.G4processes.G4electromagnetic.G4emadjoint
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
# - G4emadjoint module build definition
|
||||
|
||||
#
|
||||
# Define the Geant4 Module.
|
||||
#
|
||||
GEANT4_DEFINE_MODULE(NAME G4emadjoint
|
||||
HEADERS
|
||||
G4AdjointAlongStepWeightCorrection.hh
|
||||
G4AdjointBremsstrahlungModel.hh
|
||||
G4AdjointCSManager.hh
|
||||
G4AdjointCSMatrix.hh
|
||||
G4AdjointComptonModel.hh
|
||||
G4AdjointInterpolator.hh
|
||||
G4AdjointIonIonisationModel.hh
|
||||
G4AdjointPhotoElectricModel.hh
|
||||
G4AdjointProcessEquivalentToDirectProcess.hh
|
||||
G4AdjointeIonisationModel.hh
|
||||
G4AdjointhIonisationModel.hh
|
||||
G4AdjointhMultipleScattering.hh
|
||||
G4ContinuousGainOfEnergy.hh
|
||||
G4InversePEEffect.hh
|
||||
G4IonInverseIonisation.hh
|
||||
G4VAdjointReverseReaction.hh
|
||||
G4AdjointForcedInteractionForGamma.hh
|
||||
G4VEmAdjointModel.hh
|
||||
G4eInverseBremsstrahlung.hh
|
||||
G4eInverseCompton.hh
|
||||
G4eInverseIonisation.hh
|
||||
G4hInverseIonisation.hh
|
||||
G4UrbanAdjointMscModel.hh
|
||||
G4eAdjointMultipleScattering.hh
|
||||
SOURCES
|
||||
G4AdjointAlongStepWeightCorrection.cc
|
||||
G4AdjointBremsstrahlungModel.cc
|
||||
G4AdjointCSManager.cc
|
||||
G4AdjointCSMatrix.cc
|
||||
G4AdjointComptonModel.cc
|
||||
G4AdjointInterpolator.cc
|
||||
G4AdjointIonIonisationModel.cc
|
||||
G4AdjointPhotoElectricModel.cc
|
||||
G4AdjointProcessEquivalentToDirectProcess.cc
|
||||
G4AdjointeIonisationModel.cc
|
||||
G4AdjointhIonisationModel.cc
|
||||
G4AdjointhMultipleScattering.cc
|
||||
G4ContinuousGainOfEnergy.cc
|
||||
G4InversePEEffect.cc
|
||||
G4IonInverseIonisation.cc
|
||||
G4VAdjointReverseReaction.cc
|
||||
G4AdjointForcedInteractionForGamma.cc
|
||||
G4VEmAdjointModel.cc
|
||||
G4eInverseBremsstrahlung.cc
|
||||
G4eInverseCompton.cc
|
||||
G4eInverseIonisation.cc
|
||||
G4hInverseIonisation.cc
|
||||
G4UrbanAdjointMscModel.cc
|
||||
G4eAdjointMultipleScattering.cc
|
||||
GRANULAR_DEPENDENCIES
|
||||
G4baryons
|
||||
G4bosons
|
||||
G4cuts
|
||||
G4emstandard
|
||||
G4emutils
|
||||
G4geometrymng
|
||||
G4globman
|
||||
G4hepnumerics
|
||||
G4intercoms
|
||||
G4ions
|
||||
G4leptons
|
||||
G4materials
|
||||
G4mesons
|
||||
G4navigation
|
||||
G4partadj
|
||||
G4partman
|
||||
G4procman
|
||||
G4track
|
||||
G4volumes
|
||||
GLOBAL_DEPENDENCIES
|
||||
G4geometry
|
||||
G4global
|
||||
G4intercoms
|
||||
G4materials
|
||||
G4particles
|
||||
G4track
|
||||
LINK_LIBRARIES
|
||||
)
|
||||
|
||||
# List any source specific properties here
|
||||
geant4_add_module(G4emadjoint
|
||||
PUBLIC_HEADERS
|
||||
G4AdjointAlongStepWeightCorrection.hh
|
||||
G4AdjointBremsstrahlungModel.hh
|
||||
G4AdjointCSManager.hh
|
||||
G4AdjointCSMatrix.hh
|
||||
G4AdjointComptonModel.hh
|
||||
G4AdjointInterpolator.hh
|
||||
G4AdjointIonIonisationModel.hh
|
||||
G4AdjointPhotoElectricModel.hh
|
||||
G4AdjointProcessEquivalentToDirectProcess.hh
|
||||
G4AdjointeIonisationModel.hh
|
||||
G4AdjointhIonisationModel.hh
|
||||
G4AdjointhMultipleScattering.hh
|
||||
G4ContinuousGainOfEnergy.hh
|
||||
G4InversePEEffect.hh
|
||||
G4IonInverseIonisation.hh
|
||||
G4VAdjointReverseReaction.hh
|
||||
G4AdjointForcedInteractionForGamma.hh
|
||||
G4VEmAdjointModel.hh
|
||||
G4eInverseBremsstrahlung.hh
|
||||
G4eInverseCompton.hh
|
||||
G4eInverseIonisation.hh
|
||||
G4hInverseIonisation.hh
|
||||
G4UrbanAdjointMscModel.hh
|
||||
G4eAdjointMultipleScattering.hh
|
||||
SOURCES
|
||||
G4AdjointAlongStepWeightCorrection.cc
|
||||
G4AdjointBremsstrahlungModel.cc
|
||||
G4AdjointCSManager.cc
|
||||
G4AdjointCSMatrix.cc
|
||||
G4AdjointComptonModel.cc
|
||||
G4AdjointInterpolator.cc
|
||||
G4AdjointIonIonisationModel.cc
|
||||
G4AdjointPhotoElectricModel.cc
|
||||
G4AdjointProcessEquivalentToDirectProcess.cc
|
||||
G4AdjointeIonisationModel.cc
|
||||
G4AdjointhIonisationModel.cc
|
||||
G4AdjointhMultipleScattering.cc
|
||||
G4ContinuousGainOfEnergy.cc
|
||||
G4InversePEEffect.cc
|
||||
G4IonInverseIonisation.cc
|
||||
G4VAdjointReverseReaction.cc
|
||||
G4AdjointForcedInteractionForGamma.cc
|
||||
G4VEmAdjointModel.cc
|
||||
G4eInverseBremsstrahlung.cc
|
||||
G4eInverseCompton.cc
|
||||
G4eInverseIonisation.cc
|
||||
G4hInverseIonisation.cc
|
||||
G4UrbanAdjointMscModel.cc
|
||||
G4eAdjointMultipleScattering.cc)
|
||||
|
||||
geant4_module_link_libraries(G4emadjoint
|
||||
PUBLIC
|
||||
G4cuts
|
||||
G4emutils
|
||||
G4globman
|
||||
G4leptons
|
||||
G4partman
|
||||
G4procman
|
||||
PRIVATE
|
||||
G4baryons
|
||||
G4bosons
|
||||
G4emstandard
|
||||
G4hepnumerics
|
||||
G4heprandom
|
||||
G4ions
|
||||
G4materials
|
||||
G4partadj
|
||||
G4track)
|
||||
|
||||
+57
-71
@@ -23,104 +23,90 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointAlongStepWeightCorrection.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
G4AdjointAlongStepWeightCorrection::G4AdjointAlongStepWeightCorrection(const G4String& name,
|
||||
G4ProcessType type): G4VContinuousProcess(name, type)
|
||||
{fParticleChange = new G4ParticleChange();
|
||||
currentMaterialIndex=0;
|
||||
preStepKinEnergy=1.;
|
||||
currentCouple=0;
|
||||
G4AdjointAlongStepWeightCorrection::G4AdjointAlongStepWeightCorrection(
|
||||
const G4String& name, G4ProcessType type)
|
||||
: G4VContinuousProcess(name, type)
|
||||
{
|
||||
fParticleChange = new G4ParticleChange();
|
||||
fCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
G4AdjointAlongStepWeightCorrection::~G4AdjointAlongStepWeightCorrection()
|
||||
{delete fParticleChange;
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointAlongStepWeightCorrection::PreparePhysicsTable(
|
||||
const G4ParticleDefinition& )
|
||||
{
|
||||
;
|
||||
delete fParticleChange;
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void G4AdjointAlongStepWeightCorrection::BuildPhysicsTable(const G4ParticleDefinition& )
|
||||
{;
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4VParticleChange* G4AdjointAlongStepWeightCorrection::AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
void G4AdjointAlongStepWeightCorrection::ProcessDescription(
|
||||
std::ostream& out) const
|
||||
{
|
||||
out <<
|
||||
"Continuous processes act on adjoint particles to continuously correct their "
|
||||
"weight during the adjoint reverse tracking. This process is needed when "
|
||||
"the adjoint cross sections are not scaled such that the total adjoint cross "
|
||||
"section matches the total forward cross section. By default the mode where "
|
||||
"the total adjoint cross section is equal to the total forward cross section "
|
||||
"is used and therefore this along step weightcorrection factor is 1. However "
|
||||
"in some cases (some energy ranges) the total forward cross section or the "
|
||||
"total adjoint cross section can be zero. In this case the along step weight "
|
||||
"correction is needed and is given by exp(-(Sigma_tot_adj-Sigma_tot_fwd).dx)"
|
||||
"\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
G4VParticleChange* G4AdjointAlongStepWeightCorrection::AlongStepDoIt(
|
||||
const G4Track& track, const G4Step& step)
|
||||
{
|
||||
|
||||
fParticleChange->Initialize(track);
|
||||
|
||||
|
||||
// Get the actual (true) Step length
|
||||
//----------------------------------
|
||||
G4double length = step.GetStepLength();
|
||||
|
||||
|
||||
G4double Tkin = step.GetPostStepPoint()->GetKineticEnergy();
|
||||
G4ParticleDefinition* thePartDef= const_cast<G4ParticleDefinition*> (track.GetDynamicParticle()->GetDefinition());
|
||||
G4double weight_correction=G4AdjointCSManager::GetAdjointCSManager()->GetContinuousWeightCorrection(thePartDef,
|
||||
preStepKinEnergy,Tkin, currentCouple,length);
|
||||
|
||||
|
||||
|
||||
G4ParticleDefinition* thePartDef = const_cast<G4ParticleDefinition*>(
|
||||
track.GetDynamicParticle()->GetDefinition());
|
||||
G4double weight_correction = fCSManager->GetContinuousWeightCorrection(
|
||||
thePartDef, fPreStepKinEnergy, Tkin, fCurrentCouple, length);
|
||||
|
||||
//Caution!!!
|
||||
// It is important to select the weight of the post_step_point
|
||||
// as the current weight and not the weight of the track, as t
|
||||
// the weight of the track is changed after having applied all
|
||||
// the along_step_do_it.
|
||||
// Caution!!!
|
||||
// It is important to select the weight of the post_step_point as the current
|
||||
// weight and not the weight of the track, as the weight of the track is
|
||||
// changed after having applied all the along_step_do_it.
|
||||
G4double new_weight =
|
||||
weight_correction * step.GetPostStepPoint()->GetWeight();
|
||||
|
||||
// G4double new_weight=weight_correction*track.GetWeight(); //old
|
||||
G4double new_weight=weight_correction*step.GetPostStepPoint()->GetWeight();
|
||||
|
||||
|
||||
|
||||
//if (weight_correction >2.) new_weight=1.e-300;
|
||||
|
||||
|
||||
//The following test check for zero weight.
|
||||
//This happens after weight correction of gamma for photo electric effect.
|
||||
//When the new weight is 0 it will be later on consider as nan by G4.
|
||||
//Therefore we do put a lower limit of 1.e-300. for new_weight
|
||||
//Correction by L.Desorgher on 15 July 2009
|
||||
if (new_weight==0 || (new_weight<=0 && new_weight>0)){
|
||||
//G4cout<<new_weight<<'\t'<<weight_correction<<'\t'<<track.GetWeight()<<G4endl;
|
||||
new_weight=1.e-300;
|
||||
// The following test check for zero weight.
|
||||
// This happens after weight correction of gamma for photo electric effect.
|
||||
// When the new weight is 0 it will be later on considered as NaN by G4.
|
||||
// Therefore we put a lower limit of 1.e-300. for new_weight
|
||||
if(new_weight == 0. || (new_weight <= 0. && new_weight > 0.))
|
||||
{
|
||||
new_weight = 1.e-300;
|
||||
}
|
||||
|
||||
//G4cout<<new_weight<<'\t'<<weight_correction<<'\t'<<track.GetWeight()<<G4endl;
|
||||
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
|
||||
return fParticleChange;
|
||||
}
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointAlongStepWeightCorrection::GetContinuousStepLimit(const G4Track& track,
|
||||
G4double , G4double , G4double& )
|
||||
{
|
||||
G4double x = DBL_MAX;
|
||||
G4double G4AdjointAlongStepWeightCorrection::GetContinuousStepLimit(
|
||||
const G4Track& track, G4double, G4double, G4double&)
|
||||
{
|
||||
DefineMaterial(track.GetMaterialCutsCouple());
|
||||
preStepKinEnergy = track.GetKineticEnergy();
|
||||
return x;
|
||||
fPreStepKinEnergy = track.GetKineticEnergy();
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
@@ -23,414 +23,319 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointBremsstrahlungModel.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SeltzerBergerModel.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointBremsstrahlungModel::G4AdjointBremsstrahlungModel(G4VEmModel* aModel):
|
||||
G4VEmAdjointModel("AdjointeBremModel")
|
||||
{
|
||||
SetUseMatrix(false);
|
||||
SetUseMatrixPerElement(false);
|
||||
|
||||
theDirectStdBremModel = aModel;
|
||||
theDirectEMModel=theDirectStdBremModel;
|
||||
theEmModelManagerForFwdModels = new G4EmModelManager();
|
||||
isDirectModelInitialised = false;
|
||||
G4VEmFluctuationModel* f=0;
|
||||
G4Region* r=0;
|
||||
theEmModelManagerForFwdModels->AddEmModel(1, theDirectStdBremModel, f, r);
|
||||
|
||||
SetApplyCutInRange(true);
|
||||
highKinEnergy= 1.*GeV;
|
||||
lowKinEnergy = 1.0*keV;
|
||||
|
||||
lastCZ =0.;
|
||||
|
||||
|
||||
theAdjEquivOfDirectPrimPartDef =G4AdjointElectron::AdjointElectron();
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointGamma::AdjointGamma();
|
||||
theDirectPrimaryPartDef=G4Electron::Electron();
|
||||
second_part_of_same_type=false;
|
||||
|
||||
|
||||
CS_biasing_factor =1.;
|
||||
|
||||
|
||||
G4AdjointBremsstrahlungModel::G4AdjointBremsstrahlungModel(G4VEmModel* aModel)
|
||||
: G4VEmAdjointModel("AdjointeBremModel")
|
||||
{
|
||||
fDirectModel = aModel;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointBremsstrahlungModel::G4AdjointBremsstrahlungModel():
|
||||
G4VEmAdjointModel("AdjointeBremModel")
|
||||
G4AdjointBremsstrahlungModel::G4AdjointBremsstrahlungModel()
|
||||
: G4VEmAdjointModel("AdjointeBremModel")
|
||||
{
|
||||
fDirectModel = new G4SeltzerBergerModel();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointBremsstrahlungModel::Initialize()
|
||||
{
|
||||
SetUseMatrix(false);
|
||||
SetUseMatrixPerElement(false);
|
||||
|
||||
theDirectStdBremModel = new G4SeltzerBergerModel();
|
||||
theDirectEMModel=theDirectStdBremModel;
|
||||
theEmModelManagerForFwdModels = new G4EmModelManager();
|
||||
isDirectModelInitialised = false;
|
||||
G4VEmFluctuationModel* f=0;
|
||||
G4Region* r=0;
|
||||
theEmModelManagerForFwdModels->AddEmModel(1, theDirectStdBremModel, f, r);
|
||||
// theDirectPenelopeBremModel =0;
|
||||
fEmModelManagerForFwdModels = new G4EmModelManager();
|
||||
fEmModelManagerForFwdModels->AddEmModel(1, fDirectModel, nullptr, nullptr);
|
||||
SetApplyCutInRange(true);
|
||||
highKinEnergy= 1.*GeV;
|
||||
lowKinEnergy = 1.0*keV;
|
||||
lastCZ =0.;
|
||||
theAdjEquivOfDirectPrimPartDef =G4AdjointElectron::AdjointElectron();
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointGamma::AdjointGamma();
|
||||
theDirectPrimaryPartDef=G4Electron::Electron();
|
||||
second_part_of_same_type=false;
|
||||
|
||||
fElectron = G4Electron::Electron();
|
||||
fGamma = G4Gamma::Gamma();
|
||||
|
||||
fAdjEquivDirectPrimPart = G4AdjointElectron::AdjointElectron();
|
||||
fAdjEquivDirectSecondPart = G4AdjointGamma::AdjointGamma();
|
||||
fDirectPrimaryPart = fElectron;
|
||||
fSecondPartSameType = false;
|
||||
|
||||
fCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointBremsstrahlungModel::~G4AdjointBremsstrahlungModel()
|
||||
{if (theDirectStdBremModel) delete theDirectStdBremModel;
|
||||
if (theEmModelManagerForFwdModels) delete theEmModelManagerForFwdModels;
|
||||
{
|
||||
if(fEmModelManagerForFwdModels)
|
||||
delete fEmModelManagerForFwdModels;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointBremsstrahlungModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
void G4AdjointBremsstrahlungModel::SampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
if (!UseMatrix) return RapidSampleSecondaries(aTrack,IsScatProjToProjCase,fParticleChange);
|
||||
if(!fUseMatrix)
|
||||
return RapidSampleSecondaries(aTrack, isScatProjToProj, fParticleChange);
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimTotalEnergy = theAdjointPrimary->GetTotalEnergy();
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
G4double projectileKinEnergy = SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy,
|
||||
IsScatProjToProjCase);
|
||||
//Weight correction
|
||||
//-----------------------
|
||||
CorrectPostStepWeight(fParticleChange,
|
||||
aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy,
|
||||
projectileKinEnergy,
|
||||
IsScatProjToProjCase);
|
||||
|
||||
|
||||
//Kinematic
|
||||
//---------
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
G4double projectileP = std::sqrt(projectileP2);
|
||||
|
||||
|
||||
//Angle of the gamma direction with the projectile taken from G4eBremsstrahlungModel
|
||||
//------------------------------------------------
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimTotalEnergy = theAdjointPrimary->GetTotalEnergy();
|
||||
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4double projectileKinEnergy =
|
||||
SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, isScatProjToProj);
|
||||
|
||||
// Weight correction
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy, projectileKinEnergy,
|
||||
isScatProjToProj);
|
||||
|
||||
// Kinematic
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
G4double projectileP = std::sqrt(projectileP2);
|
||||
|
||||
// Angle of the gamma direction with the projectile taken from
|
||||
// G4eBremsstrahlungModel
|
||||
G4double u;
|
||||
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
|
||||
if(0.25 > G4UniformRand())
|
||||
u = -std::log(G4UniformRand() * G4UniformRand()) / 0.625;
|
||||
else
|
||||
u = -std::log(G4UniformRand() * G4UniformRand()) / 1.875;
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u = - std::log(G4UniformRand()*G4UniformRand())/a1;
|
||||
else u = - std::log(G4UniformRand()*G4UniformRand())/a2;
|
||||
G4double theta = u * electron_mass_c2 / projectileTotalEnergy;
|
||||
G4double sint = std::sin(theta);
|
||||
G4double cost = std::cos(theta);
|
||||
|
||||
G4double theta = u*electron_mass_c2/projectileTotalEnergy;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
|
||||
G4double sint = std::sin(theta);
|
||||
G4double cost = std::cos(theta);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
G4ThreeVector projectileMomentum;
|
||||
projectileMomentum=G4ThreeVector(std::cos(phi)*sint,std::sin(phi)*sint,cost)*projectileP; //gamma frame
|
||||
if (IsScatProjToProjCase) {//the adjoint primary is the scattered e-
|
||||
G4ThreeVector gammaMomentum = (projectileTotalEnergy-adjointPrimTotalEnergy)*G4ThreeVector(0.,0.,1.);
|
||||
G4ThreeVector dirProd=projectileMomentum-gammaMomentum;
|
||||
G4double cost1 = std::cos(dirProd.angle(projectileMomentum));
|
||||
G4double sint1 = std::sqrt(1.-cost1*cost1);
|
||||
projectileMomentum=G4ThreeVector(std::cos(phi)*sint1,std::sin(phi)*sint1,cost1)*projectileP;
|
||||
|
||||
G4ThreeVector projectileMomentum =
|
||||
G4ThreeVector(std::cos(phi) * sint, std::sin(phi) * sint, cost) *
|
||||
projectileP; // gamma frame
|
||||
if(isScatProjToProj)
|
||||
{ // the adjoint primary is the scattered e-
|
||||
G4ThreeVector gammaMomentum =
|
||||
(projectileTotalEnergy - adjointPrimTotalEnergy) *
|
||||
G4ThreeVector(0., 0., 1.);
|
||||
G4ThreeVector dirProd = projectileMomentum - gammaMomentum;
|
||||
G4double cost1 = std::cos(dirProd.angle(projectileMomentum));
|
||||
G4double sint1 = std::sqrt(1. - cost1 * cost1);
|
||||
projectileMomentum =
|
||||
G4ThreeVector(std::cos(phi) * sint1, std::sin(phi) * sint1, cost1) *
|
||||
projectileP;
|
||||
}
|
||||
|
||||
|
||||
projectileMomentum.rotateUz(theAdjointPrimary->GetMomentumDirection());
|
||||
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointBremsstrahlungModel::RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
void G4AdjointBremsstrahlungModel::RapidSampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimTotalEnergy = theAdjointPrimary->GetTotalEnergy();
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
G4double projectileKinEnergy =0.;
|
||||
G4double gammaEnergy=0.;
|
||||
G4double diffCSUsed=0.;
|
||||
if (!IsScatProjToProjCase){
|
||||
gammaEnergy=adjointPrimKinEnergy;
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin= GetSecondAdjEnergyMinForProdToProjCase(adjointPrimKinEnergy);;
|
||||
if (Emin>=Emax) return;
|
||||
projectileKinEnergy=Emin*std::pow(Emax/Emin,G4UniformRand());
|
||||
diffCSUsed=CS_biasing_factor*lastCZ/projectileKinEnergy;
|
||||
|
||||
}
|
||||
else { G4double Emax = GetSecondAdjEnergyMaxForScatProjToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForScatProjToProjCase(adjointPrimKinEnergy,currentTcutForDirectSecond);
|
||||
if (Emin>=Emax) return;
|
||||
G4double f1=(Emin-adjointPrimKinEnergy)/Emin;
|
||||
G4double f2=(Emax-adjointPrimKinEnergy)/Emax/f1;
|
||||
projectileKinEnergy=adjointPrimKinEnergy/(1.-f1*std::pow(f2,G4UniformRand()));
|
||||
gammaEnergy=projectileKinEnergy-adjointPrimKinEnergy;
|
||||
diffCSUsed=lastCZ*adjointPrimKinEnergy/projectileKinEnergy/gammaEnergy;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Weight correction
|
||||
//-----------------------
|
||||
//First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
//if this has to be done in the model
|
||||
//For the case of forced interaction this will be done in the PostStepDoIt of the
|
||||
//forced interaction
|
||||
//It is important to set the weight before the vreation of the secondary
|
||||
//
|
||||
G4double w_corr=additional_weight_correction_factor_for_post_step_outside_model;
|
||||
if (correct_weight_for_post_step_in_model) {
|
||||
w_corr=G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
}
|
||||
//G4cout<<"Correction factor start in brem model "<<w_corr<<std::endl;
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimTotalEnergy = theAdjointPrimary->GetTotalEnergy();
|
||||
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Then another correction is needed due to the fact that a biaised differential CS has been used rather than the one consistent with the direct model
|
||||
//Here we consider the true diffCS as the one obtained by the numericla differentiation over Tcut of the direct CS, corrected by the Migdal term.
|
||||
//Basically any other differential CS diffCS could be used here (example Penelope).
|
||||
G4double projectileKinEnergy = 0.;
|
||||
G4double gammaEnergy = 0.;
|
||||
G4double diffCSUsed = 0.;
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
gammaEnergy = adjointPrimKinEnergy;
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProj(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForProdToProj(adjointPrimKinEnergy);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
projectileKinEnergy = Emin * std::pow(Emax / Emin, G4UniformRand());
|
||||
diffCSUsed = fCsBiasingFactor * fLastCZ / projectileKinEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Emax =
|
||||
GetSecondAdjEnergyMaxForScatProjToProj(adjointPrimKinEnergy);
|
||||
G4double Emin =
|
||||
GetSecondAdjEnergyMinForScatProjToProj(adjointPrimKinEnergy, fTcutSecond);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
G4double f1 = (Emin - adjointPrimKinEnergy) / Emin;
|
||||
G4double f2 = (Emax - adjointPrimKinEnergy) / Emax / f1;
|
||||
projectileKinEnergy =
|
||||
adjointPrimKinEnergy / (1. - f1 * std::pow(f2, G4UniformRand()));
|
||||
gammaEnergy = projectileKinEnergy - adjointPrimKinEnergy;
|
||||
diffCSUsed =
|
||||
fLastCZ * adjointPrimKinEnergy / projectileKinEnergy / gammaEnergy;
|
||||
}
|
||||
|
||||
G4double diffCS = DiffCrossSectionPerVolumePrimToSecond(currentMaterial, projectileKinEnergy, gammaEnergy);
|
||||
/*G4cout<<"diffCS "<<diffCS <<std::endl;
|
||||
G4cout<<"diffCS_Used "<<diffCSUsed <<std::endl;*/
|
||||
w_corr*=diffCS/diffCSUsed;
|
||||
// Weight correction:
|
||||
// First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
// if this has to be done in the model.
|
||||
// For the case of forced interaction this will be done in the PostStepDoIt of
|
||||
// the forced interaction. It is important to set the weight before the
|
||||
// creation of the secondary
|
||||
G4double w_corr = fOutsideWeightFactor;
|
||||
if(fInModelWeightCorr)
|
||||
{
|
||||
w_corr = fCSManager->GetPostStepWeightCorrection();
|
||||
}
|
||||
|
||||
// Then another correction is needed due to the fact that a biaised
|
||||
// differential CS has been used rather than the one consistent with the
|
||||
// direct model Here we consider the true diffCS as the one obtained by the
|
||||
// numerical differentiation over Tcut of the direct CS, corrected by the
|
||||
// Migdal term. Basically any other differential CS could be used here
|
||||
// (example Penelope).
|
||||
G4double diffCS = DiffCrossSectionPerVolumePrimToSecond(
|
||||
fCurrentMaterial, projectileKinEnergy, gammaEnergy);
|
||||
w_corr *= diffCS / diffCSUsed;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight()*w_corr;
|
||||
/*G4cout<<"New weight brem "<<new_weight<<std::endl;
|
||||
G4cout<<"Weight correction brem "<<w_corr<<std::endl;*/
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
//Kinematic
|
||||
//---------
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
G4double projectileP = std::sqrt(projectileP2);
|
||||
|
||||
G4double new_weight = aTrack.GetWeight() * w_corr;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
//Use the angular model of the forward model to generate the gamma direction
|
||||
//---------------------------------------------------------------------------
|
||||
//Dum dynamic particle to use the model
|
||||
G4DynamicParticle * aDynPart = new G4DynamicParticle(G4Electron::Electron(),G4ThreeVector(0.,0.,1.)*projectileP);
|
||||
// Kinematic
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
G4double projectileP = std::sqrt(projectileP2);
|
||||
|
||||
//Get the element from the direct model
|
||||
const G4Element* elm = theDirectEMModel->SelectRandomAtom(currentCouple,G4Electron::Electron(),
|
||||
projectileKinEnergy,currentTcutForDirectSecond);
|
||||
G4int Z=elm->GetZasInt();
|
||||
G4double energy = aDynPart->GetTotalEnergy()-gammaEnergy;
|
||||
G4ThreeVector projectileMomentum =
|
||||
theDirectEMModel->GetAngularDistribution()->SampleDirection(aDynPart,energy,Z,currentMaterial)*projectileP;
|
||||
// Use the angular model of the forward model to generate the gamma direction
|
||||
// Dummy dynamic particle to use the model
|
||||
G4DynamicParticle* aDynPart =
|
||||
new G4DynamicParticle(fElectron, G4ThreeVector(0., 0., 1.) * projectileP);
|
||||
|
||||
// Get the element from the direct model
|
||||
const G4Element* elm = fDirectModel->SelectRandomAtom(
|
||||
fCurrentCouple, fElectron, projectileKinEnergy, fTcutSecond);
|
||||
G4int Z = elm->GetZasInt();
|
||||
G4double energy = aDynPart->GetTotalEnergy() - gammaEnergy;
|
||||
G4ThreeVector projectileMomentum =
|
||||
fDirectModel->GetAngularDistribution()->SampleDirection(aDynPart, energy, Z,
|
||||
fCurrentMaterial) * projectileP;
|
||||
G4double phi = projectileMomentum.getPhi();
|
||||
|
||||
/*
|
||||
//Angle of the gamma direction with the projectile taken from G4eBremsstrahlungModel
|
||||
//------------------------------------------------
|
||||
G4double u;
|
||||
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u = - std::log(G4UniformRand()*G4UniformRand())/a1;
|
||||
else u = - std::log(G4UniformRand()*G4UniformRand())/a2;
|
||||
|
||||
G4double theta = u*electron_mass_c2/projectileTotalEnergy;
|
||||
|
||||
G4double sint = std::sin(theta);
|
||||
G4double cost = std::cos(theta);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4ThreeVector projectileMomentum;
|
||||
projectileMomentum=G4ThreeVector(std::cos(phi)*sint,std::sin(phi)*sint,cost)*projectileP; //gamma frame
|
||||
*/
|
||||
if (IsScatProjToProjCase) {//the adjoint primary is the scattered e-
|
||||
G4ThreeVector gammaMomentum = (projectileTotalEnergy-adjointPrimTotalEnergy)*G4ThreeVector(0.,0.,1.);
|
||||
G4ThreeVector dirProd=projectileMomentum-gammaMomentum;
|
||||
G4double cost1 = std::cos(dirProd.angle(projectileMomentum));
|
||||
G4double sint1 = std::sqrt(1.-cost1*cost1);
|
||||
projectileMomentum=G4ThreeVector(std::cos(phi)*sint1,std::sin(phi)*sint1,cost1)*projectileP;
|
||||
if(isScatProjToProj)
|
||||
{ // the adjoint primary is the scattered e-
|
||||
G4ThreeVector gammaMomentum =
|
||||
(projectileTotalEnergy - adjointPrimTotalEnergy) *
|
||||
G4ThreeVector(0., 0., 1.);
|
||||
G4ThreeVector dirProd = projectileMomentum - gammaMomentum;
|
||||
G4double cost1 = std::cos(dirProd.angle(projectileMomentum));
|
||||
G4double sint1 = std::sqrt(1. - cost1 * cost1);
|
||||
projectileMomentum =
|
||||
G4ThreeVector(std::cos(phi) * sint1, std::sin(phi) * sint1, cost1) *
|
||||
projectileP;
|
||||
}
|
||||
|
||||
projectileMomentum.rotateUz(theAdjointPrimary->GetMomentumDirection());
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointBremsstrahlungModel::DiffCrossSectionPerVolumePrimToSecond(const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
)
|
||||
{if (!isDirectModelInitialised) {
|
||||
theEmModelManagerForFwdModels->Initialise(G4Electron::Electron(),G4Gamma::Gamma(),1.,0);
|
||||
isDirectModelInitialised =true;
|
||||
}
|
||||
/*
|
||||
return DiffCrossSectionPerVolumePrimToSecondApproximated2(aMaterial,
|
||||
kinEnergyProj,
|
||||
kinEnergyProd);
|
||||
*/
|
||||
return G4VEmAdjointModel::DiffCrossSectionPerVolumePrimToSecond(aMaterial,
|
||||
kinEnergyProj,
|
||||
kinEnergyProd);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointBremsstrahlungModel::DiffCrossSectionPerVolumePrimToSecondApproximated1(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
)
|
||||
{
|
||||
G4double dCrossEprod=0.;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(kinEnergyProd);
|
||||
|
||||
|
||||
//In this approximation we consider that the secondary gammas are sampled with 1/Egamma energy distribution
|
||||
//This is what is applied in the discrete standard model before the rejection test that make a correction
|
||||
//The application of the same rejection function is not possible here.
|
||||
//The differentiation of the CS over Ecut does not produce neither a good differential CS. That is due to the
|
||||
// fact that in the discrete model the differential CS and the integrated CS are both fitted but separatly and
|
||||
// therefore do not allow a correct numerical differentiation of the integrated CS to get the differential one.
|
||||
// In the future we plan to use the brem secondary spectra from the G4Penelope implementation
|
||||
|
||||
if (kinEnergyProj>Emin_proj && kinEnergyProj<=Emax_proj){
|
||||
G4double sigma=theDirectEMModel->CrossSectionPerVolume(aMaterial,theDirectPrimaryPartDef,kinEnergyProj,1.*keV);
|
||||
dCrossEprod=sigma/kinEnergyProd/std::log(kinEnergyProj/keV);
|
||||
}
|
||||
return dCrossEprod;
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointBremsstrahlungModel::DiffCrossSectionPerVolumePrimToSecondApproximated2(
|
||||
const G4Material* material,
|
||||
G4double kinEnergyProj, // kinetic energy of the primary particle before the interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
)
|
||||
G4double G4AdjointBremsstrahlungModel::DiffCrossSectionPerVolumePrimToSecond(
|
||||
const G4Material* aMaterial,
|
||||
G4double kinEnergyProj, // kin energy of primary before interaction
|
||||
G4double kinEnergyProd // kinetic energy of the secondary particle
|
||||
)
|
||||
{
|
||||
//In this approximation we derive the direct cross section over Tcut=gamma energy, en after apply the Migdla correction factor
|
||||
//used in the direct model
|
||||
|
||||
G4double dCrossEprod=0.;
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
G4double dum=0.;
|
||||
G4double E1=kinEnergyProd,E2=kinEnergyProd*1.001;
|
||||
G4double dE=E2-E1;
|
||||
for (size_t i=0; i<material->GetNumberOfElements(); i++) {
|
||||
G4double C1=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,(*theElementVector)[i]->GetZ(),dum ,E1);
|
||||
G4double C2=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,(*theElementVector)[i]->GetZ(),dum,E2);
|
||||
dCrossEprod += theAtomNumDensityVector[i] * (C1-C2)/dE;
|
||||
}
|
||||
|
||||
return dCrossEprod;
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointBremsstrahlungModel::AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{ if (!isDirectModelInitialised) {
|
||||
theEmModelManagerForFwdModels->Initialise(G4Electron::Electron(),G4Gamma::Gamma(),1.,0);
|
||||
isDirectModelInitialised =true;
|
||||
if(!fIsDirectModelInitialised)
|
||||
{
|
||||
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 1., 0);
|
||||
fIsDirectModelInitialised = true;
|
||||
}
|
||||
if (UseMatrix) return G4VEmAdjointModel::AdjointCrossSection(aCouple,primEnergy,IsScatProjToProjCase);
|
||||
return G4VEmAdjointModel::DiffCrossSectionPerVolumePrimToSecond(
|
||||
aMaterial, kinEnergyProj, kinEnergyProd);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointBremsstrahlungModel::AdjointCrossSection(
|
||||
const G4MaterialCutsCouple* aCouple, G4double primEnergy,
|
||||
G4bool isScatProjToProj)
|
||||
{
|
||||
static constexpr G4double maxEnergy = 100. * MeV / 2.718281828459045;
|
||||
// 2.78.. == std::exp(1.)
|
||||
if(!fIsDirectModelInitialised)
|
||||
{
|
||||
fEmModelManagerForFwdModels->Initialise(fElectron, fGamma, 1., 0);
|
||||
fIsDirectModelInitialised = true;
|
||||
}
|
||||
if(fUseMatrix)
|
||||
return G4VEmAdjointModel::AdjointCrossSection(aCouple, primEnergy,
|
||||
isScatProjToProj);
|
||||
DefineCurrentMaterial(aCouple);
|
||||
G4double Cross=0.;
|
||||
lastCZ=theDirectEMModel->CrossSectionPerVolume(aCouple->GetMaterial(),theDirectPrimaryPartDef,100.*MeV,100.*MeV/std::exp(1.));//this give the constant above
|
||||
|
||||
if (!IsScatProjToProjCase ){
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(primEnergy);
|
||||
if (Emax_proj>Emin_proj && primEnergy > currentTcutForDirectSecond) Cross= CS_biasing_factor*lastCZ*std::log(Emax_proj/Emin_proj);
|
||||
}
|
||||
else {
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForScatProjToProjCase(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForScatProjToProjCase(primEnergy,currentTcutForDirectSecond);
|
||||
if (Emax_proj>Emin_proj) Cross= lastCZ*std::log((Emax_proj-primEnergy)*Emin_proj/Emax_proj/(Emin_proj-primEnergy));
|
||||
|
||||
}
|
||||
return Cross;
|
||||
}
|
||||
G4double Cross = 0.;
|
||||
// this gives the constant above
|
||||
fLastCZ = fDirectModel->CrossSectionPerVolume(
|
||||
aCouple->GetMaterial(), fDirectPrimaryPart, 100. * MeV, maxEnergy);
|
||||
|
||||
G4double G4AdjointBremsstrahlungModel::GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{
|
||||
return AdjointCrossSection(aCouple, primEnergy,IsScatProjToProjCase);
|
||||
lastCZ=theDirectEMModel->CrossSectionPerVolume(aCouple->GetMaterial(),theDirectPrimaryPartDef,100.*MeV,100.*MeV/std::exp(1.));//this give the constant above
|
||||
return G4VEmAdjointModel::GetAdjointCrossSection(aCouple, primEnergy,IsScatProjToProjCase);
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(primEnergy);
|
||||
if(Emax_proj > Emin_proj && primEnergy > fTcutSecond)
|
||||
Cross = fCsBiasingFactor * fLastCZ * std::log(Emax_proj / Emin_proj);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForScatProjToProj(primEnergy);
|
||||
G4double Emin_proj =
|
||||
GetSecondAdjEnergyMinForScatProjToProj(primEnergy, fTcutSecond);
|
||||
if(Emax_proj > Emin_proj)
|
||||
Cross = fLastCZ * std::log((Emax_proj - primEnergy) * Emin_proj /
|
||||
Emax_proj / (Emin_proj - primEnergy));
|
||||
}
|
||||
return Cross;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,177 +23,198 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
///////////////////////////////////////////////////////
|
||||
G4AdjointCSMatrix::G4AdjointCSMatrix(G4bool aBool) { fScatProjToProj = aBool; }
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointCSMatrix::G4AdjointCSMatrix(G4bool aBool){
|
||||
theLogPrimEnergyVector.clear();
|
||||
theLogCrossSectionVector.clear();
|
||||
theLogSecondEnergyMatrix.clear();
|
||||
theLogProbMatrix.clear();
|
||||
theLogProbMatrixIndex.clear();
|
||||
log0Vector.clear();
|
||||
nb_of_PrimEnergy=0;
|
||||
is_scat_proj_to_proj_case =aBool;
|
||||
dlog =0;
|
||||
G4AdjointCSMatrix::~G4AdjointCSMatrix()
|
||||
{
|
||||
fLogPrimEnergyVector.clear();
|
||||
fLogCrossSectionVector.clear();
|
||||
|
||||
for (auto p : fLogSecondEnergyMatrix) {
|
||||
p->clear();
|
||||
delete p;
|
||||
p = nullptr;
|
||||
}
|
||||
fLogSecondEnergyMatrix.clear();
|
||||
|
||||
for (auto p : fLogProbMatrix) {
|
||||
p->clear();
|
||||
delete p;
|
||||
p = nullptr;
|
||||
}
|
||||
fLogProbMatrix.clear();
|
||||
|
||||
for (auto p : fLogProbMatrixIndex) {
|
||||
if (p) {
|
||||
p->clear();
|
||||
delete p;
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
fLogProbMatrixIndex.clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointCSMatrix::~G4AdjointCSMatrix(){
|
||||
theLogPrimEnergyVector.clear();
|
||||
theLogCrossSectionVector.clear();
|
||||
theLogSecondEnergyMatrix.clear();
|
||||
theLogProbMatrix.clear();
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointCSMatrix::Clear()
|
||||
{
|
||||
theLogPrimEnergyVector.clear();
|
||||
theLogCrossSectionVector.clear();
|
||||
theLogSecondEnergyMatrix.clear();
|
||||
theLogProbMatrix.clear();
|
||||
theLogProbMatrixIndex.clear();
|
||||
log0Vector.clear();
|
||||
nb_of_PrimEnergy=0;
|
||||
fLogPrimEnergyVector.clear();
|
||||
fLogCrossSectionVector.clear();
|
||||
fLogSecondEnergyMatrix.clear();
|
||||
fLogProbMatrix.clear();
|
||||
fLogProbMatrixIndex.clear();
|
||||
fLog0Vector.clear();
|
||||
fNbPrimEnergy = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointCSMatrix::AddData(G4double aLogPrimEnergy,G4double aLogCS, std::vector< double>* aLogSecondEnergyVector,
|
||||
std::vector< double>* aLogProbVector,size_t n_pro_decade){
|
||||
|
||||
G4AdjointInterpolator* theInterpolator=G4AdjointInterpolator::GetInstance();
|
||||
|
||||
//At this time we consider that the energy is increasing monotically
|
||||
theLogPrimEnergyVector.push_back(aLogPrimEnergy);
|
||||
theLogCrossSectionVector.push_back(aLogCS);
|
||||
theLogSecondEnergyMatrix.push_back(aLogSecondEnergyVector);
|
||||
theLogProbMatrix.push_back(aLogProbVector);
|
||||
|
||||
std::vector< size_t>* aLogProbVectorIndex = 0;
|
||||
dlog =0;
|
||||
|
||||
if (n_pro_decade > 0 && aLogProbVector->size()>0) {
|
||||
aLogProbVectorIndex = new std::vector< size_t>();
|
||||
dlog=std::log(10.)/n_pro_decade;
|
||||
G4double log_val = int(std::min((*aLogProbVector)[0],aLogProbVector->back())/dlog)*dlog;
|
||||
log0Vector.push_back(log_val);
|
||||
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while(log_val<0.) {
|
||||
aLogProbVectorIndex->push_back(theInterpolator->FindPosition(log_val,(*aLogProbVector)));
|
||||
log_val+=dlog;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log0Vector.push_back(0.);
|
||||
}
|
||||
theLogProbMatrixIndex.push_back(aLogProbVectorIndex);
|
||||
|
||||
|
||||
nb_of_PrimEnergy++;
|
||||
|
||||
|
||||
void G4AdjointCSMatrix::AddData(G4double aLogPrimEnergy, G4double aLogCS,
|
||||
std::vector<double>* aLogSecondEnergyVector,
|
||||
std::vector<double>* aLogProbVector,
|
||||
size_t n_pro_decade)
|
||||
{
|
||||
G4AdjointInterpolator* theInterpolator = G4AdjointInterpolator::GetInstance();
|
||||
|
||||
// At this time we consider that the energy is increasing monotically
|
||||
fLogPrimEnergyVector.push_back(aLogPrimEnergy);
|
||||
fLogCrossSectionVector.push_back(aLogCS);
|
||||
fLogSecondEnergyMatrix.push_back(aLogSecondEnergyVector);
|
||||
fLogProbMatrix.push_back(aLogProbVector);
|
||||
|
||||
std::vector<size_t>* aLogProbVectorIndex = nullptr;
|
||||
|
||||
if(n_pro_decade > 0 && !aLogProbVector->empty())
|
||||
{
|
||||
aLogProbVectorIndex = new std::vector<size_t>();
|
||||
G4double dlog = std::log(10.) / n_pro_decade;
|
||||
G4double log_val =
|
||||
int(std::min((*aLogProbVector)[0], aLogProbVector->back()) / dlog) * dlog;
|
||||
fLog0Vector.push_back(log_val);
|
||||
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while(log_val < 0.)
|
||||
{
|
||||
aLogProbVectorIndex->push_back(
|
||||
theInterpolator->FindPosition(log_val, (*aLogProbVector)));
|
||||
log_val += dlog;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fLog0Vector.push_back(0.);
|
||||
}
|
||||
fLogProbMatrixIndex.push_back(aLogProbVectorIndex);
|
||||
|
||||
++fNbPrimEnergy;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4bool G4AdjointCSMatrix::GetData(unsigned int i, G4double& aLogPrimEnergy,G4double& aLogCS,G4double& log0, std::vector< double>*& aLogSecondEnergyVector,
|
||||
std::vector< double>*& aLogProbVector, std::vector< size_t>*& aLogProbVectorIndex)
|
||||
{ if (i>= nb_of_PrimEnergy) return false;
|
||||
//G4cout<<"Test Get Data "<<G4endl;
|
||||
aLogPrimEnergy = theLogPrimEnergyVector[i];
|
||||
aLogCS = theLogCrossSectionVector[i];
|
||||
aLogSecondEnergyVector = theLogSecondEnergyMatrix[i];
|
||||
aLogProbVector = theLogProbMatrix[i];
|
||||
aLogProbVectorIndex = theLogProbMatrixIndex[i];
|
||||
log0=log0Vector[i];
|
||||
return true;
|
||||
|
||||
G4bool G4AdjointCSMatrix::GetData(unsigned int i, G4double& aLogPrimEnergy,
|
||||
G4double& aLogCS, G4double& log0,
|
||||
std::vector<double>*& aLogSecondEnergyVector,
|
||||
std::vector<double>*& aLogProbVector,
|
||||
std::vector<size_t>*& aLogProbVectorIndex)
|
||||
{
|
||||
if(i >= fNbPrimEnergy)
|
||||
return false;
|
||||
aLogPrimEnergy = fLogPrimEnergyVector[i];
|
||||
aLogCS = fLogCrossSectionVector[i];
|
||||
aLogSecondEnergyVector = fLogSecondEnergyMatrix[i];
|
||||
aLogProbVector = fLogProbMatrix[i];
|
||||
aLogProbVectorIndex = fLogProbMatrixIndex[i];
|
||||
log0 = fLog0Vector[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointCSMatrix::Write(G4String file_name)
|
||||
{ std::fstream FileOutput(file_name, std::ios::out);
|
||||
FileOutput<<std::setiosflags(std::ios::scientific);
|
||||
FileOutput<<std::setprecision(6);
|
||||
FileOutput<<theLogPrimEnergyVector.size()<<G4endl;
|
||||
for (size_t i=0;i<theLogPrimEnergyVector.size();i++){
|
||||
FileOutput<<std::exp(theLogPrimEnergyVector[i])/MeV<<'\t'<<std::exp(theLogCrossSectionVector[i])<<G4endl;
|
||||
size_t j1=0;
|
||||
FileOutput<<theLogSecondEnergyMatrix[i]->size()<<G4endl;
|
||||
for (size_t j=0;j<theLogSecondEnergyMatrix[i]->size();j++){
|
||||
FileOutput<<std::exp((*theLogSecondEnergyMatrix[i])[j]);
|
||||
j1++;
|
||||
if (j1<10) FileOutput<<'\t';
|
||||
else {
|
||||
FileOutput<<G4endl;
|
||||
j1=0;
|
||||
}
|
||||
}
|
||||
if (j1>0) FileOutput<<G4endl;
|
||||
j1=0;
|
||||
FileOutput<<theLogProbMatrix[i]->size()<<G4endl;
|
||||
for (size_t j=0;j<theLogProbMatrix[i]->size();j++){
|
||||
FileOutput<<std::exp((*theLogProbMatrix[i])[j]);
|
||||
j1++;
|
||||
if (j1<10) FileOutput<<'\t';
|
||||
else {
|
||||
FileOutput<<G4endl;
|
||||
j1=0;
|
||||
}
|
||||
}
|
||||
if (j1>0) FileOutput<<G4endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
std::fstream FileOutput(file_name, std::ios::out);
|
||||
FileOutput << std::setiosflags(std::ios::scientific);
|
||||
FileOutput << std::setprecision(6);
|
||||
FileOutput << fLogPrimEnergyVector.size() << G4endl;
|
||||
for(size_t i = 0; i < fLogPrimEnergyVector.size(); ++i)
|
||||
{
|
||||
FileOutput << std::exp(fLogPrimEnergyVector[i]) / MeV << '\t'
|
||||
<< std::exp(fLogCrossSectionVector[i]) << G4endl;
|
||||
size_t j1 = 0;
|
||||
FileOutput << fLogSecondEnergyMatrix[i]->size() << G4endl;
|
||||
for(size_t j = 0; j < fLogSecondEnergyMatrix[i]->size(); ++j)
|
||||
{
|
||||
FileOutput << std::exp((*fLogSecondEnergyMatrix[i])[j]);
|
||||
++j1;
|
||||
if(j1 < 10)
|
||||
FileOutput << '\t';
|
||||
else
|
||||
{
|
||||
FileOutput << G4endl;
|
||||
j1 = 0;
|
||||
}
|
||||
}
|
||||
if(j1 > 0)
|
||||
FileOutput << G4endl;
|
||||
j1 = 0;
|
||||
FileOutput << fLogProbMatrix[i]->size() << G4endl;
|
||||
for(size_t j = 0; j < fLogProbMatrix[i]->size(); ++j)
|
||||
{
|
||||
FileOutput << std::exp((*fLogProbMatrix[i])[j]);
|
||||
++j1;
|
||||
if(j1 < 10)
|
||||
FileOutput << '\t';
|
||||
else
|
||||
{
|
||||
FileOutput << G4endl;
|
||||
j1 = 0;
|
||||
}
|
||||
}
|
||||
if(j1 > 0)
|
||||
FileOutput << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointCSMatrix::Read(G4String file_name)
|
||||
{ std::fstream FileOutput(file_name, std::ios::in);
|
||||
size_t n1,n2;
|
||||
|
||||
|
||||
theLogPrimEnergyVector.clear();
|
||||
theLogCrossSectionVector.clear();
|
||||
theLogSecondEnergyMatrix.clear();
|
||||
theLogProbMatrix.clear();
|
||||
FileOutput>>n1;
|
||||
for (size_t i=0; i<n1;i++){
|
||||
G4double E,CS;
|
||||
FileOutput>>E>>CS;
|
||||
theLogPrimEnergyVector.push_back(E);
|
||||
theLogCrossSectionVector.push_back(CS);
|
||||
FileOutput>>n2;
|
||||
theLogSecondEnergyMatrix.push_back(new std::vector<G4double>());
|
||||
theLogProbMatrix.push_back(new std::vector<G4double>());
|
||||
|
||||
for (size_t j=0; j<n2;j++){
|
||||
G4double E1;
|
||||
FileOutput>>E1;
|
||||
theLogSecondEnergyMatrix[i]->push_back(E1);
|
||||
}
|
||||
FileOutput>>n2;
|
||||
for (size_t j=0; j<n2;j++){
|
||||
G4double prob;
|
||||
FileOutput>>prob;
|
||||
theLogProbMatrix[i]->push_back(prob);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
std::fstream FileOutput(file_name, std::ios::in);
|
||||
size_t n1, n2;
|
||||
|
||||
fLogPrimEnergyVector.clear();
|
||||
fLogCrossSectionVector.clear();
|
||||
fLogSecondEnergyMatrix.clear();
|
||||
fLogProbMatrix.clear();
|
||||
FileOutput >> n1;
|
||||
for(size_t i = 0; i < n1; ++i)
|
||||
{
|
||||
G4double E, CS;
|
||||
FileOutput >> E >> CS;
|
||||
fLogPrimEnergyVector.push_back(E);
|
||||
fLogCrossSectionVector.push_back(CS);
|
||||
FileOutput >> n2;
|
||||
fLogSecondEnergyMatrix.push_back(new std::vector<G4double>());
|
||||
fLogProbMatrix.push_back(new std::vector<G4double>());
|
||||
|
||||
for(size_t j = 0; j < n2; ++j)
|
||||
{
|
||||
G4double E1;
|
||||
FileOutput >> E1;
|
||||
fLogSecondEnergyMatrix[i]->push_back(E1);
|
||||
}
|
||||
FileOutput >> n2;
|
||||
for(size_t j = 0; j < n2; ++j)
|
||||
{
|
||||
G4double prob;
|
||||
FileOutput >> prob;
|
||||
fLogProbMatrix[i]->push_back(prob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,395 +24,339 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
#include "G4AdjointComptonModel.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointComptonModel.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4KleinNishinaCompton.hh"
|
||||
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4VEmProcess.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointComptonModel::G4AdjointComptonModel():
|
||||
G4VEmAdjointModel("AdjointCompton")
|
||||
|
||||
{ SetApplyCutInRange(false);
|
||||
G4AdjointComptonModel::G4AdjointComptonModel()
|
||||
: G4VEmAdjointModel("AdjointCompton")
|
||||
{
|
||||
SetApplyCutInRange(false);
|
||||
SetUseMatrix(false);
|
||||
SetUseMatrixPerElement(true);
|
||||
SetUseOnlyOneMatrixForAllElements(true);
|
||||
theAdjEquivOfDirectPrimPartDef =G4AdjointGamma::AdjointGamma();
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron();
|
||||
theDirectPrimaryPartDef=G4Gamma::Gamma();
|
||||
second_part_of_same_type=false;
|
||||
theDirectEMModel=new G4KleinNishinaCompton(G4Gamma::Gamma(),"ComptonDirectModel");
|
||||
G4direct_CS = 0.;
|
||||
fAdjEquivDirectPrimPart = G4AdjointGamma::AdjointGamma();
|
||||
fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
|
||||
fDirectPrimaryPart = G4Gamma::Gamma();
|
||||
fSecondPartSameType = false;
|
||||
fDirectModel =
|
||||
new G4KleinNishinaCompton(G4Gamma::Gamma(), "ComptonDirectModel");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointComptonModel::~G4AdjointComptonModel()
|
||||
{;}
|
||||
G4AdjointComptonModel::~G4AdjointComptonModel() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointComptonModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
if (!UseMatrix) return RapidSampleSecondaries(aTrack,IsScatProjToProjCase,fParticleChange);
|
||||
|
||||
//A recall of the compton scattering law is
|
||||
//Egamma2=Egamma1/(1+(Egamma1/E0_electron)(1.-cos_th))
|
||||
//Therefore Egamma2_max= Egamma2(cos_th=1) = Egamma1
|
||||
//Therefore Egamma2_min= Egamma2(cos_th=-1) = Egamma1/(1+2.(Egamma1/E0_electron))
|
||||
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
if(!fUseMatrix)
|
||||
return RapidSampleSecondaries(aTrack, isScatProjToProj, fParticleChange);
|
||||
|
||||
// A recall of the compton scattering law:
|
||||
// Egamma2=Egamma1/(1+(Egamma1/E0_electron)(1.-cos_th))
|
||||
// Therefore Egamma2_max= Egamma2(cos_th=1) = Egamma1
|
||||
// and Egamma2_min= Egamma2(cos_th=-1) =
|
||||
// Egamma1/(1+2.(Egamma1/E0_electron))
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Sample secondary energy
|
||||
//-----------------------
|
||||
G4double gammaE1;
|
||||
gammaE1 = SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy,
|
||||
IsScatProjToProjCase);
|
||||
|
||||
|
||||
//gammaE2
|
||||
//-----------
|
||||
|
||||
G4double gammaE2 = adjointPrimKinEnergy;
|
||||
if (!IsScatProjToProjCase) gammaE2 = gammaE1 - adjointPrimKinEnergy;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Cos th
|
||||
//-------
|
||||
// G4cout<<"Compton scattering "<<gammaE1<<'\t'<<gammaE2<<G4endl;
|
||||
G4double cos_th = 1.+ electron_mass_c2*(1./gammaE1 -1./gammaE2);
|
||||
if (!IsScatProjToProjCase) {
|
||||
G4double p_elec=theAdjointPrimary->GetTotalMomentum();
|
||||
cos_th = (gammaE1 - gammaE2*cos_th)/p_elec;
|
||||
}
|
||||
G4double sin_th = 0.;
|
||||
if (std::abs(cos_th)>1){
|
||||
//G4cout<<"Problem in compton scattering with cos_th "<<cos_th<<G4endl;
|
||||
if (cos_th>0) {
|
||||
cos_th=1.;
|
||||
}
|
||||
else cos_th=-1.;
|
||||
sin_th=0.;
|
||||
}
|
||||
else sin_th = std::sqrt(1.-cos_th*cos_th);
|
||||
|
||||
|
||||
|
||||
|
||||
//gamma0 momentum
|
||||
//--------------------
|
||||
// Sample secondary energy
|
||||
G4double gammaE1;
|
||||
gammaE1 =
|
||||
SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, isScatProjToProj);
|
||||
|
||||
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector gammaMomentum1 = gammaE1*G4ThreeVector(std::cos(phi)*sin_th,std::sin(phi)*sin_th,cos_th);
|
||||
gammaMomentum1.rotateUz(dir_parallel);
|
||||
// G4cout<<gamma0Energy<<'\t'<<gamma0Momentum<<G4endl;
|
||||
|
||||
|
||||
//It is important to correct the weight of particles before adding the secondary
|
||||
//------------------------------------------------------------------------------
|
||||
CorrectPostStepWeight(fParticleChange,
|
||||
aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy,
|
||||
gammaE1,
|
||||
IsScatProjToProjCase);
|
||||
|
||||
if (!IsScatProjToProjCase){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,gammaMomentum1));
|
||||
//G4cout<<"gamma0Momentum "<<gamma0Momentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(gammaE1);
|
||||
fParticleChange->ProposeMomentumDirection(gammaMomentum1.unit());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointComptonModel::RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
// gammaE2
|
||||
G4double gammaE2 = adjointPrimKinEnergy;
|
||||
if(!isScatProjToProj)
|
||||
gammaE2 = gammaE1 - adjointPrimKinEnergy;
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double diffCSUsed=0.1*currentMaterial->GetElectronDensity()*twopi_mc2_rcl2;
|
||||
G4double gammaE1=0.;
|
||||
G4double gammaE2=0.;
|
||||
if (!IsScatProjToProjCase){
|
||||
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin= GetSecondAdjEnergyMinForProdToProjCase(adjointPrimKinEnergy);;
|
||||
if (Emin>=Emax) return;
|
||||
G4double f1=(Emin-adjointPrimKinEnergy)/Emin;
|
||||
G4double f2=(Emax-adjointPrimKinEnergy)/Emax/f1;
|
||||
gammaE1=adjointPrimKinEnergy/(1.-f1*std::pow(f2,G4UniformRand()));;
|
||||
gammaE2=gammaE1-adjointPrimKinEnergy;
|
||||
diffCSUsed= diffCSUsed*(1.+2.*std::log(1.+electron_mass_c2/adjointPrimKinEnergy))*adjointPrimKinEnergy/gammaE1/gammaE2;
|
||||
|
||||
|
||||
}
|
||||
else { G4double Emax = GetSecondAdjEnergyMaxForScatProjToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForScatProjToProjCase(adjointPrimKinEnergy,currentTcutForDirectSecond);
|
||||
if (Emin>=Emax) return;
|
||||
gammaE2 =adjointPrimKinEnergy;
|
||||
gammaE1=Emin*std::pow(Emax/Emin,G4UniformRand());
|
||||
diffCSUsed= diffCSUsed/gammaE1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Weight correction
|
||||
//-----------------------
|
||||
//First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
G4double w_corr=additional_weight_correction_factor_for_post_step_outside_model;
|
||||
if (correct_weight_for_post_step_in_model) {
|
||||
w_corr=G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
// Cos th
|
||||
G4double cos_th = 1. + electron_mass_c2 * (1. / gammaE1 - 1. / gammaE2);
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
cos_th =
|
||||
(gammaE1 - gammaE2 * cos_th) / theAdjointPrimary->GetTotalMomentum();
|
||||
}
|
||||
//Then another correction is needed due to the fact that a biaised differential CS has been used rather than the
|
||||
//one consistent with the direct model
|
||||
|
||||
|
||||
G4double diffCS = DiffCrossSectionPerAtomPrimToScatPrim(gammaE1, gammaE2,1,0.);
|
||||
if (diffCS >0) diffCS /=G4direct_CS; // here we have the normalised diffCS
|
||||
//An we remultiply by the lambda of the forward process
|
||||
diffCS*=theDirectEMProcess->GetLambda(gammaE1,currentCouple);
|
||||
//diffCS*=theDirectEMModel->CrossSectionPerVolume(currentMaterial,G4Gamma::Gamma(),gammaE1,0.,2.*gammaE1);
|
||||
//G4cout<<"diffCS/diffCSUsed "<<diffCS/diffCSUsed<<'\t'<<gammaE1<<'\t'<<gammaE2<<G4endl;
|
||||
|
||||
w_corr*=diffCS/diffCSUsed;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight()*w_corr;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
|
||||
|
||||
//Cos th
|
||||
//-------
|
||||
G4double sin_th = 0.;
|
||||
if(std::abs(cos_th) > 1.)
|
||||
{
|
||||
if(cos_th > 0.)
|
||||
{
|
||||
cos_th = 1.;
|
||||
}
|
||||
else
|
||||
cos_th = -1.;
|
||||
sin_th = 0.;
|
||||
}
|
||||
else
|
||||
sin_th = std::sqrt(1. - cos_th * cos_th);
|
||||
|
||||
G4double cos_th = 1.+ electron_mass_c2*(1./gammaE1 -1./gammaE2);
|
||||
if (!IsScatProjToProjCase) {
|
||||
G4double p_elec=theAdjointPrimary->GetTotalMomentum();
|
||||
cos_th = (gammaE1 - gammaE2*cos_th)/p_elec;
|
||||
}
|
||||
G4double sin_th = 0.;
|
||||
if (std::abs(cos_th)>1){
|
||||
//G4cout<<"Problem in compton scattering with cos_th "<<cos_th<<G4endl;
|
||||
if (cos_th>0) {
|
||||
cos_th=1.;
|
||||
}
|
||||
else cos_th=-1.;
|
||||
sin_th=0.;
|
||||
}
|
||||
else sin_th = std::sqrt(1.-cos_th*cos_th);
|
||||
// gamma0 momentum
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector gammaMomentum1 =
|
||||
gammaE1 *
|
||||
G4ThreeVector(std::cos(phi) * sin_th, std::sin(phi) * sin_th, cos_th);
|
||||
gammaMomentum1.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
|
||||
|
||||
//gamma0 momentum
|
||||
//--------------------
|
||||
// correct the weight of particles before adding the secondary
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy, gammaE1, isScatProjToProj);
|
||||
|
||||
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector gammaMomentum1 = gammaE1*G4ThreeVector(std::cos(phi)*sin_th,std::sin(phi)*sin_th,cos_th);
|
||||
gammaMomentum1.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, gammaMomentum1));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(gammaE1);
|
||||
fParticleChange->ProposeMomentumDirection(gammaMomentum1.unit());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,gammaMomentum1));
|
||||
//G4cout<<"gamma0Momentum "<<gamma0Momentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(gammaE1);
|
||||
fParticleChange->ProposeMomentumDirection(gammaMomentum1.unit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//The implementation here is correct for energy loss process, for the photoelectric and compton scattering the method should be redefine
|
||||
void G4AdjointComptonModel::RapidSampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4double diffCSUsed =
|
||||
0.1 * fCurrentMaterial->GetElectronDensity() * twopi_mc2_rcl2;
|
||||
G4double gammaE1 = 0.;
|
||||
G4double gammaE2 = 0.;
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProj(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForProdToProj(adjointPrimKinEnergy);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
G4double f1 = (Emin - adjointPrimKinEnergy) / Emin;
|
||||
G4double f2 = (Emax - adjointPrimKinEnergy) / Emax / f1;
|
||||
gammaE1 = adjointPrimKinEnergy / (1. - f1 * std::pow(f2, G4UniformRand()));
|
||||
gammaE2 = gammaE1 - adjointPrimKinEnergy;
|
||||
diffCSUsed =
|
||||
diffCSUsed *
|
||||
(1. + 2. * std::log(1. + electron_mass_c2 / adjointPrimKinEnergy)) *
|
||||
adjointPrimKinEnergy / gammaE1 / gammaE2;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Emax =
|
||||
GetSecondAdjEnergyMaxForScatProjToProj(adjointPrimKinEnergy);
|
||||
G4double Emin =
|
||||
GetSecondAdjEnergyMinForScatProjToProj(adjointPrimKinEnergy, fTcutSecond);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
gammaE2 = adjointPrimKinEnergy;
|
||||
gammaE1 = Emin * std::pow(Emax / Emin, G4UniformRand());
|
||||
diffCSUsed = diffCSUsed / gammaE1;
|
||||
}
|
||||
|
||||
// Weight correction
|
||||
// First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
G4double w_corr = fOutsideWeightFactor;
|
||||
if(fInModelWeightCorr)
|
||||
{
|
||||
w_corr =
|
||||
G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
}
|
||||
// Then another correction is needed because a biased differential CS has
|
||||
// been used rather than the one consistent with the direct model
|
||||
|
||||
G4double diffCS =
|
||||
DiffCrossSectionPerAtomPrimToScatPrim(gammaE1, gammaE2, 1, 0.);
|
||||
if(diffCS > 0.)
|
||||
diffCS /= fDirectCS; // here we have the normalised diffCS
|
||||
// And we remultiply by the lambda of the forward process
|
||||
diffCS *= fDirectProcess->GetLambda(gammaE1, fCurrentCouple);
|
||||
|
||||
w_corr *= diffCS / diffCSUsed;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight() * w_corr;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
G4double cos_th = 1. + electron_mass_c2 * (1. / gammaE1 - 1. / gammaE2);
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
G4double p_elec = theAdjointPrimary->GetTotalMomentum();
|
||||
cos_th = (gammaE1 - gammaE2 * cos_th) / p_elec;
|
||||
}
|
||||
G4double sin_th = 0.;
|
||||
if(std::abs(cos_th) > 1.)
|
||||
{
|
||||
if(cos_th > 0.)
|
||||
{
|
||||
cos_th = 1.;
|
||||
}
|
||||
else
|
||||
cos_th = -1.;
|
||||
}
|
||||
else
|
||||
sin_th = std::sqrt(1. - cos_th * cos_th);
|
||||
|
||||
// gamma0 momentum
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector gammaMomentum1 =
|
||||
gammaE1 *
|
||||
G4ThreeVector(std::cos(phi) * sin_th, std::sin(phi) * sin_th, cos_th);
|
||||
gammaMomentum1.rotateUz(dir_parallel);
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, gammaMomentum1));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(gammaE1);
|
||||
fParticleChange->ProposeMomentumDirection(gammaMomentum1.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The implementation here is correct for energy loss process, for the
|
||||
// photoelectric and compton scattering the method should be redefined
|
||||
G4double G4AdjointComptonModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double gamEnergy0,
|
||||
G4double kinEnergyElec,
|
||||
G4double Z,
|
||||
G4double A)
|
||||
{
|
||||
G4double gamEnergy1 = gamEnergy0 - kinEnergyElec;
|
||||
G4double dSigmadEprod=0.;
|
||||
if (gamEnergy1>0.) dSigmadEprod=DiffCrossSectionPerAtomPrimToScatPrim(gamEnergy0,gamEnergy1,Z,A);
|
||||
return dSigmadEprod;
|
||||
G4double gamEnergy0, G4double kinEnergyElec, G4double Z, G4double A)
|
||||
{
|
||||
G4double gamEnergy1 = gamEnergy0 - kinEnergyElec;
|
||||
G4double dSigmadEprod = 0.;
|
||||
if(gamEnergy1 > 0.)
|
||||
dSigmadEprod =
|
||||
DiffCrossSectionPerAtomPrimToScatPrim(gamEnergy0, gamEnergy1, Z, A);
|
||||
return dSigmadEprod;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointComptonModel::DiffCrossSectionPerAtomPrimToScatPrim(
|
||||
G4double gamEnergy0,
|
||||
G4double gamEnergy1,
|
||||
G4double Z,
|
||||
G4double )
|
||||
{ //Based on Klein Nishina formula
|
||||
// In the forward case (see G4KleinNishinaCompton) the cross section is parametrised
|
||||
// but the secondaries are sampled from the
|
||||
// Klein Nishida differential cross section
|
||||
// The used diffrential cross section here is therefore the cross section multiplied by the normalised
|
||||
//differential Klein Nishida cross section
|
||||
|
||||
|
||||
//Klein Nishida Cross Section
|
||||
//-----------------------------
|
||||
G4double epsilon = gamEnergy0 / electron_mass_c2 ;
|
||||
G4double one_plus_two_epsi =1.+2.*epsilon;
|
||||
G4double gamEnergy1_max = gamEnergy0;
|
||||
G4double gamEnergy1_min = gamEnergy0/one_plus_two_epsi;
|
||||
if (gamEnergy1 >gamEnergy1_max || gamEnergy1<gamEnergy1_min) {
|
||||
/*G4cout<<"the differential CS is null"<<G4endl;
|
||||
G4cout<<gamEnergy0<<G4endl;
|
||||
G4cout<<gamEnergy1<<G4endl;
|
||||
G4cout<<gamEnergy1_min<<G4endl;*/
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
G4double epsi2 = epsilon *epsilon ;
|
||||
G4double one_plus_two_epsi_2=one_plus_two_epsi*one_plus_two_epsi;
|
||||
|
||||
|
||||
G4double CS=std::log(one_plus_two_epsi)*(1.- 2.*(1.+epsilon)/epsi2);
|
||||
CS+=4./epsilon +0.5*(1.-1./one_plus_two_epsi_2);
|
||||
CS/=epsilon;
|
||||
//Note that the pi*re2*Z factor is neglected because it is suppresed when computing dCS_dE1/CS;
|
||||
// in the differential cross section
|
||||
|
||||
|
||||
//Klein Nishida Differential Cross Section
|
||||
//-----------------------------------------
|
||||
G4double epsilon1 = gamEnergy1 / electron_mass_c2 ;
|
||||
G4double v= epsilon1/epsilon;
|
||||
G4double term1 =1.+ 1./epsilon -1/epsilon1;
|
||||
G4double dCS_dE1= 1./v +v + term1*term1 -1.;
|
||||
dCS_dE1 *=1./epsilon/gamEnergy0;
|
||||
|
||||
|
||||
//Normalised to the CS used in G4
|
||||
//-------------------------------
|
||||
|
||||
G4direct_CS = theDirectEMModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),
|
||||
gamEnergy0,
|
||||
Z, 0., 0.,0.);
|
||||
|
||||
dCS_dE1 *= G4direct_CS/CS;
|
||||
/* G4cout<<"the differential CS is not null"<<G4endl;
|
||||
G4cout<<gamEnergy0<<G4endl;
|
||||
G4cout<<gamEnergy1<<G4endl;*/
|
||||
|
||||
return dCS_dE1;
|
||||
G4double gamEnergy0, G4double gamEnergy1, G4double Z, G4double)
|
||||
{
|
||||
// Based on Klein Nishina formula
|
||||
// In the forward case (see G4KleinNishinaCompton) the cross section is
|
||||
// parametrised but the secondaries are sampled from the Klein Nishina
|
||||
// differential cross section. The differential cross section used here
|
||||
// is therefore the cross section multiplied by the normalised
|
||||
// differential Klein Nishina cross section
|
||||
|
||||
// Klein Nishina Cross Section
|
||||
G4double epsilon = gamEnergy0 / electron_mass_c2;
|
||||
G4double one_plus_two_epsi = 1. + 2. * epsilon;
|
||||
if(gamEnergy1 > gamEnergy0 || gamEnergy1 < gamEnergy0 / one_plus_two_epsi)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
|
||||
G4double CS = std::log(one_plus_two_epsi) *
|
||||
(1. - 2. * (1. + epsilon) / (epsilon * epsilon));
|
||||
CS +=
|
||||
4. / epsilon + 0.5 * (1. - 1. / (one_plus_two_epsi * one_plus_two_epsi));
|
||||
CS /= epsilon;
|
||||
// Note that the pi*re2*Z factor is neglected because it is suppressed when
|
||||
// computing dCS_dE1/CS in the differential cross section
|
||||
|
||||
// Klein Nishina Differential Cross Section
|
||||
G4double epsilon1 = gamEnergy1 / electron_mass_c2;
|
||||
G4double v = epsilon1 / epsilon;
|
||||
G4double term1 = 1. + 1. / epsilon - 1. / epsilon1;
|
||||
G4double dCS_dE1 = 1. / v + v + term1 * term1 - 1.;
|
||||
dCS_dE1 *= 1. / epsilon / gamEnergy0;
|
||||
|
||||
// Normalised to the CS used in G4
|
||||
fDirectCS = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
G4Gamma::Gamma(), gamEnergy0, Z, 0., 0., 0.);
|
||||
|
||||
dCS_dE1 *= fDirectCS / CS;
|
||||
|
||||
return dCS_dE1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointComptonModel::GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy)
|
||||
{ G4double inv_e_max = 1./PrimAdjEnergy - 2./electron_mass_c2;
|
||||
G4double e_max = HighEnergyLimit;
|
||||
if (inv_e_max > 0. ) e_max=std::min(1./inv_e_max,HighEnergyLimit);
|
||||
return e_max;
|
||||
G4double G4AdjointComptonModel::GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
G4double inv_e_max = 1. / primAdjEnergy - 2. / electron_mass_c2;
|
||||
G4double e_max = GetHighEnergyLimit();
|
||||
if(inv_e_max > 0.)
|
||||
e_max = std::min(1. / inv_e_max, e_max);
|
||||
return e_max;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointComptonModel::GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy)
|
||||
{ G4double half_e=PrimAdjEnergy/2.;
|
||||
G4double term=std::sqrt(half_e*(electron_mass_c2+half_e));
|
||||
G4double emin=half_e+term;
|
||||
return emin;
|
||||
G4double G4AdjointComptonModel::GetSecondAdjEnergyMinForProdToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
G4double half_e = primAdjEnergy / 2.;
|
||||
return half_e + std::sqrt(half_e * (electron_mass_c2 + half_e));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointComptonModel::AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{
|
||||
if (UseMatrix) return G4VEmAdjointModel::AdjointCrossSection(aCouple,primEnergy,IsScatProjToProjCase);
|
||||
G4double G4AdjointComptonModel::AdjointCrossSection(
|
||||
const G4MaterialCutsCouple* aCouple, G4double primEnergy,
|
||||
G4bool isScatProjToProj)
|
||||
{
|
||||
if(fUseMatrix)
|
||||
return G4VEmAdjointModel::AdjointCrossSection(aCouple, primEnergy,
|
||||
isScatProjToProj);
|
||||
DefineCurrentMaterial(aCouple);
|
||||
|
||||
|
||||
float Cross=0.;
|
||||
float Emax_proj =0.;
|
||||
float Emin_proj =0.;
|
||||
if (!IsScatProjToProjCase ){
|
||||
Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(primEnergy);
|
||||
Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(primEnergy);
|
||||
if (Emax_proj>Emin_proj ){
|
||||
Cross= 0.1*std::log((Emax_proj-float (primEnergy))*Emin_proj/Emax_proj/(Emin_proj-primEnergy))
|
||||
*(1.+2.*std::log(float(1.+electron_mass_c2/primEnergy)));
|
||||
}
|
||||
|
||||
G4float Cross = 0.;
|
||||
G4float Emax_proj = 0.;
|
||||
G4float Emin_proj = 0.;
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
Emax_proj = GetSecondAdjEnergyMaxForProdToProj(primEnergy);
|
||||
Emin_proj = GetSecondAdjEnergyMinForProdToProj(primEnergy);
|
||||
if(Emax_proj > Emin_proj)
|
||||
{
|
||||
Cross = 0.1 *
|
||||
std::log((Emax_proj - G4float(primEnergy)) * Emin_proj /
|
||||
Emax_proj / (Emin_proj - primEnergy)) *
|
||||
(1. + 2. * std::log(G4float(1. + electron_mass_c2 / primEnergy)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Emax_proj = GetSecondAdjEnergyMaxForScatProjToProjCase(primEnergy);
|
||||
Emin_proj = GetSecondAdjEnergyMinForScatProjToProjCase(primEnergy,0.);
|
||||
if (Emax_proj>Emin_proj) {
|
||||
Cross = 0.1*std::log(Emax_proj/Emin_proj);
|
||||
//+0.5*primEnergy*primEnergy(1./(Emin_proj*Emin_proj) - 1./(Emax_proj*Emax_proj)); neglected at the moment
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
Emax_proj = GetSecondAdjEnergyMaxForScatProjToProj(primEnergy);
|
||||
Emin_proj = GetSecondAdjEnergyMinForScatProjToProj(primEnergy, 0.);
|
||||
if(Emax_proj > Emin_proj)
|
||||
{
|
||||
Cross = 0.1 * std::log(Emax_proj / Emin_proj);
|
||||
}
|
||||
}
|
||||
|
||||
Cross*=currentMaterial->GetElectronDensity()*twopi_mc2_rcl2;
|
||||
lastCS=Cross;
|
||||
return double(Cross);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointComptonModel::GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{ return AdjointCrossSection(aCouple, primEnergy,IsScatProjToProjCase);
|
||||
//return G4VEmAdjointModel::GetAdjointCrossSection(aCouple, primEnergy,IsScatProjToProjCase);
|
||||
|
||||
Cross *= fCurrentMaterial->GetElectronDensity() * twopi_mc2_rcl2;
|
||||
fLastCS = Cross;
|
||||
return double(Cross);
|
||||
}
|
||||
|
||||
+237
-230
@@ -23,264 +23,271 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointForcedInteractionForGamma.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
|
||||
G4AdjointForcedInteractionForGamma::
|
||||
G4AdjointForcedInteractionForGamma(G4String process_name):
|
||||
G4VContinuousDiscreteProcess(process_name),theAdjointComptonModel(0),theAdjointBremModel(0)
|
||||
{ theAdjointCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
fParticleChange=new G4ParticleChange();
|
||||
lastAdjCS=0.;
|
||||
trackid = nstep = 0;
|
||||
is_free_flight_gamma = false;
|
||||
copy_gamma_for_forced_interaction = false;
|
||||
last_free_flight_trackid=1000;
|
||||
|
||||
theAdjointComptonModel =0;
|
||||
theAdjointBremModel=0;
|
||||
|
||||
acc_track_length=0.;
|
||||
acc_nb_adj_interaction_length=0.;
|
||||
acc_nb_fwd_interaction_length=0.;
|
||||
total_acc_nb_adj_interaction_length=0.;
|
||||
total_acc_nb_fwd_interaction_length=0.;
|
||||
continue_gamma_as_new_free_flight =false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointForcedInteractionForGamma::
|
||||
~G4AdjointForcedInteractionForGamma()
|
||||
{ if (fParticleChange) delete fParticleChange;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointForcedInteractionForGamma::PreparePhysicsTable(const G4ParticleDefinition&)
|
||||
{;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointForcedInteractionForGamma::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
G4AdjointForcedInteractionForGamma::G4AdjointForcedInteractionForGamma(
|
||||
G4String process_name)
|
||||
: G4VContinuousDiscreteProcess(process_name)
|
||||
, fAdjointComptonModel(nullptr)
|
||||
, fAdjointBremModel(nullptr)
|
||||
{
|
||||
theAdjointCSManager->BuildCrossSectionMatrices(); //do not worry it will be done just once
|
||||
theAdjointCSManager->BuildTotalSigmaTables();
|
||||
fCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
fParticleChange = new G4ParticleChange();
|
||||
}
|
||||
//Note on weight correction for forced interaction
|
||||
//For the forced interaction applied here we do use a truncated exponential law for the probability of survival
|
||||
//over a fixed total length. This is done by using a linear transformation of the non biased probability survival
|
||||
//In mathematic this writes
|
||||
//P'(x)=C1P(x)+C2
|
||||
//With P(x)=exp(-sum(sigma_ixi)) x and L can cross different volumes with different cross section sigma.
|
||||
//For forced interaction we get the following limit conditions
|
||||
//P'(L)=0 P'(0)=1 (L can be used over different volumes)
|
||||
//From simple solving of linear equation we get
|
||||
//C1=1/(1-P(L)) et C2=-P(L)/(1-P(L))
|
||||
//P'(x)=(P(x)-P(L))/(1-P(L))
|
||||
//For the probability over a step x1 to x2
|
||||
//P'(x1->x2)=P'(x2)/P'(x1)
|
||||
//The effective cross section is defined -d(P'(x))/dx/P'(x)
|
||||
//We get therefore
|
||||
//sigma_eff=C1sigmaP(x)/(C1P(x)+C2)=sigmaP(x)/(P(x)+C2/C1)=sigmaP(x)/(P(x)-P(L))=sigma/(1-P(L)/P(x))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4VParticleChange* G4AdjointForcedInteractionForGamma::PostStepDoIt(const G4Track& track, const G4Step& )
|
||||
{ fParticleChange->Initialize(track);
|
||||
//For the free flight gamma no interaction occur but a gamma with same property is
|
||||
//produces for further forced interaction
|
||||
//It is done at the very beginning of the track such that the weight can be the same
|
||||
if (copy_gamma_for_forced_interaction) {
|
||||
G4ThreeVector theGammaMomentum = track.GetMomentum();
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(G4AdjointGamma::AdjointGamma(),theGammaMomentum));
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
G4AdjointForcedInteractionForGamma::~G4AdjointForcedInteractionForGamma()
|
||||
{
|
||||
if(fParticleChange)
|
||||
delete fParticleChange;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointForcedInteractionForGamma::ProcessDescription(
|
||||
std::ostream& out) const
|
||||
{
|
||||
out << "Forced interaction for gamma.\n";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointForcedInteractionForGamma::BuildPhysicsTable(
|
||||
const G4ParticleDefinition&)
|
||||
{
|
||||
fCSManager->BuildCrossSectionMatrices(); // it will be done just once
|
||||
fCSManager->BuildTotalSigmaTables();
|
||||
}
|
||||
|
||||
// Note on weight correction for forced interaction.
|
||||
// For the forced interaction applied here we use a truncated exponential law
|
||||
// for the probability of survival over a fixed total length. This is done by
|
||||
// using a linear transformation of the non-biased probability survival. In
|
||||
// math this is written P'(x)=C1P(x)+C2 , with P(x)=exp(-sum(sigma_ixi)) . x and
|
||||
// L can cross different volumes with different cross section sigma. For forced
|
||||
// interaction, we get the limit conditions:
|
||||
// P'(L)=0 and P'(0)=1 (L can be used over different volumes)
|
||||
// From simple solving of linear equations we
|
||||
// get C1=1/(1-P(L)) and C2=-P(L)/(1-P(L))
|
||||
// P'(x)=(P(x)-P(L))/(1-P(L))
|
||||
// For the probability over a step x1 to x2, P'(x1->x2)=P'(x2)/P'(x1).
|
||||
// The effective cross
|
||||
// section is defined -d(P'(x))/dx/P'(x).
|
||||
// We get therefore
|
||||
// sigma_eff = C1sigmaP(x)/(C1P(x)+C2) = sigmaP(x)/(P(x)+C2/C1)
|
||||
// = sigmaP(x)/(P(x)-P(L)) = sigma/(1-P(L)/P(x))
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
G4VParticleChange* G4AdjointForcedInteractionForGamma::PostStepDoIt(
|
||||
const G4Track& track, const G4Step&)
|
||||
{
|
||||
fParticleChange->Initialize(track);
|
||||
// For the free flight gamma no interaction occurs but a gamma with same
|
||||
// properties is produced for further forced interaction. It is done at the
|
||||
// very beginning of the track so that the weight can be the same
|
||||
if(fCopyGammaForForced)
|
||||
{
|
||||
G4ThreeVector theGammaMomentum = track.GetMomentum();
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(G4AdjointGamma::AdjointGamma(), theGammaMomentum));
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
}
|
||||
else { //Occurrence of forced interaction
|
||||
else
|
||||
{ // Occurrence of forced interaction
|
||||
// Selection of the model to be called
|
||||
G4VEmAdjointModel* theSelectedModel = nullptr;
|
||||
G4bool is_scat_proj_to_proj_case = false;
|
||||
if(!fAdjointComptonModel && !fAdjointBremModel)
|
||||
return fParticleChange;
|
||||
if(!fAdjointComptonModel)
|
||||
{
|
||||
theSelectedModel = fAdjointBremModel;
|
||||
is_scat_proj_to_proj_case = false;
|
||||
// This is needed because the results of it will be used in the post step
|
||||
// do it weight correction inside the model
|
||||
fAdjointBremModel->AdjointCrossSection(track.GetMaterialCutsCouple(),
|
||||
track.GetKineticEnergy(), false);
|
||||
}
|
||||
else if(!fAdjointBremModel)
|
||||
{
|
||||
theSelectedModel = fAdjointComptonModel;
|
||||
is_scat_proj_to_proj_case = true;
|
||||
}
|
||||
else
|
||||
{ // Choose the model according to cross sections
|
||||
G4double bremAdjCS = fAdjointBremModel->AdjointCrossSection(
|
||||
track.GetMaterialCutsCouple(), track.GetKineticEnergy(), false);
|
||||
if(G4UniformRand() * fLastAdjCS < bremAdjCS)
|
||||
{
|
||||
theSelectedModel = fAdjointBremModel;
|
||||
is_scat_proj_to_proj_case = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
theSelectedModel = fAdjointComptonModel;
|
||||
is_scat_proj_to_proj_case = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Selection of the model to be called
|
||||
G4VEmAdjointModel* theSelectedModel =0;
|
||||
G4bool is_scat_proj_to_proj_case=false;
|
||||
if (!theAdjointComptonModel && !theAdjointBremModel) return fParticleChange;
|
||||
if (!theAdjointComptonModel) {
|
||||
theSelectedModel = theAdjointBremModel;
|
||||
is_scat_proj_to_proj_case=false;
|
||||
//This is needed because the results of it will be used in the post step do it weight correction inside the model
|
||||
theAdjointBremModel->AdjointCrossSection(
|
||||
track.GetMaterialCutsCouple(),track.GetKineticEnergy(), false);
|
||||
// Compute the weight correction factor
|
||||
G4double invEffectiveAdjointCS =
|
||||
(1. - std::exp(fNbAdjIntLength - fTotNbAdjIntLength)) / fLastAdjCS;
|
||||
|
||||
}
|
||||
else if (!theAdjointBremModel) {
|
||||
theSelectedModel = theAdjointComptonModel;
|
||||
is_scat_proj_to_proj_case=true;
|
||||
}
|
||||
else { //Choose the model according to cross sections
|
||||
// Call the selected model without correction of the weight in the model
|
||||
theSelectedModel->SetCorrectWeightForPostStepInModel(false);
|
||||
theSelectedModel
|
||||
->SetAdditionalWeightCorrectionFactorForPostStepOutsideModel(
|
||||
fLastAdjCS * invEffectiveAdjointCS);
|
||||
theSelectedModel->SampleSecondaries(track, is_scat_proj_to_proj_case,
|
||||
fParticleChange);
|
||||
theSelectedModel->SetCorrectWeightForPostStepInModel(true);
|
||||
|
||||
G4double bremAdjCS = theAdjointBremModel->AdjointCrossSection(
|
||||
track.GetMaterialCutsCouple(),track.GetKineticEnergy(), false);
|
||||
if (G4UniformRand()*lastAdjCS<bremAdjCS) {
|
||||
theSelectedModel = theAdjointBremModel;
|
||||
is_scat_proj_to_proj_case=false;
|
||||
}
|
||||
else {
|
||||
theSelectedModel = theAdjointComptonModel;
|
||||
is_scat_proj_to_proj_case=true;
|
||||
}
|
||||
}
|
||||
|
||||
//Compute the weight correction factor
|
||||
G4double one_over_effectiveAdjointCS= (1.-std::exp(acc_nb_adj_interaction_length-total_acc_nb_adj_interaction_length))/lastAdjCS;
|
||||
G4double weight_correction_factor = lastAdjCS*one_over_effectiveAdjointCS;
|
||||
//G4cout<<"Weight correction factor start "<<weight_correction_factor<<std::endl;
|
||||
//Call the selected model without correction of the weight in the model
|
||||
theSelectedModel->SetCorrectWeightForPostStepInModel(false);
|
||||
theSelectedModel->SetAdditionalWeightCorrectionFactorForPostStepOutsideModel(weight_correction_factor);
|
||||
theSelectedModel->SampleSecondaries(track,is_scat_proj_to_proj_case,fParticleChange);
|
||||
theSelectedModel->SetCorrectWeightForPostStepInModel(true);
|
||||
|
||||
continue_gamma_as_new_free_flight =true;
|
||||
fContinueGammaAsNewFreeFlight = true;
|
||||
}
|
||||
return fParticleChange;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4VParticleChange* G4AdjointForcedInteractionForGamma::AlongStepDoIt(const G4Track& track, const G4Step& )
|
||||
{ fParticleChange->Initialize(track);
|
||||
//Compute nb of interactions length over step length
|
||||
G4VParticleChange* G4AdjointForcedInteractionForGamma::AlongStepDoIt(
|
||||
const G4Track& track, const G4Step&)
|
||||
{
|
||||
fParticleChange->Initialize(track);
|
||||
// Compute nb of interactions length over step length
|
||||
G4ThreeVector position = track.GetPosition();
|
||||
G4double stepLength = track.GetStep()->GetStepLength();
|
||||
G4double ekin = track.GetKineticEnergy();
|
||||
G4double nb_fwd_interaction_length_over_step=0.;
|
||||
G4double nb_adj_interaction_length_over_step=0.;
|
||||
lastAdjCS = G4AdjointCSManager::GetAdjointCSManager()->GetTotalAdjointCS(track.GetDefinition(), ekin, track.GetMaterialCutsCouple());
|
||||
lastFwdCS = G4AdjointCSManager::GetAdjointCSManager()->GetTotalForwardCS(G4AdjointGamma::AdjointGamma(),
|
||||
ekin,track.GetMaterialCutsCouple());
|
||||
nb_fwd_interaction_length_over_step = stepLength*lastFwdCS;
|
||||
nb_adj_interaction_length_over_step = stepLength*lastAdjCS;
|
||||
G4double fwd_survival_probability=std::exp(-nb_fwd_interaction_length_over_step);
|
||||
G4double mc_induced_survival_probability=1.;
|
||||
G4double stepLength = track.GetStep()->GetStepLength();
|
||||
G4double ekin = track.GetKineticEnergy();
|
||||
fLastAdjCS = fCSManager->GetTotalAdjointCS(track.GetDefinition(), ekin,
|
||||
track.GetMaterialCutsCouple());
|
||||
G4double nb_fwd_interaction_length_over_step =
|
||||
stepLength * fCSManager->GetTotalForwardCS(G4AdjointGamma::AdjointGamma(),
|
||||
ekin,
|
||||
track.GetMaterialCutsCouple());
|
||||
|
||||
if (is_free_flight_gamma) { //for free_flight survival probability stays 1
|
||||
//Accumulate the number of interaction lengths during free flight of gamma
|
||||
total_acc_nb_fwd_interaction_length+=nb_fwd_interaction_length_over_step;
|
||||
total_acc_nb_adj_interaction_length+=nb_adj_interaction_length_over_step;
|
||||
acc_track_length+=stepLength;
|
||||
G4double nb_adj_interaction_length_over_step = stepLength * fLastAdjCS;
|
||||
G4double fwd_survival_probability =
|
||||
std::exp(-nb_fwd_interaction_length_over_step);
|
||||
G4double mc_induced_survival_probability = 1.;
|
||||
|
||||
if(fFreeFlightGamma)
|
||||
{ // for free_flight survival probability stays 1
|
||||
// Accumulate the number of interaction lengths during free flight of gamma
|
||||
fTotNbAdjIntLength += nb_adj_interaction_length_over_step;
|
||||
fAccTrackLength += stepLength;
|
||||
}
|
||||
else {
|
||||
G4double previous_acc_nb_adj_interaction_length =acc_nb_adj_interaction_length;
|
||||
acc_nb_fwd_interaction_length+=nb_fwd_interaction_length_over_step;
|
||||
acc_nb_adj_interaction_length+=nb_adj_interaction_length_over_step;
|
||||
theNumberOfInteractionLengthLeft-=nb_adj_interaction_length_over_step;
|
||||
else
|
||||
{
|
||||
G4double previous_acc_nb_adj_interaction_length = fNbAdjIntLength;
|
||||
fNbAdjIntLength += nb_adj_interaction_length_over_step;
|
||||
theNumberOfInteractionLengthLeft -= nb_adj_interaction_length_over_step;
|
||||
|
||||
//Following condition to remove very rare FPE issue
|
||||
//if (total_acc_nb_adj_interaction_length <= 1.e-50 && theNumberOfInteractionLengthLeft<=1.e-50) { //condition added to avoid FPE issue
|
||||
// VI 06.11.2017 - new condition
|
||||
if (std::abs(total_acc_nb_adj_interaction_length - previous_acc_nb_adj_interaction_length) <= 1.e-15) {
|
||||
mc_induced_survival_probability = 1.e50;
|
||||
/*
|
||||
G4cout << "FPE protection: " << total_acc_nb_adj_interaction_length << " "
|
||||
<< previous_acc_nb_adj_interaction_length << " "
|
||||
<< acc_nb_fwd_interaction_length << " "
|
||||
<< acc_nb_adj_interaction_length << " "
|
||||
<< theNumberOfInteractionLengthLeft
|
||||
<< G4endl;
|
||||
*/
|
||||
}
|
||||
else {
|
||||
mc_induced_survival_probability= std::exp(-acc_nb_adj_interaction_length)-std::exp(-total_acc_nb_adj_interaction_length);
|
||||
mc_induced_survival_probability=mc_induced_survival_probability/(std::exp(-previous_acc_nb_adj_interaction_length)-std::exp(-total_acc_nb_adj_interaction_length));
|
||||
}
|
||||
// protection against rare race condition
|
||||
if(std::abs(fTotNbAdjIntLength - previous_acc_nb_adj_interaction_length) <=
|
||||
1.e-15)
|
||||
{
|
||||
mc_induced_survival_probability = 1.e50;
|
||||
}
|
||||
else
|
||||
{
|
||||
mc_induced_survival_probability =
|
||||
std::exp(-fNbAdjIntLength) - std::exp(-fTotNbAdjIntLength);
|
||||
mc_induced_survival_probability /=
|
||||
(std::exp(-previous_acc_nb_adj_interaction_length) -
|
||||
std::exp(-fTotNbAdjIntLength));
|
||||
}
|
||||
}
|
||||
G4double weight_correction = fwd_survival_probability/mc_induced_survival_probability;
|
||||
G4double weight_correction =
|
||||
fwd_survival_probability / mc_induced_survival_probability;
|
||||
|
||||
//weight_correction = 1.;
|
||||
//Caution!!!
|
||||
// It is important to select the weight of the post_step_point
|
||||
// as the current weight and not the weight of the track, as t
|
||||
// the weight of the track is changed after having applied all
|
||||
// the along_step_do_it.
|
||||
G4double new_weight=weight_correction*track.GetStep()->GetPostStepPoint()->GetWeight();
|
||||
/*
|
||||
G4cout<<"New weight "<<new_weight<<std::endl;
|
||||
G4cout<<"Weight correction "<<weight_correction<<std::endl;
|
||||
*/
|
||||
// Caution!!!
|
||||
// It is important to select the weight of the post_step_point as the
|
||||
// current weight and not the weight of the track, as the weight of the track
|
||||
// is changed after having applied all the along_step_do_it.
|
||||
G4double new_weight =
|
||||
weight_correction * track.GetStep()->GetPostStepPoint()->GetWeight();
|
||||
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
return fParticleChange;
|
||||
return fParticleChange;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointForcedInteractionForGamma::PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
G4double ,
|
||||
G4ForceCondition* condition)
|
||||
{ G4int step_id = track.GetCurrentStepNumber();
|
||||
*condition = NotForced;
|
||||
copy_gamma_for_forced_interaction = false;
|
||||
G4int track_id=track.GetTrackID();
|
||||
is_free_flight_gamma = (track_id != last_free_flight_trackid+1 || continue_gamma_as_new_free_flight);
|
||||
if (is_free_flight_gamma) {
|
||||
if (step_id == 1 || continue_gamma_as_new_free_flight) {
|
||||
*condition=Forced;
|
||||
//A gamma with same conditions will be generate at next post_step do it for the forced interaction
|
||||
copy_gamma_for_forced_interaction = true;
|
||||
last_free_flight_trackid = track_id;
|
||||
acc_track_length=0.;
|
||||
total_acc_nb_adj_interaction_length=0.;
|
||||
total_acc_nb_fwd_interaction_length=0.;
|
||||
continue_gamma_as_new_free_flight=false;
|
||||
return 1.e-90;
|
||||
G4double
|
||||
G4AdjointForcedInteractionForGamma::PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double, G4ForceCondition* condition)
|
||||
{
|
||||
static G4int lastFreeFlightTrackId = 1000;
|
||||
G4int step_id = track.GetCurrentStepNumber();
|
||||
*condition = NotForced;
|
||||
fCopyGammaForForced = false;
|
||||
G4int track_id = track.GetTrackID();
|
||||
fFreeFlightGamma =
|
||||
(track_id != lastFreeFlightTrackId + 1 || fContinueGammaAsNewFreeFlight);
|
||||
if(fFreeFlightGamma)
|
||||
{
|
||||
if(step_id == 1 || fContinueGammaAsNewFreeFlight)
|
||||
{
|
||||
*condition = Forced;
|
||||
// A gamma with same conditions will be generate at next post_step do it
|
||||
// for the forced interaction
|
||||
fCopyGammaForForced = true;
|
||||
lastFreeFlightTrackId = track_id;
|
||||
fAccTrackLength = 0.;
|
||||
fTotNbAdjIntLength = 0.;
|
||||
fContinueGammaAsNewFreeFlight = false;
|
||||
return 1.e-90;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DBL_MAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Computation of accumulated length for
|
||||
return DBL_MAX;
|
||||
else
|
||||
{ // compute the interaction length for forced interaction
|
||||
if(step_id == 1)
|
||||
{
|
||||
G4double min_val = std::exp(-fTotNbAdjIntLength);
|
||||
theNumberOfInteractionLengthLeft =
|
||||
-std::log(min_val + G4UniformRand() * (1. - min_val));
|
||||
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
|
||||
fNbAdjIntLength = 0.;
|
||||
}
|
||||
G4VPhysicalVolume* thePostPhysVolume =
|
||||
track.GetStep()->GetPreStepPoint()->GetPhysicalVolume();
|
||||
G4double ekin = track.GetKineticEnergy();
|
||||
G4double postCS = 0.;
|
||||
if(thePostPhysVolume)
|
||||
{
|
||||
postCS = fCSManager->GetTotalAdjointCS(
|
||||
G4AdjointGamma::AdjointGamma(), ekin,
|
||||
thePostPhysVolume->GetLogicalVolume()->GetMaterialCutsCouple());
|
||||
}
|
||||
if(postCS > 0.)
|
||||
return theNumberOfInteractionLengthLeft / postCS;
|
||||
else
|
||||
return DBL_MAX;
|
||||
}
|
||||
}
|
||||
else { //compute the interaction length for forced interaction
|
||||
if (step_id ==1) {
|
||||
G4double min_val= std::exp(-total_acc_nb_adj_interaction_length);
|
||||
theNumberOfInteractionLengthLeft = -std::log( min_val+G4UniformRand()*(1.-min_val));
|
||||
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
|
||||
acc_nb_adj_interaction_length=0.;
|
||||
acc_nb_fwd_interaction_length=0.;
|
||||
}
|
||||
G4VPhysicalVolume* thePostPhysVolume = track.GetStep()->GetPreStepPoint()->GetPhysicalVolume();
|
||||
G4double ekin =track.GetKineticEnergy();
|
||||
G4double postCS=0.;
|
||||
if (thePostPhysVolume){
|
||||
postCS = G4AdjointCSManager::GetAdjointCSManager()->GetTotalAdjointCS(G4AdjointGamma::AdjointGamma(),
|
||||
ekin,thePostPhysVolume->GetLogicalVolume()->GetMaterialCutsCouple());
|
||||
}
|
||||
if (postCS>0.) return theNumberOfInteractionLengthLeft/postCS;
|
||||
else return DBL_MAX;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointForcedInteractionForGamma::GetContinuousStepLimit(const G4Track& ,
|
||||
G4double ,
|
||||
G4double ,
|
||||
G4double& )
|
||||
{return DBL_MAX;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Not used in this process but should be implemented as virtual method
|
||||
G4double G4AdjointForcedInteractionForGamma::GetMeanFreePath(const G4Track& ,
|
||||
G4double ,
|
||||
G4ForceCondition*)
|
||||
{ return 0.;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointForcedInteractionForGamma::GetContinuousStepLimit(
|
||||
const G4Track&, G4double, G4double, G4double&)
|
||||
{
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Not used in this process but should be implemented as virtual method
|
||||
G4double G4AdjointForcedInteractionForGamma::GetMeanFreePath(const G4Track&,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
|
||||
@@ -23,211 +23,185 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
|
||||
G4ThreadLocal G4AdjointInterpolator* G4AdjointInterpolator::theInstance = 0;
|
||||
G4ThreadLocal G4AdjointInterpolator* G4AdjointInterpolator::fInstance = nullptr;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointInterpolator* G4AdjointInterpolator::GetAdjointInterpolator()
|
||||
{
|
||||
return GetInstance();
|
||||
return GetInstance();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointInterpolator* G4AdjointInterpolator::GetInstance()
|
||||
{
|
||||
if(!theInstance)
|
||||
if(!fInstance)
|
||||
{
|
||||
theInstance = new G4AdjointInterpolator;
|
||||
fInstance = new G4AdjointInterpolator;
|
||||
}
|
||||
return theInstance;
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointInterpolator::G4AdjointInterpolator()
|
||||
{
|
||||
}
|
||||
G4AdjointInterpolator::G4AdjointInterpolator() {}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointInterpolator::~G4AdjointInterpolator()
|
||||
{
|
||||
}
|
||||
G4AdjointInterpolator::~G4AdjointInterpolator() {}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::LinearInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2)
|
||||
G4double G4AdjointInterpolator::LinearInterpolation(G4double& x, G4double& x1,
|
||||
G4double& x2, G4double& y1,
|
||||
G4double& y2)
|
||||
{
|
||||
G4double res = y1+ (x-x1)*(y2-y1)/(x2-x1);
|
||||
//G4cout<<"Linear "<<res<<G4endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::LogarithmicInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2)
|
||||
{
|
||||
if (y1<=0 || y2<=0 || x1<=0) return LinearInterpolation(x,x1,x2,y1,y2);
|
||||
G4double B=std::log(y2/y1)/std::log(x2/x1);
|
||||
//G4cout<<"x1,x2,y1,y2 "<<x1<<'\t'<<x2<<'\t'<<y1<<'\t'<<y2<<'\t'<<G4endl;
|
||||
G4double A=y1/std::pow(x1,B);
|
||||
G4double res=A*std::pow(x,B);
|
||||
// G4cout<<"Log "<<res<<G4endl;
|
||||
G4double res = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::ExponentialInterpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2)
|
||||
G4double G4AdjointInterpolator::LogarithmicInterpolation(
|
||||
G4double& x, G4double& x1, G4double& x2, G4double& y1, G4double& y2)
|
||||
{
|
||||
G4double B=(std::log(y2)-std::log(y1));
|
||||
B=B/(x2-x1);
|
||||
G4double A=y1*std::exp(-B*x1);
|
||||
G4double res=A*std::exp(B*x);
|
||||
if(y1 <= 0. || y2 <= 0. || x1 <= 0.)
|
||||
return LinearInterpolation(x, x1, x2, y1, y2);
|
||||
G4double B = std::log(y2 / y1) / std::log(x2 / x1);
|
||||
G4double A = y1 / std::pow(x1, B);
|
||||
G4double res = A * std::pow(x, B);
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::Interpolation(G4double& x,G4double& x1,G4double& x2,G4double& y1,G4double& y2,G4String InterPolMethod)
|
||||
G4double G4AdjointInterpolator::ExponentialInterpolation(
|
||||
G4double& x, G4double& x1, G4double& x2, G4double& y1, G4double& y2)
|
||||
{
|
||||
if (InterPolMethod == "Log" ){
|
||||
return LogarithmicInterpolation(x,x1,x2,y1,y2);
|
||||
G4double B = (std::log(y2) - std::log(y1)) / (x2 - x1);
|
||||
G4double A = y1 * std::exp(-B * x1);
|
||||
G4double res = A * std::exp(B * x);
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
G4double G4AdjointInterpolator::Interpolation(G4double& x, G4double& x1,
|
||||
G4double& x2, G4double& y1,
|
||||
G4double& y2,
|
||||
G4String InterPolMethod)
|
||||
{
|
||||
if(InterPolMethod == "Log")
|
||||
{
|
||||
return LogarithmicInterpolation(x, x1, x2, y1, y2);
|
||||
}
|
||||
else if (InterPolMethod == "Lin" ){
|
||||
return LinearInterpolation(x,x1,x2,y1,y2);
|
||||
else if(InterPolMethod == "Lin")
|
||||
{
|
||||
return LinearInterpolation(x, x1, x2, y1, y2);
|
||||
}
|
||||
else if (InterPolMethod == "Exp" ){
|
||||
return ExponentialInterpolation(x,x1,x2,y1,y2);
|
||||
else if(InterPolMethod == "Exp")
|
||||
{
|
||||
return ExponentialInterpolation(x, x1, x2, y1, y2);
|
||||
}
|
||||
else {
|
||||
//G4cout<<"The interpolation method that you invoked does not exist!"<<G4endl;
|
||||
return -1111111111.;
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "The interpolation method that you invoked does not exist!\n";
|
||||
G4Exception("G4AdjointInterpolator::Interpolation", "adoint001",
|
||||
FatalException, ed);
|
||||
return 0.;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
size_t G4AdjointInterpolator::FindPosition(G4double& x,std::vector<G4double>& x_vec,size_t , size_t ) //only valid if x_vec is monotically increasing
|
||||
// only valid if x_vec is monotically increasing
|
||||
size_t G4AdjointInterpolator::FindPosition(G4double& x,
|
||||
std::vector<G4double>& x_vec, size_t,
|
||||
size_t)
|
||||
{
|
||||
//most rapid nethod could be used probably
|
||||
//It is important to put std::vector<G4double>& such that the vector itself is used and not a copy
|
||||
|
||||
|
||||
// most rapid method could be used probably
|
||||
|
||||
size_t ndim = x_vec.size();
|
||||
size_t ind1 = 0;
|
||||
size_t ind2 = ndim - 1;
|
||||
/* if (ind_max >= ind_min){
|
||||
ind1=ind_min;
|
||||
ind2=ind_max;
|
||||
|
||||
|
||||
|
||||
if(ndim > 1)
|
||||
{
|
||||
if(x_vec[0] < x_vec[1])
|
||||
{ // increasing
|
||||
do
|
||||
{
|
||||
size_t midBin = (ind1 + ind2) / 2;
|
||||
if(x < x_vec[midBin])
|
||||
ind2 = midBin;
|
||||
else
|
||||
ind1 = midBin;
|
||||
} while(ind2 - ind1 > 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
size_t midBin = (ind1 + ind2) / 2;
|
||||
if(x < x_vec[midBin])
|
||||
ind1 = midBin;
|
||||
else
|
||||
ind2 = midBin;
|
||||
} while(ind2 - ind1 > 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if (ndim >1) {
|
||||
|
||||
if (x_vec[0] < x_vec[1] ) { //increasing
|
||||
do {
|
||||
size_t midBin = (ind1 + ind2)/2;
|
||||
if (x < x_vec[midBin])
|
||||
ind2 = midBin;
|
||||
else
|
||||
ind1 = midBin;
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
} while (ind2 - ind1 > 1);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
size_t midBin = (ind1 + ind2)/2;
|
||||
if (x < x_vec[midBin])
|
||||
ind1 = midBin;
|
||||
else
|
||||
ind2 = midBin;
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
} while (ind2 - ind1 > 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return ind1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
size_t G4AdjointInterpolator::FindPositionForLogVector(G4double& log_x,std::vector<G4double>& log_x_vec) //only valid if x_vec is monotically increasing
|
||||
// only valid if x_vec is monotically increasing
|
||||
size_t G4AdjointInterpolator::FindPositionForLogVector(
|
||||
G4double& log_x, std::vector<G4double>& log_x_vec)
|
||||
{
|
||||
//most rapid nethod could be used probably
|
||||
//It is important to put std::vector<G4double>& such that the vector itself is used and not a copy
|
||||
// most rapid method could be used probably
|
||||
return FindPosition(log_x, log_x_vec);
|
||||
/*
|
||||
if (log_x_vec.size()>3){
|
||||
size_t ind=0;
|
||||
G4double log_x1=log_x_vec[1];
|
||||
G4double d_log =log_x_vec[2]-log_x1;
|
||||
G4double dind=(log_x-log_x1)/d_log +1.;
|
||||
if (dind <1.) ind=0;
|
||||
else if (dind >= double(log_x_vec.size())-2.) ind =log_x_vec.size()-2;
|
||||
else ind =size_t(dind);
|
||||
return ind;
|
||||
|
||||
}
|
||||
else return FindPosition(log_x, log_x_vec);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::Interpolate(G4double& x,std::vector<G4double>& x_vec,std::vector<G4double>& y_vec,G4String InterPolMethod)
|
||||
G4double G4AdjointInterpolator::Interpolate(G4double& x,
|
||||
std::vector<G4double>& x_vec,
|
||||
std::vector<G4double>& y_vec,
|
||||
G4String InterPolMethod)
|
||||
{
|
||||
size_t i=FindPosition(x,x_vec);
|
||||
//G4cout<<i<<G4endl;
|
||||
//G4cout<<x<<G4endl;
|
||||
//G4cout<<x_vec[i]<<G4endl;
|
||||
return Interpolation( x,x_vec[i],x_vec[i+1],y_vec[i],y_vec[i+1],InterPolMethod);
|
||||
size_t i = FindPosition(x, x_vec);
|
||||
return Interpolation(x, x_vec[i], x_vec[i + 1], y_vec[i], y_vec[i + 1],
|
||||
InterPolMethod);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::InterpolateWithIndexVector(G4double& x,std::vector<G4double>& x_vec,std::vector<G4double>& y_vec,
|
||||
std::vector<size_t>& index_vec,G4double x0, G4double dx) //only linear interpolation possible
|
||||
G4double G4AdjointInterpolator::InterpolateWithIndexVector(
|
||||
G4double& x, std::vector<G4double>& x_vec, std::vector<G4double>& y_vec,
|
||||
std::vector<size_t>& index_vec, G4double x0,
|
||||
G4double dx) // only linear interpolation possible
|
||||
{
|
||||
size_t ind=0;
|
||||
if (x>x0) ind=int((x-x0)/dx);
|
||||
if (ind >= index_vec.size()-1) ind= index_vec.size()-2;
|
||||
size_t ind = 0;
|
||||
if(x > x0)
|
||||
ind = int((x - x0) / dx);
|
||||
if(ind >= index_vec.size() - 1)
|
||||
ind = index_vec.size() - 2;
|
||||
size_t ind1 = index_vec[ind];
|
||||
size_t ind2 = index_vec[ind+1];
|
||||
if (ind1 >ind2) {
|
||||
size_t ind11=ind1;
|
||||
ind1=ind2;
|
||||
ind2=ind11;
|
||||
|
||||
size_t ind2 = index_vec[ind + 1];
|
||||
if(ind1 > ind2)
|
||||
{
|
||||
size_t ind11 = ind1;
|
||||
ind1 = ind2;
|
||||
ind2 = ind11;
|
||||
}
|
||||
ind=FindPosition(x,x_vec,ind1,ind2);
|
||||
return Interpolation( x,x_vec[ind],x_vec[ind+1],y_vec[ind],y_vec[ind+1],"Lin");
|
||||
}
|
||||
ind = FindPosition(x, x_vec, ind1, ind2);
|
||||
return Interpolation(x, x_vec[ind], x_vec[ind + 1], y_vec[ind],
|
||||
y_vec[ind + 1], "Lin");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointInterpolator::InterpolateForLogVector(G4double& log_x,std::vector<G4double>& log_x_vec,std::vector<G4double>& log_y_vec)
|
||||
G4double G4AdjointInterpolator::InterpolateForLogVector(
|
||||
G4double& log_x, std::vector<G4double>& log_x_vec,
|
||||
std::vector<G4double>& log_y_vec)
|
||||
{
|
||||
//size_t i=0;
|
||||
size_t i=FindPositionForLogVector(log_x,log_x_vec);
|
||||
/*G4cout<<"In interpolate "<<G4endl;
|
||||
G4cout<<i<<G4endl;
|
||||
G4cout<<log_x<<G4endl;
|
||||
G4cout<<log_x_vec[i]<<G4endl;
|
||||
G4cout<<log_x_vec[i+1]<<G4endl;
|
||||
G4cout<<log_y_vec[i]<<G4endl;
|
||||
G4cout<<log_y_vec[i+1]<<G4endl;*/
|
||||
|
||||
G4double log_y=LinearInterpolation(log_x,log_x_vec[i],log_x_vec[i+1],log_y_vec[i],log_y_vec[i+1]);
|
||||
size_t i = FindPositionForLogVector(log_x, log_x_vec);
|
||||
|
||||
G4double log_y = LinearInterpolation(log_x, log_x_vec[i], log_x_vec[i + 1],
|
||||
log_y_vec[i], log_y_vec[i + 1]);
|
||||
return log_y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,341 +23,317 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
#include "G4AdjointIonIonisationModel.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointIonIonisationModel.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4AdjointProton.hh"
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
#include "G4BetheBlochModel.hh"
|
||||
#include "G4BraggIonModel.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointIonIonisationModel::G4AdjointIonIonisationModel():
|
||||
G4VEmAdjointModel("Adjoint_IonIonisation")
|
||||
{
|
||||
|
||||
|
||||
UseMatrix =true;
|
||||
UseMatrixPerElement = true;
|
||||
ApplyCutInRange = true;
|
||||
UseOnlyOneMatrixForAllElements = true;
|
||||
CS_biasing_factor =1.;
|
||||
second_part_of_same_type =false;
|
||||
use_only_bragg = false; // for the Ion ionisation using the parametrised table model the cross sections and the sample of secondaries is done
|
||||
// as in the BraggIonModel, Therefore the use of this flag;
|
||||
|
||||
//The direct EM Model is taken has BetheBloch it is only used for the computation
|
||||
// of the differential cross section.
|
||||
//The Bragg model could be used as an alternative as it offers the same differential cross section
|
||||
|
||||
theBetheBlochDirectEMModel = new G4BetheBlochModel(G4GenericIon::GenericIon());
|
||||
theBraggIonDirectEMModel = new G4BraggIonModel(G4GenericIon::GenericIon());
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron();
|
||||
theDirectPrimaryPartDef =0;
|
||||
theAdjEquivOfDirectPrimPartDef =0;
|
||||
/* theDirectPrimaryPartDef =fwd_ion;
|
||||
theAdjEquivOfDirectPrimPartDef =adj_ion;
|
||||
|
||||
DefineProjectileProperty();*/
|
||||
|
||||
|
||||
G4AdjointIonIonisationModel::G4AdjointIonIonisationModel()
|
||||
: G4VEmAdjointModel("Adjoint_IonIonisation")
|
||||
{
|
||||
fUseMatrix = true;
|
||||
fUseMatrixPerElement = true;
|
||||
fApplyCutInRange = true;
|
||||
fOneMatrixForAllElements = true;
|
||||
fSecondPartSameType = false;
|
||||
|
||||
// The direct EM Model is taken as BetheBloch. It is only used for the
|
||||
// computation of the differential cross section.
|
||||
// The Bragg model could be used as an alternative as it offers the same
|
||||
// differential cross section
|
||||
|
||||
fBetheBlochDirectEMModel = new G4BetheBlochModel(G4GenericIon::GenericIon());
|
||||
fBraggIonDirectEMModel = new G4BraggIonModel(G4GenericIon::GenericIon());
|
||||
fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
|
||||
fDirectPrimaryPart = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointIonIonisationModel::~G4AdjointIonIonisationModel()
|
||||
{;}
|
||||
G4AdjointIonIonisationModel::~G4AdjointIonIonisationModel() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointIonIonisationModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
|
||||
//Elastic inverse scattering
|
||||
//---------------------------------------------------------
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP =theAdjointPrimary->GetTotalMomentum();
|
||||
void G4AdjointIonIonisationModel::SampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
//Sample secondary energy
|
||||
//-----------------------
|
||||
G4double projectileKinEnergy = SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, IsScatProjToProjCase);
|
||||
CorrectPostStepWeight(fParticleChange,
|
||||
aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy,
|
||||
projectileKinEnergy,
|
||||
IsScatProjToProjCase); //Caution !!!this weight correction should be always applied
|
||||
// Elastic inverse scattering
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP = theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
|
||||
//Kinematic:
|
||||
//we consider a two body elastic scattering for the forward processes where the projectile knock on an e- at rest and gives
|
||||
// him part of its energy
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
|
||||
|
||||
|
||||
//Companion
|
||||
//-----------
|
||||
G4double companionM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
if (IsScatProjToProjCase) {
|
||||
companionM0=theAdjEquivOfDirectSecondPartDef->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =companionM0+ projectileKinEnergy-adjointPrimKinEnergy;
|
||||
G4double companionP2 = companionTotalEnergy*companionTotalEnergy - companionM0*companionM0;
|
||||
|
||||
|
||||
//Projectile momentum
|
||||
//--------------------
|
||||
G4double P_parallel = (adjointPrimP*adjointPrimP + projectileP2 - companionP2)/(2.*adjointPrimP);
|
||||
G4double P_perp = std::sqrt( projectileP2 - P_parallel*P_parallel);
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector projectileMomentum = G4ThreeVector(P_perp*std::cos(phi),P_perp*std::sin(phi),P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
//G4cout<<"projectileMomentum "<<projectileMomentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointIonIonisationModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj,
|
||||
G4double kinEnergyProd,
|
||||
G4double Z,
|
||||
G4double A)
|
||||
{//Probably that here the Bragg Model should be also used for kinEnergyProj/nuc<2MeV
|
||||
|
||||
|
||||
|
||||
G4double dSigmadEprod=0;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(kinEnergyProd);
|
||||
|
||||
G4double kinEnergyProjScaled = massRatio*kinEnergyProj;
|
||||
|
||||
|
||||
if (kinEnergyProj>Emin_proj && kinEnergyProj<=Emax_proj){ //the produced particle should have a kinetic energy smaller than the projectile
|
||||
G4double Tmax=kinEnergyProj;
|
||||
|
||||
G4double E1=kinEnergyProd;
|
||||
G4double E2=kinEnergyProd*1.000001;
|
||||
G4double dE=(E2-E1);
|
||||
G4double sigma1,sigma2;
|
||||
theDirectEMModel =theBraggIonDirectEMModel;
|
||||
if (kinEnergyProjScaled >2.*MeV && !use_only_bragg) theDirectEMModel = theBetheBlochDirectEMModel; //Bethe Bloch Model
|
||||
sigma1=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E1,1.e20);
|
||||
sigma2=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E2,1.e20);
|
||||
|
||||
dSigmadEprod=(sigma1-sigma2)/dE;
|
||||
|
||||
//G4double chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPrimaryPartDef,currentMaterial,E);
|
||||
|
||||
|
||||
|
||||
if (dSigmadEprod>1.) {
|
||||
G4cout<<"sigma1 "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<sigma1<<G4endl;
|
||||
G4cout<<"sigma2 "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<sigma2<<G4endl;
|
||||
G4cout<<"dsigma "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<dSigmadEprod<<G4endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (theDirectEMModel == theBetheBlochDirectEMModel ){
|
||||
//correction of differential cross section at high energy to correct for the suppression of particle at secondary at high
|
||||
//energy used in the Bethe Bloch Model. This correction consist to multiply by g the probability function used
|
||||
//to test the rejection of a secondary
|
||||
//-------------------------
|
||||
|
||||
//Source code taken from G4BetheBlochModel::SampleSecondaries
|
||||
|
||||
G4double deltaKinEnergy = kinEnergyProd;
|
||||
|
||||
//Part of the taken code
|
||||
//----------------------
|
||||
|
||||
|
||||
|
||||
// projectile formfactor - suppresion of high energy
|
||||
// delta-electron production at high energy
|
||||
|
||||
|
||||
G4double x = formfact*deltaKinEnergy;
|
||||
if(x > 1.e-6) {
|
||||
G4double totEnergy = kinEnergyProj + mass;
|
||||
G4double etot2 = totEnergy*totEnergy;
|
||||
G4double beta2 = kinEnergyProj*(kinEnergyProj + 2.0*mass)/etot2;
|
||||
G4double f;
|
||||
G4double f1 = 0.0;
|
||||
f = 1.0 - beta2*deltaKinEnergy/Tmax;
|
||||
if( 0.5 == spin ) {
|
||||
f1 = 0.5*deltaKinEnergy*deltaKinEnergy/etot2;
|
||||
f += f1;
|
||||
}
|
||||
G4double x1 = 1.0 + x;
|
||||
G4double gg = 1.0/(x1*x1);
|
||||
if( 0.5 == spin ) {
|
||||
G4double x2 = 0.5*electron_mass_c2*deltaKinEnergy/(mass*mass);
|
||||
gg *= (1.0 + magMoment2*(x2 - f1/f)/(1.0 + x2));
|
||||
}
|
||||
if(gg > 1.0) {
|
||||
G4cout << "### G4BetheBlochModel in Adjoint Sim WARNING: gg= " << gg
|
||||
<< G4endl;
|
||||
gg=1.;
|
||||
}
|
||||
//G4cout<<"gg"<<gg<<G4endl;
|
||||
dSigmadEprod*=gg;
|
||||
}
|
||||
}
|
||||
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return dSigmadEprod;
|
||||
// Sample secondary energy
|
||||
G4double projectileKinEnergy =
|
||||
SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, isScatProjToProj);
|
||||
// Caution !!!this weight correction should be always applied
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy, projectileKinEnergy,
|
||||
isScatProjToProj);
|
||||
|
||||
// Kinematics:
|
||||
// we consider a two body elastic scattering for the forward processes where
|
||||
// the projectile knock on an e- at rest and gives it part of its energy
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
|
||||
// Companion
|
||||
G4double companionM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
if(isScatProjToProj)
|
||||
{
|
||||
companionM0 = fAdjEquivDirectSecondPart->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =
|
||||
companionM0 + projectileKinEnergy - adjointPrimKinEnergy;
|
||||
G4double companionP2 =
|
||||
companionTotalEnergy * companionTotalEnergy - companionM0 * companionM0;
|
||||
|
||||
// Projectile momentum
|
||||
G4double P_parallel =
|
||||
(adjointPrimP * adjointPrimP + projectileP2 - companionP2) /
|
||||
(2. * adjointPrimP);
|
||||
G4double P_perp = std::sqrt(projectileP2 - P_parallel * P_parallel);
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector projectileMomentum =
|
||||
G4ThreeVector(P_perp * std::cos(phi), P_perp * std::sin(phi), P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointIonIonisationModel::SetIon(G4ParticleDefinition* adj_ion, G4ParticleDefinition* fwd_ion)
|
||||
{ theDirectPrimaryPartDef =fwd_ion;
|
||||
theAdjEquivOfDirectPrimPartDef =adj_ion;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointIonIonisationModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, G4double kinEnergyProd, G4double Z, G4double A)
|
||||
{
|
||||
// Probably that here the Bragg Model should be also used for
|
||||
// kinEnergyProj/nuc<2MeV
|
||||
G4double dSigmadEprod = 0.;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(kinEnergyProd);
|
||||
|
||||
G4double kinEnergyProjScaled = fMassRatio * kinEnergyProj;
|
||||
|
||||
// the produced particle should have a kinetic energy smaller than the
|
||||
// projectile
|
||||
if(kinEnergyProj > Emin_proj && kinEnergyProj <= Emax_proj)
|
||||
{
|
||||
G4double Tmax = kinEnergyProj;
|
||||
|
||||
G4double E1 = kinEnergyProd;
|
||||
G4double E2 = kinEnergyProd * 1.000001;
|
||||
G4double dE = (E2 - E1);
|
||||
G4double sigma1, sigma2;
|
||||
fDirectModel = fBraggIonDirectEMModel;
|
||||
if(kinEnergyProjScaled > 2. * MeV && !fUseOnlyBragg)
|
||||
fDirectModel = fBetheBlochDirectEMModel;
|
||||
sigma1 = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E1, 1.e20);
|
||||
sigma2 = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E2, 1.e20);
|
||||
|
||||
dSigmadEprod = (sigma1 - sigma2) / dE;
|
||||
|
||||
if(dSigmadEprod > 1.)
|
||||
{
|
||||
G4cout << "sigma1 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << sigma1 << G4endl;
|
||||
G4cout << "sigma2 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << sigma2 << G4endl;
|
||||
G4cout << "dsigma " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << dSigmadEprod << G4endl;
|
||||
}
|
||||
|
||||
if(fDirectModel == fBetheBlochDirectEMModel)
|
||||
{
|
||||
// correction of differential cross section at high energy to correct for
|
||||
// the suppression of particle at secondary at high energy used in the
|
||||
// Bethe Bloch Model. This correction consist to multiply by g the
|
||||
// probability function used to test the rejection of a secondary Source
|
||||
// code taken from G4BetheBlochModel::SampleSecondaries
|
||||
|
||||
G4double deltaKinEnergy = kinEnergyProd;
|
||||
|
||||
G4double x = fFormFact * deltaKinEnergy;
|
||||
if(x > 1.e-6)
|
||||
{
|
||||
G4double totEnergy = kinEnergyProj + fMass;
|
||||
G4double etot2 = totEnergy * totEnergy;
|
||||
G4double beta2 = kinEnergyProj * (kinEnergyProj + 2.0 * fMass) / etot2;
|
||||
G4double f1 = 0.0;
|
||||
G4double f = 1.0 - beta2 * deltaKinEnergy / Tmax;
|
||||
if(0.5 == fSpin)
|
||||
{
|
||||
f1 = 0.5 * deltaKinEnergy * deltaKinEnergy / etot2;
|
||||
f += f1;
|
||||
}
|
||||
G4double x1 = 1.0 + x;
|
||||
G4double gg = 1.0 / (x1 * x1);
|
||||
if(0.5 == fSpin)
|
||||
{
|
||||
G4double x2 =
|
||||
0.5 * electron_mass_c2 * deltaKinEnergy / (fMass * fMass);
|
||||
gg *= (1.0 + fMagMoment2 * (x2 - f1 / f) / (1.0 + x2));
|
||||
}
|
||||
if(gg > 1.0)
|
||||
{
|
||||
G4cout << "### G4BetheBlochModel in Adjoint Sim WARNING: gg= " << gg
|
||||
<< G4endl;
|
||||
gg = 1.;
|
||||
}
|
||||
dSigmadEprod *= gg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dSigmadEprod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointIonIonisationModel::SetIon(G4ParticleDefinition* adj_ion,
|
||||
G4ParticleDefinition* fwd_ion)
|
||||
{
|
||||
fDirectPrimaryPart = fwd_ion;
|
||||
fAdjEquivDirectPrimPart = adj_ion;
|
||||
|
||||
DefineProjectileProperty();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointIonIonisationModel::CorrectPostStepWeight(G4ParticleChange* fParticleChange, G4double old_weight,
|
||||
G4double adjointPrimKinEnergy, G4double projectileKinEnergy,G4bool )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointIonIonisationModel::CorrectPostStepWeight(
|
||||
G4ParticleChange* fParticleChange, G4double old_weight,
|
||||
G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool)
|
||||
{
|
||||
//It is needed because the direct cross section used to compute the differential cross section is not the one used in
|
||||
// the direct model where the GenericIon stuff is considered with correction of effective charge. In the direct model the samnepl of secondaries does
|
||||
// not reflect the integral cross section. The integral fwd cross section that we used to compute the differential CS
|
||||
// match the sample of secondaries in the forward case despite the fact that its is not the same total CS than in the FWD case. For this reasion an extra
|
||||
// weight correction is needed at the end.
|
||||
|
||||
// It is needed because the direct cross section used to compute the
|
||||
// differential cross section is not the one used in
|
||||
// the direct model where the GenericIon stuff is considered with correction
|
||||
// of effective charge. In the direct model the samnepl of secondaries does
|
||||
// not reflect the integral cross section. The integral fwd cross section that
|
||||
// we used to compute the differential CS match the sample of secondaries in
|
||||
// the forward case despite the fact that its is not the same total CS than in
|
||||
// the FWD case. For this reason an extra weight correction is needed at the
|
||||
// end.
|
||||
|
||||
G4double new_weight=old_weight;
|
||||
|
||||
//the correction of CS due to the problem explained above
|
||||
G4double kinEnergyProjScaled = massRatio*projectileKinEnergy;
|
||||
theDirectEMModel =theBraggIonDirectEMModel;
|
||||
if (kinEnergyProjScaled >2.*MeV && !use_only_bragg) theDirectEMModel = theBetheBlochDirectEMModel; //Bethe Bloch Model
|
||||
G4double UsedFwdCS=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,projectileKinEnergy,1,1 ,currentTcutForDirectSecond,1.e20);
|
||||
G4double chargeSqRatio =1.;
|
||||
if (chargeSquare>1.) chargeSqRatio = theDirectEMModel->GetChargeSquareRatio(theDirectPrimaryPartDef,currentMaterial,projectileKinEnergy);
|
||||
G4double CorrectFwdCS = chargeSqRatio*theDirectEMModel->ComputeCrossSectionPerAtom(G4GenericIon::GenericIon(),kinEnergyProjScaled,1,1 ,currentTcutForDirectSecond,1.e20);
|
||||
if (UsedFwdCS >0) new_weight*= CorrectFwdCS/UsedFwdCS;//May be some check is needed if UsedFwdCS ==0 probably that then we should avoid a secondary to be produced,
|
||||
|
||||
|
||||
//additional CS crorrection needed for cross section biasing in general.
|
||||
//May be wrong for ions!!! Most of the time not used!
|
||||
G4double w_corr =1./CS_biasing_factor;
|
||||
w_corr*=G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
new_weight*=w_corr;
|
||||
|
||||
new_weight*=projectileKinEnergy/adjointPrimKinEnergy;
|
||||
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
G4double new_weight = old_weight;
|
||||
|
||||
// the correction of CS due to the problem explained above
|
||||
G4double kinEnergyProjScaled = fMassRatio * projectileKinEnergy;
|
||||
fDirectModel = fBraggIonDirectEMModel;
|
||||
if(kinEnergyProjScaled > 2. * MeV && !fUseOnlyBragg)
|
||||
fDirectModel = fBetheBlochDirectEMModel;
|
||||
G4double UsedFwdCS = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, projectileKinEnergy, 1, 1, fTcutSecond, 1.e20);
|
||||
G4double chargeSqRatio = 1.;
|
||||
if(fChargeSquare > 1.)
|
||||
chargeSqRatio = fDirectModel->GetChargeSquareRatio(
|
||||
fDirectPrimaryPart, fCurrentMaterial, projectileKinEnergy);
|
||||
G4double CorrectFwdCS =
|
||||
chargeSqRatio * fDirectModel->ComputeCrossSectionPerAtom(
|
||||
G4GenericIon::GenericIon(), kinEnergyProjScaled, 1, 1,
|
||||
fTcutSecond, 1.e20);
|
||||
// May be some check is needed if UsedFwdCS ==0 probably that then we should
|
||||
// avoid a secondary to be produced,
|
||||
if(UsedFwdCS > 0.)
|
||||
new_weight *= CorrectFwdCS / UsedFwdCS;
|
||||
|
||||
// additional CS correction needed for cross section biasing in general.
|
||||
// May be wrong for ions. Most of the time not used.
|
||||
new_weight *=
|
||||
G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection() /
|
||||
fCsBiasingFactor;
|
||||
|
||||
new_weight *= projectileKinEnergy / adjointPrimKinEnergy;
|
||||
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointIonIonisationModel::DefineProjectileProperty()
|
||||
{
|
||||
//Slightly modified code taken from G4BetheBlochModel::SetParticle
|
||||
//------------------------------------------------
|
||||
G4String pname = theDirectPrimaryPartDef->GetParticleName();
|
||||
if (theDirectPrimaryPartDef->GetParticleType() == "nucleus" &&
|
||||
pname != "deuteron" && pname != "triton") {
|
||||
isIon = true;
|
||||
{
|
||||
// Slightly modified code taken from G4BetheBlochModel::SetParticle
|
||||
G4String pname = fDirectPrimaryPart->GetParticleName();
|
||||
|
||||
fMass = fDirectPrimaryPart->GetPDGMass();
|
||||
fMassRatio = G4GenericIon::GenericIon()->GetPDGMass() / fMass;
|
||||
fSpin = fDirectPrimaryPart->GetPDGSpin();
|
||||
G4double q = fDirectPrimaryPart->GetPDGCharge() / eplus;
|
||||
fChargeSquare = q * q;
|
||||
fRatio = electron_mass_c2 / fMass;
|
||||
fOnePlusRatio2 = (1. + fRatio) * (1. + fRatio);
|
||||
fOneMinusRatio2 = (1. - fRatio) * (1. - fRatio);
|
||||
G4double magmom = fDirectPrimaryPart->GetPDGMagneticMoment() * fMass /
|
||||
(0.5 * eplus * hbar_Planck * c_squared);
|
||||
fMagMoment2 = magmom * magmom - 1.0;
|
||||
if(fDirectPrimaryPart->GetLeptonNumber() == 0)
|
||||
{
|
||||
G4double x = 0.8426 * GeV;
|
||||
if(fSpin == 0.0 && fMass < GeV)
|
||||
{
|
||||
x = 0.736 * GeV;
|
||||
}
|
||||
|
||||
mass = theDirectPrimaryPartDef->GetPDGMass();
|
||||
massRatio= G4GenericIon::GenericIon()->GetPDGMass()/mass;
|
||||
mass_ratio_projectile = massRatio;
|
||||
spin = theDirectPrimaryPartDef->GetPDGSpin();
|
||||
G4double q = theDirectPrimaryPartDef->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
ratio = electron_mass_c2/mass;
|
||||
ratio2 = ratio*ratio;
|
||||
one_plus_ratio_2=(1+ratio)*(1+ratio);
|
||||
one_minus_ratio_2=(1-ratio)*(1-ratio);
|
||||
G4double magmom = theDirectPrimaryPartDef->GetPDGMagneticMoment()
|
||||
*mass/(0.5*eplus*hbar_Planck*c_squared);
|
||||
magMoment2 = magmom*magmom - 1.0;
|
||||
formfact = 0.0;
|
||||
if(theDirectPrimaryPartDef->GetLeptonNumber() == 0) {
|
||||
G4double x = 0.8426*GeV;
|
||||
if(spin == 0.0 && mass < GeV) {x = 0.736*GeV;}
|
||||
else if(mass > GeV) {
|
||||
x /= G4NistManager::Instance()->GetZ13(mass/proton_mass_c2);
|
||||
// tlimit = 51.2*GeV*A13[iz]*A13[iz];
|
||||
}
|
||||
formfact = 2.0*electron_mass_c2/(x*x);
|
||||
tlimit = 2.0/formfact;
|
||||
}
|
||||
else if(fMass > GeV)
|
||||
{
|
||||
x /= G4NistManager::Instance()->GetZ13(fMass / proton_mass_c2);
|
||||
}
|
||||
fFormFact = 2.0 * electron_mass_c2 / (x * x);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
return primAdjEnergy * fOnePlusRatio2 /
|
||||
(fOneMinusRatio2 - 2. * fRatio * primAdjEnergy / fMass);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy)
|
||||
{
|
||||
G4double Tmax=PrimAdjEnergy*one_plus_ratio_2/(one_minus_ratio_2-2.*ratio*PrimAdjEnergy/mass);
|
||||
return Tmax;
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMinForScatProjToProj(
|
||||
G4double primAdjEnergy, G4double tcut)
|
||||
{
|
||||
return primAdjEnergy + tcut;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMinForScatProjToProjCase(G4double PrimAdjEnergy,G4double Tcut)
|
||||
{ return PrimAdjEnergy+Tcut;
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMaxForProdToProj(
|
||||
G4double)
|
||||
{
|
||||
return GetHighEnergyLimit();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMaxForProdToProjCase(G4double )
|
||||
{ return HighEnergyLimit;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy)
|
||||
{ G4double Tmin= (2*PrimAdjEnergy-4*mass + std::sqrt(4.*PrimAdjEnergy*PrimAdjEnergy +16.*mass*mass + 8.*PrimAdjEnergy*mass*(1/ratio +ratio)))/4.;
|
||||
return Tmin;
|
||||
G4double G4AdjointIonIonisationModel::GetSecondAdjEnergyMinForProdToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
return (2. * primAdjEnergy - 4. * fMass +
|
||||
std::sqrt(4. * primAdjEnergy * primAdjEnergy + 16. * fMass * fMass +
|
||||
8. * primAdjEnergy * fMass * (1. / fRatio + fRatio))) /
|
||||
4.;
|
||||
}
|
||||
|
||||
@@ -23,250 +23,213 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointPhotoElectricModel.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PEEffectFluoModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPhotoElectricModel::G4AdjointPhotoElectricModel():
|
||||
G4VEmAdjointModel("AdjointPEEffect")
|
||||
G4AdjointPhotoElectricModel::G4AdjointPhotoElectricModel()
|
||||
: G4VEmAdjointModel("AdjointPEEffect")
|
||||
|
||||
{ SetUseMatrix(false);
|
||||
{
|
||||
SetUseMatrix(false);
|
||||
SetApplyCutInRange(false);
|
||||
|
||||
//Initialization
|
||||
current_eEnergy =0.;
|
||||
totAdjointCS=0.;
|
||||
factorCSBiasing =1.;
|
||||
post_step_AdjointCS =0.;
|
||||
pre_step_AdjointCS =0.;
|
||||
totBiasedAdjointCS =0.;
|
||||
|
||||
index_element=0;
|
||||
|
||||
theAdjEquivOfDirectPrimPartDef =G4AdjointGamma::AdjointGamma();
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron();
|
||||
theDirectPrimaryPartDef=G4Gamma::Gamma();
|
||||
second_part_of_same_type=false;
|
||||
theDirectPEEffectModel = new G4PEEffectFluoModel();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPhotoElectricModel::~G4AdjointPhotoElectricModel()
|
||||
{;}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPhotoElectricModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{ if (IsScatProjToProjCase) return ;
|
||||
|
||||
//Compute the totAdjointCS vectors if not already done for the current couple and electron energy
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
const G4MaterialCutsCouple* aCouple = aTrack.GetMaterialCutsCouple();
|
||||
const G4DynamicParticle* aDynPart = aTrack.GetDynamicParticle() ;
|
||||
G4double electronEnergy = aDynPart->GetKineticEnergy();
|
||||
G4ThreeVector electronDirection= aDynPart->GetMomentumDirection() ;
|
||||
pre_step_AdjointCS = totAdjointCS; //The last computed CS was at pre step point
|
||||
post_step_AdjointCS = AdjointCrossSection(aCouple, electronEnergy,IsScatProjToProjCase);
|
||||
post_step_AdjointCS = totAdjointCS;
|
||||
|
||||
|
||||
|
||||
|
||||
//Sample element
|
||||
//-------------
|
||||
const G4ElementVector* theElementVector = currentMaterial->GetElementVector();
|
||||
size_t nelm = currentMaterial->GetNumberOfElements();
|
||||
G4double rand_CS= G4UniformRand()*xsec[nelm-1];
|
||||
for (index_element=0; index_element<nelm-1; index_element++){
|
||||
if (rand_CS<xsec[index_element]) break;
|
||||
}
|
||||
|
||||
//Sample shell and binding energy
|
||||
//-------------
|
||||
G4int nShells = (*theElementVector)[index_element]->GetNbOfAtomicShells();
|
||||
rand_CS= shell_prob[index_element][nShells-1]*G4UniformRand();
|
||||
G4int i = 0;
|
||||
for (i=0; i<nShells-1; i++){
|
||||
if (rand_CS<shell_prob[index_element][i]) break;
|
||||
}
|
||||
G4double gammaEnergy= electronEnergy+(*theElementVector)[index_element]->GetAtomicShell(i);
|
||||
|
||||
//Sample cos theta
|
||||
//Copy of the G4PEEfectFluoModel cos theta sampling method ElecCosThetaDistribution.
|
||||
//This method cannot be used directly from G4PEEfectFluoModel because it is a friend method. I should ask Vladimir to change that
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//G4double cos_theta = theDirectPEEffectModel->ElecCosThetaDistribution(electronEnergy);
|
||||
|
||||
G4double cos_theta = 1.;
|
||||
G4double gamma = 1. + electronEnergy/electron_mass_c2;
|
||||
if (gamma <= 5.) {
|
||||
G4double beta = std::sqrt(gamma*gamma-1.)/gamma;
|
||||
G4double b = 0.5*gamma*(gamma-1.)*(gamma-2);
|
||||
|
||||
G4double rndm,term,greject,grejsup;
|
||||
if (gamma < 2.) grejsup = gamma*gamma*(1.+b-beta*b);
|
||||
else grejsup = gamma*gamma*(1.+b+beta*b);
|
||||
|
||||
do { rndm = 1.-2*G4UniformRand();
|
||||
cos_theta = (rndm+beta)/(rndm*beta+1.);
|
||||
term = 1.-beta*cos_theta;
|
||||
greject = (1.-cos_theta*cos_theta)*(1.+b*term)/(term*term);
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
} while(greject < G4UniformRand()*grejsup);
|
||||
}
|
||||
|
||||
// direction of the adjoint gamma electron
|
||||
//---------------------------------------
|
||||
|
||||
|
||||
G4double sin_theta = std::sqrt(1.-cos_theta*cos_theta);
|
||||
G4double Phi = twopi * G4UniformRand();
|
||||
G4double dirx = sin_theta*std::cos(Phi),diry = sin_theta*std::sin(Phi),dirz = cos_theta;
|
||||
G4ThreeVector adjoint_gammaDirection(dirx,diry,dirz);
|
||||
adjoint_gammaDirection.rotateUz(electronDirection);
|
||||
|
||||
|
||||
|
||||
//Weight correction
|
||||
//-----------------------
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(), electronEnergy,gammaEnergy,IsScatProjToProjCase);
|
||||
|
||||
|
||||
|
||||
//Create secondary and modify fParticleChange
|
||||
//--------------------------------------------
|
||||
G4DynamicParticle* anAdjointGamma = new G4DynamicParticle (
|
||||
G4AdjointGamma::AdjointGamma(),adjoint_gammaDirection, gammaEnergy);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(anAdjointGamma);
|
||||
|
||||
|
||||
|
||||
|
||||
fAdjEquivDirectPrimPart = G4AdjointGamma::AdjointGamma();
|
||||
fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
|
||||
fDirectPrimaryPart = G4Gamma::Gamma();
|
||||
fSecondPartSameType = false;
|
||||
fDirectModel = new G4PEEffectFluoModel();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPhotoElectricModel::CorrectPostStepWeight(G4ParticleChange* fParticleChange,
|
||||
G4double old_weight,
|
||||
G4double adjointPrimKinEnergy,
|
||||
G4double projectileKinEnergy ,
|
||||
G4bool )
|
||||
G4AdjointPhotoElectricModel::~G4AdjointPhotoElectricModel() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointPhotoElectricModel::SampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
G4double new_weight=old_weight;
|
||||
if(isScatProjToProj)
|
||||
return;
|
||||
|
||||
G4double w_corr =G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection()/factorCSBiasing;
|
||||
w_corr*=post_step_AdjointCS/pre_step_AdjointCS;
|
||||
// Compute the fTotAdjointCS vectors if not already done for the current
|
||||
// couple and electron energy
|
||||
const G4DynamicParticle* aDynPart = aTrack.GetDynamicParticle();
|
||||
G4double electronEnergy = aDynPart->GetKineticEnergy();
|
||||
G4ThreeVector electronDirection = aDynPart->GetMomentumDirection();
|
||||
fPreStepAdjointCS =
|
||||
fTotAdjointCS; // The last computed CS was at pre step point
|
||||
AdjointCrossSection(aTrack.GetMaterialCutsCouple(), electronEnergy,
|
||||
isScatProjToProj);
|
||||
fPostStepAdjointCS = fTotAdjointCS;
|
||||
|
||||
// Sample element
|
||||
const G4ElementVector* theElementVector =
|
||||
fCurrentMaterial->GetElementVector();
|
||||
size_t nelm = fCurrentMaterial->GetNumberOfElements();
|
||||
G4double rand_CS = G4UniformRand() * fXsec[nelm - 1];
|
||||
for(fIndexElement = 0; fIndexElement < nelm - 1; ++fIndexElement)
|
||||
{
|
||||
if(rand_CS < fXsec[fIndexElement])
|
||||
break;
|
||||
}
|
||||
|
||||
new_weight*=w_corr;
|
||||
new_weight*=projectileKinEnergy/adjointPrimKinEnergy;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
}
|
||||
// Sample shell and binding energy
|
||||
G4int nShells = (*theElementVector)[fIndexElement]->GetNbOfAtomicShells();
|
||||
rand_CS = fShellProb[fIndexElement][nShells - 1] * G4UniformRand();
|
||||
G4int i;
|
||||
for(i = 0; i < nShells - 1; ++i)
|
||||
{
|
||||
if(rand_CS < fShellProb[fIndexElement][i])
|
||||
break;
|
||||
}
|
||||
G4double gammaEnergy =
|
||||
electronEnergy + (*theElementVector)[fIndexElement]->GetAtomicShell(i);
|
||||
|
||||
// Sample cos theta
|
||||
// Copy of the G4PEEfectFluoModel cos theta sampling method
|
||||
// ElecCosThetaDistribution. This method cannot be used directly from
|
||||
// G4PEEffectFluoModel because it is a friend method.
|
||||
G4double cos_theta = 1.;
|
||||
G4double gamma = 1. + electronEnergy / electron_mass_c2;
|
||||
if(gamma <= 5.)
|
||||
{
|
||||
G4double beta = std::sqrt(gamma * gamma - 1.) / gamma;
|
||||
G4double b = 0.5 * gamma * (gamma - 1.) * (gamma - 2.);
|
||||
|
||||
G4double rndm, term, greject, grejsup;
|
||||
if(gamma < 2.)
|
||||
grejsup = gamma * gamma * (1. + b - beta * b);
|
||||
else
|
||||
grejsup = gamma * gamma * (1. + b + beta * b);
|
||||
|
||||
do
|
||||
{
|
||||
rndm = 1. - 2. * G4UniformRand();
|
||||
cos_theta = (rndm + beta) / (rndm * beta + 1.);
|
||||
term = 1. - beta * cos_theta;
|
||||
greject = (1. - cos_theta * cos_theta) * (1. + b * term) / (term * term);
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
} while(greject < G4UniformRand() * grejsup);
|
||||
}
|
||||
|
||||
// direction of the adjoint gamma electron
|
||||
G4double sin_theta = std::sqrt(1. - cos_theta * cos_theta);
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double dirx = sin_theta * std::cos(phi);
|
||||
G4double diry = sin_theta * std::sin(phi);
|
||||
G4double dirz = cos_theta;
|
||||
G4ThreeVector adjoint_gammaDirection(dirx, diry, dirz);
|
||||
adjoint_gammaDirection.rotateUz(electronDirection);
|
||||
|
||||
// Weight correction
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(), electronEnergy,
|
||||
gammaEnergy, isScatProjToProj);
|
||||
|
||||
// Create secondary and modify fParticleChange
|
||||
G4DynamicParticle* anAdjointGamma = new G4DynamicParticle(
|
||||
G4AdjointGamma::AdjointGamma(), adjoint_gammaDirection, gammaEnergy);
|
||||
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(anAdjointGamma);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPhotoElectricModel::CorrectPostStepWeight(
|
||||
G4ParticleChange* fParticleChange, G4double old_weight,
|
||||
G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool)
|
||||
{
|
||||
G4double new_weight = old_weight;
|
||||
|
||||
G4double G4AdjointPhotoElectricModel::AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double electronEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{
|
||||
|
||||
G4double w_corr =
|
||||
G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection() /
|
||||
fFactorCSBiasing;
|
||||
w_corr *= fPostStepAdjointCS / fPreStepAdjointCS;
|
||||
|
||||
if (IsScatProjToProjCase) return 0.;
|
||||
new_weight *= w_corr * projectileKinEnergy / adjointPrimKinEnergy;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
}
|
||||
|
||||
|
||||
if (aCouple !=currentCouple || current_eEnergy !=electronEnergy) {
|
||||
totAdjointCS = 0.;
|
||||
DefineCurrentMaterialAndElectronEnergy(aCouple, electronEnergy);
|
||||
const G4ElementVector* theElementVector = currentMaterial->GetElementVector();
|
||||
const double* theAtomNumDensityVector = currentMaterial->GetVecNbOfAtomsPerVolume();
|
||||
size_t nelm = currentMaterial->GetNumberOfElements();
|
||||
for (index_element=0;index_element<nelm;index_element++){
|
||||
|
||||
totAdjointCS +=AdjointCrossSectionPerAtom((*theElementVector)[index_element],electronEnergy)*theAtomNumDensityVector[index_element];
|
||||
xsec[index_element] = totAdjointCS;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointPhotoElectricModel::AdjointCrossSection(
|
||||
const G4MaterialCutsCouple* aCouple, G4double electronEnergy,
|
||||
G4bool isScatProjToProj)
|
||||
{
|
||||
if(isScatProjToProj)
|
||||
return 0.;
|
||||
|
||||
totBiasedAdjointCS=std::min(totAdjointCS,0.01);
|
||||
// totBiasedAdjointCS=totAdjointCS;
|
||||
factorCSBiasing = totBiasedAdjointCS/totAdjointCS;
|
||||
lastCS=totBiasedAdjointCS;
|
||||
|
||||
|
||||
G4double totBiasedAdjointCS = 0.;
|
||||
if(aCouple != fCurrentCouple || fCurrenteEnergy != electronEnergy)
|
||||
{
|
||||
fTotAdjointCS = 0.;
|
||||
DefineCurrentMaterialAndElectronEnergy(aCouple, electronEnergy);
|
||||
const G4ElementVector* theElementVector =
|
||||
fCurrentMaterial->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector =
|
||||
fCurrentMaterial->GetVecNbOfAtomsPerVolume();
|
||||
size_t nelm = fCurrentMaterial->GetNumberOfElements();
|
||||
for(fIndexElement = 0; fIndexElement < nelm; ++fIndexElement)
|
||||
{
|
||||
fTotAdjointCS += AdjointCrossSectionPerAtom(
|
||||
(*theElementVector)[fIndexElement], electronEnergy) *
|
||||
theAtomNumDensityVector[fIndexElement];
|
||||
fXsec[fIndexElement] = fTotAdjointCS;
|
||||
}
|
||||
|
||||
totBiasedAdjointCS = std::min(fTotAdjointCS, 0.01);
|
||||
fFactorCSBiasing = totBiasedAdjointCS / fTotAdjointCS;
|
||||
}
|
||||
return totBiasedAdjointCS;
|
||||
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
G4double G4AdjointPhotoElectricModel::GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double electronEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{ return AdjointCrossSection(aCouple,electronEnergy,IsScatProjToProjCase);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
G4double G4AdjointPhotoElectricModel::AdjointCrossSectionPerAtom(const G4Element* anElement,G4double electronEnergy)
|
||||
{
|
||||
G4int nShells = anElement->GetNbOfAtomicShells();
|
||||
G4double Z= anElement->GetZ();
|
||||
G4int i = 0;
|
||||
G4double B0=anElement->GetAtomicShell(0);
|
||||
G4double gammaEnergy = electronEnergy+B0;
|
||||
G4double CS= theDirectPEEffectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),gammaEnergy,Z,0.,0.,0.);
|
||||
G4double adjointCS =0.;
|
||||
if (CS >0) adjointCS += CS/gammaEnergy;
|
||||
shell_prob[index_element][0] = adjointCS;
|
||||
for (i=1;i<nShells;i++){
|
||||
//G4cout<<i<<G4endl;
|
||||
G4double Bi_= anElement->GetAtomicShell(i-1);
|
||||
G4double Bi = anElement->GetAtomicShell(i);
|
||||
//G4cout<<Bi_<<'\t'<<Bi<<G4endl;
|
||||
if (electronEnergy <Bi_-Bi) {
|
||||
gammaEnergy = electronEnergy+Bi;
|
||||
|
||||
CS=theDirectPEEffectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),gammaEnergy,Z,0.,0.,0.);
|
||||
if (CS>0) adjointCS +=CS/gammaEnergy;
|
||||
}
|
||||
shell_prob[index_element][i] = adjointCS;
|
||||
|
||||
G4double G4AdjointPhotoElectricModel::AdjointCrossSectionPerAtom(
|
||||
const G4Element* anElement, G4double electronEnergy)
|
||||
{
|
||||
G4int nShells = anElement->GetNbOfAtomicShells();
|
||||
G4double Z = anElement->GetZ();
|
||||
G4double gammaEnergy = electronEnergy + anElement->GetAtomicShell(0);
|
||||
G4double CS = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
G4Gamma::Gamma(), gammaEnergy, Z, 0., 0., 0.);
|
||||
G4double adjointCS = 0.;
|
||||
if(CS > 0.)
|
||||
adjointCS += CS / gammaEnergy;
|
||||
fShellProb[fIndexElement][0] = adjointCS;
|
||||
for(G4int i = 1; i < nShells; ++i)
|
||||
{
|
||||
G4double Bi1 = anElement->GetAtomicShell(i - 1);
|
||||
G4double Bi = anElement->GetAtomicShell(i);
|
||||
if(electronEnergy < Bi1 - Bi)
|
||||
{
|
||||
gammaEnergy = electronEnergy + Bi;
|
||||
CS = fDirectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),
|
||||
gammaEnergy, Z, 0., 0., 0.);
|
||||
if(CS > 0.)
|
||||
adjointCS += CS / gammaEnergy;
|
||||
}
|
||||
fShellProb[fIndexElement][i] = adjointCS;
|
||||
}
|
||||
adjointCS*=electronEnergy;
|
||||
adjointCS *= electronEnergy;
|
||||
return adjointCS;
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void G4AdjointPhotoElectricModel::DefineCurrentMaterialAndElectronEnergy(const G4MaterialCutsCouple* couple, G4double anEnergy)
|
||||
{ currentCouple = const_cast<G4MaterialCutsCouple*> (couple);
|
||||
currentMaterial = const_cast<G4Material*> (couple->GetMaterial());
|
||||
currentCoupleIndex = couple->GetIndex();
|
||||
currentMaterialIndex = currentMaterial->GetIndex();
|
||||
current_eEnergy = anEnergy;
|
||||
theDirectPEEffectModel->SetCurrentCouple(couple);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointPhotoElectricModel::DefineCurrentMaterialAndElectronEnergy(
|
||||
const G4MaterialCutsCouple* couple, G4double anEnergy)
|
||||
{
|
||||
fCurrentCouple = const_cast<G4MaterialCutsCouple*>(couple);
|
||||
fCurrentMaterial = const_cast<G4Material*>(couple->GetMaterial());
|
||||
fCurrenteEnergy = anEnergy;
|
||||
fDirectModel->SetCurrentCouple(couple);
|
||||
}
|
||||
|
||||
+170
-218
@@ -23,297 +23,249 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// Class Description
|
||||
//
|
||||
// This class is for adjoint process equivalent to direct process
|
||||
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// Created by L.Desorgher 25 Sept. 2009 Inspired from G4WrapperProcess
|
||||
// Created by L.Desorgher 25 Sept. 2009
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#include "G4AdjointProcessEquivalentToDirectProcess.hh"
|
||||
|
||||
#include "G4DynamicParticle.hh"
|
||||
G4AdjointProcessEquivalentToDirectProcess::G4AdjointProcessEquivalentToDirectProcess(const G4String& aName,
|
||||
G4VProcess* aProcess,
|
||||
G4ParticleDefinition* fwd_particle_def)
|
||||
:G4VProcess(aName)
|
||||
{
|
||||
theDirectProcess =aProcess;
|
||||
theProcessType = theDirectProcess->GetProcessType();
|
||||
theFwdParticleDef = fwd_particle_def;
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VProcess.hh"
|
||||
|
||||
G4AdjointProcessEquivalentToDirectProcess::
|
||||
G4AdjointProcessEquivalentToDirectProcess(
|
||||
const G4String& aName, G4VProcess* aProcess,
|
||||
G4ParticleDefinition* fwd_particle_def)
|
||||
: G4VProcess(aName)
|
||||
{
|
||||
fDirectProcess = aProcess;
|
||||
theProcessType = fDirectProcess->GetProcessType();
|
||||
fFwdParticleDef = fwd_particle_def;
|
||||
}
|
||||
|
||||
|
||||
G4AdjointProcessEquivalentToDirectProcess::~G4AdjointProcessEquivalentToDirectProcess()
|
||||
G4AdjointProcessEquivalentToDirectProcess::
|
||||
~G4AdjointProcessEquivalentToDirectProcess()
|
||||
{
|
||||
if (theDirectProcess!=0) delete theDirectProcess;
|
||||
if(fDirectProcess != nullptr)
|
||||
delete fDirectProcess;
|
||||
}
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::ResetNumberOfInteractionLengthLeft()
|
||||
void G4AdjointProcessEquivalentToDirectProcess::
|
||||
ResetNumberOfInteractionLengthLeft()
|
||||
{
|
||||
theDirectProcess->ResetNumberOfInteractionLengthLeft();
|
||||
fDirectProcess->ResetNumberOfInteractionLengthLeft();
|
||||
}
|
||||
|
||||
G4double G4AdjointProcessEquivalentToDirectProcess::
|
||||
AlongStepGetPhysicalInteractionLength( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& proposedSafety,
|
||||
G4GPILSelection* selection )
|
||||
{
|
||||
|
||||
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
AlongStepGetPhysicalInteractionLength(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& proposedSafety,
|
||||
G4GPILSelection* selection)
|
||||
{
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
G4double GPIL = theDirectProcess->
|
||||
AlongStepGetPhysicalInteractionLength( track,
|
||||
previousStepSize,
|
||||
currentMinimumStep,
|
||||
proposedSafety,
|
||||
selection );
|
||||
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4double GPIL = fDirectProcess->AlongStepGetPhysicalInteractionLength(
|
||||
track, previousStepSize, currentMinimumStep, proposedSafety, selection);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
|
||||
|
||||
return GPIL;
|
||||
|
||||
}
|
||||
|
||||
G4double G4AdjointProcessEquivalentToDirectProcess::
|
||||
AtRestGetPhysicalInteractionLength( const G4Track& track,
|
||||
G4ForceCondition* condition )
|
||||
{ //Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
G4double
|
||||
G4AdjointProcessEquivalentToDirectProcess::AtRestGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4ForceCondition* condition)
|
||||
{
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
|
||||
|
||||
G4double GPIL = theDirectProcess->AtRestGetPhysicalInteractionLength( track, condition );
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4double GPIL =
|
||||
fDirectProcess->AtRestGetPhysicalInteractionLength(track, condition);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
|
||||
return GPIL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
G4double G4AdjointProcessEquivalentToDirectProcess::
|
||||
PostStepGetPhysicalInteractionLength( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition )
|
||||
G4double
|
||||
G4AdjointProcessEquivalentToDirectProcess::PostStepGetPhysicalInteractionLength(
|
||||
const G4Track& track, G4double previousStepSize, G4ForceCondition* condition)
|
||||
{
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
|
||||
|
||||
G4double GPIL = theDirectProcess->PostStepGetPhysicalInteractionLength( track,
|
||||
previousStepSize,
|
||||
condition );
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4double GPIL = fDirectProcess->PostStepGetPhysicalInteractionLength(
|
||||
track, previousStepSize, condition);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
return GPIL;
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::SetProcessManager(const G4ProcessManager* procMan)
|
||||
{
|
||||
theDirectProcess->SetProcessManager(procMan);
|
||||
|
||||
return GPIL;
|
||||
}
|
||||
|
||||
const G4ProcessManager* G4AdjointProcessEquivalentToDirectProcess::GetProcessManager()
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::PostStepDoIt(
|
||||
const G4Track& track, const G4Step& stepData)
|
||||
{
|
||||
return theDirectProcess->GetProcessManager();
|
||||
}
|
||||
*/
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::PostStepDoIt( const G4Track& track,
|
||||
const G4Step& stepData )
|
||||
{
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
|
||||
G4VParticleChange* partChange = theDirectProcess->PostStepDoIt( track, stepData );
|
||||
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4VParticleChange* partChange = fDirectProcess->PostStepDoIt(track, stepData);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
|
||||
return partChange;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::AlongStepDoIt( const G4Track& track,
|
||||
const G4Step& stepData )
|
||||
{
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::AlongStepDoIt(
|
||||
const G4Track& track, const G4Step& stepData)
|
||||
{
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
G4VParticleChange* partChange =theDirectProcess->AlongStepDoIt( track, stepData );
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4VParticleChange* partChange =
|
||||
fDirectProcess->AlongStepDoIt(track, stepData);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
return partChange;
|
||||
|
||||
return partChange;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::AtRestDoIt( const G4Track& track,
|
||||
const G4Step& stepData )
|
||||
|
||||
G4VParticleChange* G4AdjointProcessEquivalentToDirectProcess::AtRestDoIt(
|
||||
const G4Track& track, const G4Step& stepData)
|
||||
{
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track.GetDynamicParticle());
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
|
||||
//Call the direct process
|
||||
//----------------------
|
||||
G4VParticleChange* partChange =theDirectProcess->AtRestDoIt( track, stepData );
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
// Call the direct process
|
||||
G4VParticleChange* partChange = fDirectProcess->AtRestDoIt(track, stepData);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
return partChange;
|
||||
|
||||
|
||||
|
||||
return partChange;
|
||||
}
|
||||
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::IsApplicable(const G4ParticleDefinition&)
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::IsApplicable(
|
||||
const G4ParticleDefinition&)
|
||||
{
|
||||
return theDirectProcess->IsApplicable(*theFwdParticleDef);
|
||||
return fDirectProcess->IsApplicable(*fFwdParticleDef);
|
||||
}
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::BuildPhysicsTable(const G4ParticleDefinition& )
|
||||
void G4AdjointProcessEquivalentToDirectProcess::BuildPhysicsTable(
|
||||
const G4ParticleDefinition&)
|
||||
{
|
||||
return theDirectProcess->BuildPhysicsTable(*theFwdParticleDef);
|
||||
return fDirectProcess->BuildPhysicsTable(*fFwdParticleDef);
|
||||
}
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::PreparePhysicsTable(const G4ParticleDefinition& )
|
||||
void G4AdjointProcessEquivalentToDirectProcess::PreparePhysicsTable(
|
||||
const G4ParticleDefinition&)
|
||||
{
|
||||
return theDirectProcess->PreparePhysicsTable(*theFwdParticleDef);
|
||||
return fDirectProcess->PreparePhysicsTable(*fFwdParticleDef);
|
||||
}
|
||||
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::
|
||||
StorePhysicsTable(const G4ParticleDefinition* ,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::StorePhysicsTable(
|
||||
const G4ParticleDefinition*, const G4String& directory, G4bool ascii)
|
||||
{
|
||||
return theDirectProcess->StorePhysicsTable(theFwdParticleDef, directory, ascii);
|
||||
}
|
||||
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::
|
||||
RetrievePhysicsTable( const G4ParticleDefinition* ,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
return fDirectProcess->StorePhysicsTable(fFwdParticleDef, directory, ascii);
|
||||
}
|
||||
|
||||
G4bool G4AdjointProcessEquivalentToDirectProcess::RetrievePhysicsTable(
|
||||
const G4ParticleDefinition*, const G4String& directory, G4bool ascii)
|
||||
{
|
||||
return theDirectProcess->RetrievePhysicsTable(theFwdParticleDef, directory, ascii);
|
||||
}
|
||||
return fDirectProcess->RetrievePhysicsTable(fFwdParticleDef, directory,
|
||||
ascii);
|
||||
}
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::StartTracking(G4Track* track)
|
||||
{
|
||||
//Change the particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
G4DynamicParticle* theDynPart = const_cast<G4DynamicParticle*> (track->GetDynamicParticle());
|
||||
// Change the particle definition to the direct one
|
||||
G4DynamicParticle* theDynPart =
|
||||
const_cast<G4DynamicParticle*>(track->GetDynamicParticle());
|
||||
G4ParticleDefinition* adjPartDef = theDynPart->GetDefinition();
|
||||
|
||||
G4DecayProducts* decayProducts = const_cast<G4DecayProducts*> (theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*)(0));
|
||||
theDynPart->SetDefinition(theFwdParticleDef);
|
||||
|
||||
theDirectProcess->StartTracking(track);
|
||||
|
||||
//Restore the adjoint particle definition to the direct one
|
||||
//------------------------------------------------
|
||||
|
||||
G4DecayProducts* decayProducts =
|
||||
const_cast<G4DecayProducts*>(theDynPart->GetPreAssignedDecayProducts());
|
||||
theDynPart->SetPreAssignedDecayProducts((G4DecayProducts*) (0));
|
||||
theDynPart->SetDefinition(fFwdParticleDef);
|
||||
|
||||
fDirectProcess->StartTracking(track);
|
||||
|
||||
// Restore the adjoint particle definition to the direct one
|
||||
theDynPart->SetDefinition(adjPartDef);
|
||||
theDynPart->SetPreAssignedDecayProducts(decayProducts);
|
||||
|
||||
|
||||
return;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void G4AdjointProcessEquivalentToDirectProcess::EndTracking()
|
||||
{
|
||||
theDirectProcess->EndTracking();
|
||||
fDirectProcess->EndTracking();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,193 +23,175 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointeIonisationModel.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4AdjointGamma.hh"
|
||||
|
||||
#include "G4Electron.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointeIonisationModel::G4AdjointeIonisationModel():
|
||||
G4VEmAdjointModel("Inv_eIon_model")
|
||||
G4AdjointeIonisationModel::G4AdjointeIonisationModel()
|
||||
: G4VEmAdjointModel("Inv_eIon_model")
|
||||
|
||||
{
|
||||
|
||||
UseMatrix =true;
|
||||
UseMatrixPerElement = true;
|
||||
ApplyCutInRange = true;
|
||||
UseOnlyOneMatrixForAllElements = true;
|
||||
CS_biasing_factor =1.;
|
||||
WithRapidSampling = false;
|
||||
|
||||
theAdjEquivOfDirectPrimPartDef =G4AdjointElectron::AdjointElectron();
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron();
|
||||
theDirectPrimaryPartDef=G4Electron::Electron();
|
||||
second_part_of_same_type=true;
|
||||
fUseMatrix = true;
|
||||
fUseMatrixPerElement = true;
|
||||
fApplyCutInRange = true;
|
||||
fOneMatrixForAllElements = true;
|
||||
|
||||
fAdjEquivDirectPrimPart = G4AdjointElectron::AdjointElectron();
|
||||
fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
|
||||
fDirectPrimaryPart = G4Electron::Electron();
|
||||
fSecondPartSameType = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointeIonisationModel::~G4AdjointeIonisationModel()
|
||||
{;}
|
||||
G4AdjointeIonisationModel::~G4AdjointeIonisationModel() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointeIonisationModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
void G4AdjointeIonisationModel::SampleSecondaries(
|
||||
const G4Track& aTrack, G4bool IsScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
|
||||
// Elastic inverse scattering
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP = theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
|
||||
//Elastic inverse scattering
|
||||
//---------------------------------------------------------
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP =theAdjointPrimary->GetTotalMomentum();
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
//Sample secondary energy
|
||||
//-----------------------
|
||||
G4double projectileKinEnergy;
|
||||
if (!WithRapidSampling ) { //used by default
|
||||
projectileKinEnergy = SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, IsScatProjToProjCase);
|
||||
|
||||
CorrectPostStepWeight(fParticleChange,
|
||||
aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy,
|
||||
projectileKinEnergy,
|
||||
IsScatProjToProjCase); //Caution !!!this weight correction should be always applied
|
||||
}
|
||||
else { //only for test at the moment
|
||||
|
||||
G4double Emin,Emax;
|
||||
if (IsScatProjToProjCase) {
|
||||
Emin=GetSecondAdjEnergyMinForScatProjToProjCase(adjointPrimKinEnergy,currentTcutForDirectSecond);
|
||||
Emax=GetSecondAdjEnergyMaxForScatProjToProjCase(adjointPrimKinEnergy);
|
||||
}
|
||||
else {
|
||||
Emin=GetSecondAdjEnergyMinForProdToProjCase(adjointPrimKinEnergy);
|
||||
Emax=GetSecondAdjEnergyMaxForProdToProjCase(adjointPrimKinEnergy);
|
||||
}
|
||||
projectileKinEnergy = Emin*std::pow(Emax/Emin,G4UniformRand());
|
||||
|
||||
|
||||
|
||||
lastCS=lastAdjointCSForScatProjToProjCase;
|
||||
if ( !IsScatProjToProjCase) lastCS=lastAdjointCSForProdToProjCase;
|
||||
|
||||
G4double new_weight=aTrack.GetWeight();
|
||||
G4double used_diffCS=lastCS*std::log(Emax/Emin)/projectileKinEnergy;
|
||||
G4double needed_diffCS=adjointPrimKinEnergy/projectileKinEnergy;
|
||||
if (!IsScatProjToProjCase) needed_diffCS *=DiffCrossSectionPerVolumePrimToSecond(currentMaterial,projectileKinEnergy,adjointPrimKinEnergy);
|
||||
else needed_diffCS *=DiffCrossSectionPerVolumePrimToScatPrim(currentMaterial,projectileKinEnergy,adjointPrimKinEnergy);
|
||||
new_weight*=needed_diffCS/used_diffCS;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Kinematic:
|
||||
//we consider a two body elastic scattering for the forward processes where the projectile knock on an e- at rest and gives
|
||||
// him part of its energy
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
|
||||
|
||||
|
||||
//Companion
|
||||
//-----------
|
||||
G4double companionM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
if (IsScatProjToProjCase) {
|
||||
companionM0=theAdjEquivOfDirectSecondPartDef->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =companionM0+ projectileKinEnergy-adjointPrimKinEnergy;
|
||||
G4double companionP2 = companionTotalEnergy*companionTotalEnergy - companionM0*companionM0;
|
||||
|
||||
|
||||
//Projectile momentum
|
||||
//--------------------
|
||||
G4double P_parallel = (adjointPrimP*adjointPrimP + projectileP2 - companionP2)/(2.*adjointPrimP);
|
||||
G4double P_perp = std::sqrt( projectileP2 - P_parallel*P_parallel);
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector projectileMomentum = G4ThreeVector(P_perp*std::cos(phi),P_perp*std::sin(phi),P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
//G4cout<<"projectileMomentum "<<projectileMomentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
|
||||
// Sample secondary energy
|
||||
G4double projectileKinEnergy;
|
||||
if(!fWithRapidSampling)
|
||||
{ // used by default
|
||||
projectileKinEnergy =
|
||||
SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, IsScatProjToProj);
|
||||
|
||||
|
||||
// Caution!!! this weight correction should be always applied
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy, projectileKinEnergy,
|
||||
IsScatProjToProj);
|
||||
}
|
||||
else
|
||||
{ // only for testing
|
||||
G4double Emin, Emax;
|
||||
if(IsScatProjToProj)
|
||||
{
|
||||
Emin = GetSecondAdjEnergyMinForScatProjToProj(adjointPrimKinEnergy,
|
||||
fTcutSecond);
|
||||
Emax = GetSecondAdjEnergyMaxForScatProjToProj(adjointPrimKinEnergy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Emin = GetSecondAdjEnergyMinForProdToProj(adjointPrimKinEnergy);
|
||||
Emax = GetSecondAdjEnergyMaxForProdToProj(adjointPrimKinEnergy);
|
||||
}
|
||||
projectileKinEnergy = Emin * std::pow(Emax / Emin, G4UniformRand());
|
||||
|
||||
fLastCS = fLastAdjointCSForScatProjToProj;
|
||||
if(!IsScatProjToProj)
|
||||
fLastCS = fLastAdjointCSForProdToProj;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight();
|
||||
G4double used_diffCS =
|
||||
fLastCS * std::log(Emax / Emin) / projectileKinEnergy;
|
||||
G4double needed_diffCS = adjointPrimKinEnergy / projectileKinEnergy;
|
||||
if(!IsScatProjToProj)
|
||||
needed_diffCS *= DiffCrossSectionPerVolumePrimToSecond(
|
||||
fCurrentMaterial, projectileKinEnergy, adjointPrimKinEnergy);
|
||||
else
|
||||
needed_diffCS *= DiffCrossSectionPerVolumePrimToScatPrim(
|
||||
fCurrentMaterial, projectileKinEnergy, adjointPrimKinEnergy);
|
||||
new_weight *= needed_diffCS / used_diffCS;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
}
|
||||
|
||||
// Kinematic:
|
||||
// we consider a two body elastic scattering for the forward processes where
|
||||
// the projectile knock on an e- at rest and gives it part of its energy
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
|
||||
// Companion
|
||||
G4double companionM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
if(IsScatProjToProj)
|
||||
{
|
||||
companionM0 = fAdjEquivDirectSecondPart->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =
|
||||
companionM0 + projectileKinEnergy - adjointPrimKinEnergy;
|
||||
G4double companionP2 =
|
||||
companionTotalEnergy * companionTotalEnergy - companionM0 * companionM0;
|
||||
|
||||
// Projectile momentum
|
||||
G4double P_parallel =
|
||||
(adjointPrimP * adjointPrimP + projectileP2 - companionP2) /
|
||||
(2. * adjointPrimP);
|
||||
G4double P_perp = std::sqrt(projectileP2 - P_parallel * P_parallel);
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector projectileMomentum =
|
||||
G4ThreeVector(P_perp * std::cos(phi), P_perp * std::sin(phi), P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
if(!IsScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//The implementation here is correct for energy loss process, for the photoelectric and compton scattering the method should be redefine
|
||||
// The implementation here is correct for energy loss process, for the
|
||||
// photoelectric and compton scattering the method should be redefined
|
||||
G4double G4AdjointeIonisationModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj,
|
||||
G4double kinEnergyProd,
|
||||
G4double Z,
|
||||
G4double )
|
||||
G4double kinEnergyProj, G4double kinEnergyProd, G4double Z, G4double)
|
||||
{
|
||||
G4double dSigmadEprod=0;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(kinEnergyProd);
|
||||
|
||||
|
||||
if (kinEnergyProj>Emin_proj && kinEnergyProj<=Emax_proj){ //the produced particle should have a kinetic energy smaller than the projectile
|
||||
dSigmadEprod=Z*DiffCrossSectionMoller(kinEnergyProj,kinEnergyProd);
|
||||
}
|
||||
return dSigmadEprod;
|
||||
|
||||
|
||||
|
||||
G4double dSigmadEprod = 0.;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(kinEnergyProd);
|
||||
|
||||
// the produced particle should have a kinetic energy smaller than the
|
||||
// projectile
|
||||
if(kinEnergyProj > Emin_proj && kinEnergyProj <= Emax_proj)
|
||||
{
|
||||
dSigmadEprod = Z * DiffCrossSectionMoller(kinEnergyProj, kinEnergyProd);
|
||||
}
|
||||
return dSigmadEprod;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointeIonisationModel::DiffCrossSectionMoller(G4double kinEnergyProj,G4double kinEnergyProd){
|
||||
|
||||
G4double energy = kinEnergyProj + electron_mass_c2;
|
||||
G4double x = kinEnergyProd/kinEnergyProj;
|
||||
G4double gam = energy/electron_mass_c2;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double beta2 = 1.0 - 1.0/gamma2;
|
||||
|
||||
G4double gg = (2.0*gam - 1.0)/gamma2;
|
||||
G4double y = 1.0 - x;
|
||||
G4double fac=twopi_mc2_rcl2/electron_mass_c2;
|
||||
G4double dCS = fac*( 1.-gg + ((1.0 - gg*x)/(x*x))
|
||||
+ ((1.0 - gg*y)/(y*y)))/(beta2*(gam-1));
|
||||
return dCS/kinEnergyProj;
|
||||
|
||||
|
||||
|
||||
}
|
||||
G4double G4AdjointeIonisationModel::DiffCrossSectionMoller(
|
||||
G4double kinEnergyProj, G4double kinEnergyProd)
|
||||
{
|
||||
// G4double energy = kinEnergyProj + electron_mass_c2;
|
||||
G4double x = kinEnergyProd / kinEnergyProj;
|
||||
G4double gam = (kinEnergyProj + electron_mass_c2) / electron_mass_c2;
|
||||
G4double gamma2 = gam * gam;
|
||||
G4double beta2 = 1.0 - 1.0 / gamma2;
|
||||
|
||||
G4double gg = (2.0 * gam - 1.0) / gamma2;
|
||||
G4double y = 1.0 - x;
|
||||
G4double fac = twopi_mc2_rcl2 / electron_mass_c2;
|
||||
G4double dCS =
|
||||
fac * (1. - gg + ((1.0 - gg * x) / (x * x)) + ((1.0 - gg * y) / (y * y))) /
|
||||
(beta2 * (gam - 1.));
|
||||
return dCS / kinEnergyProj;
|
||||
}
|
||||
|
||||
@@ -23,476 +23,444 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4AdjointhIonisationModel.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4AdjointProton.hh"
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
#include "G4BetheBlochModel.hh"
|
||||
#include "G4BraggModel.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4NistManager.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4TrackStatus.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointhIonisationModel::G4AdjointhIonisationModel(G4ParticleDefinition* projectileDefinition):
|
||||
G4VEmAdjointModel("Adjoint_hIonisation")
|
||||
{
|
||||
G4AdjointhIonisationModel::G4AdjointhIonisationModel(G4ParticleDefinition* pDef)
|
||||
: G4VEmAdjointModel("Adjoint_hIonisation")
|
||||
{
|
||||
fUseMatrix = true;
|
||||
fUseMatrixPerElement = true;
|
||||
fApplyCutInRange = true;
|
||||
fOneMatrixForAllElements = true;
|
||||
fSecondPartSameType = false;
|
||||
|
||||
// The direct EM Model is taken as BetheBloch. It is only used for the
|
||||
// computation of the differential cross section.
|
||||
// The Bragg model could be used as an alternative as it offers the same
|
||||
// differential cross section
|
||||
|
||||
fDirectModel = new G4BetheBlochModel(pDef);
|
||||
fBraggDirectEMModel = new G4BraggModel(pDef);
|
||||
fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
|
||||
fDirectPrimaryPart = pDef;
|
||||
|
||||
UseMatrix =true;
|
||||
UseMatrixPerElement = true;
|
||||
ApplyCutInRange = true;
|
||||
UseOnlyOneMatrixForAllElements = true;
|
||||
CS_biasing_factor =1.;
|
||||
second_part_of_same_type =false;
|
||||
|
||||
//The direct EM Modfel is taken has BetheBloch it is only used for the computation
|
||||
// of the differential cross section.
|
||||
//The Bragg model could be used as an alternative as it offers the same differential cross section
|
||||
|
||||
theDirectEMModel = new G4BetheBlochModel(projectileDefinition);
|
||||
theBraggDirectEMModel = new G4BraggModel(projectileDefinition);
|
||||
theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron();
|
||||
|
||||
theDirectPrimaryPartDef = projectileDefinition;
|
||||
theAdjEquivOfDirectPrimPartDef = 0;
|
||||
if (projectileDefinition == G4Proton::Proton()) {
|
||||
theAdjEquivOfDirectPrimPartDef = G4AdjointProton::AdjointProton();
|
||||
|
||||
if(pDef == G4Proton::Proton())
|
||||
{
|
||||
fAdjEquivDirectPrimPart = G4AdjointProton::AdjointProton();
|
||||
}
|
||||
|
||||
|
||||
DefineProjectileProperty();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointhIonisationModel::~G4AdjointhIonisationModel()
|
||||
{;}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointhIonisationModel::SampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
if (!UseMatrix) return RapidSampleSecondaries(aTrack,IsScatProjToProjCase,fParticleChange);
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
|
||||
//Elastic inverse scattering
|
||||
//---------------------------------------------------------
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP =theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
//Sample secondary energy
|
||||
//-----------------------
|
||||
G4double projectileKinEnergy = SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, IsScatProjToProjCase);
|
||||
CorrectPostStepWeight(fParticleChange,
|
||||
aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy,
|
||||
projectileKinEnergy,
|
||||
IsScatProjToProjCase); //Caution !!!this weight correction should be always applied
|
||||
|
||||
|
||||
//Kinematic:
|
||||
//we consider a two body elastic scattering for the forward processes where the projectile knock on an e- at rest and gives
|
||||
// him part of its energy
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
|
||||
|
||||
|
||||
//Companion
|
||||
//-----------
|
||||
G4double companionM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
if (IsScatProjToProjCase) {
|
||||
companionM0=theAdjEquivOfDirectSecondPartDef->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =companionM0+ projectileKinEnergy-adjointPrimKinEnergy;
|
||||
G4double companionP2 = companionTotalEnergy*companionTotalEnergy - companionM0*companionM0;
|
||||
|
||||
|
||||
//Projectile momentum
|
||||
//--------------------
|
||||
G4double P_parallel = (adjointPrimP*adjointPrimP + projectileP2 - companionP2)/(2.*adjointPrimP);
|
||||
G4double P_perp = std::sqrt( projectileP2 - P_parallel*P_parallel);
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector projectileMomentum = G4ThreeVector(P_perp*std::cos(phi),P_perp*std::sin(phi),P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
//G4cout<<"projectileMomentum "<<projectileMomentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
G4AdjointhIonisationModel::~G4AdjointhIonisationModel() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointhIonisationModel::RapidSampleSecondaries(const G4Track& aTrack,
|
||||
G4bool IsScatProjToProjCase,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
void G4AdjointhIonisationModel::SampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
if(!fUseMatrix)
|
||||
return RapidSampleSecondaries(aTrack, isScatProjToProj, fParticleChange);
|
||||
|
||||
const G4DynamicParticle* theAdjointPrimary =aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP =theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
if (adjointPrimKinEnergy>HighEnergyLimit*0.999){
|
||||
return;
|
||||
}
|
||||
|
||||
G4double projectileKinEnergy =0.;
|
||||
G4double eEnergy=0.;
|
||||
G4double newCS=currentMaterial->GetElectronDensity()*twopi_mc2_rcl2*mass;
|
||||
if (!IsScatProjToProjCase){//1/E^2 distribution
|
||||
|
||||
eEnergy=adjointPrimKinEnergy;
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin= GetSecondAdjEnergyMinForProdToProjCase(adjointPrimKinEnergy);
|
||||
if (Emin>=Emax) return;
|
||||
G4double a=1./Emax;
|
||||
G4double b=1./Emin;
|
||||
newCS=newCS*(b-a)/eEnergy;
|
||||
|
||||
projectileKinEnergy =1./(b- (b-a)*G4UniformRand());
|
||||
|
||||
|
||||
}
|
||||
else { G4double Emax = GetSecondAdjEnergyMaxForScatProjToProjCase(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForScatProjToProjCase(adjointPrimKinEnergy,currentTcutForDirectSecond);
|
||||
if (Emin>=Emax) return;
|
||||
G4double diff1=Emin-adjointPrimKinEnergy;
|
||||
G4double diff2=Emax-adjointPrimKinEnergy;
|
||||
|
||||
G4double t1=adjointPrimKinEnergy*(1./diff1-1./diff2);
|
||||
G4double t2=adjointPrimKinEnergy*(1./Emin-1./Emax);
|
||||
/*G4double f31=diff1/Emin;
|
||||
G4double f32=diff2/Emax/f31;*/
|
||||
G4double t3=2.*std::log(Emax/Emin);
|
||||
G4double sum_t=t1+t2+t3;
|
||||
newCS=newCS*sum_t/adjointPrimKinEnergy/adjointPrimKinEnergy;
|
||||
G4double t=G4UniformRand()*sum_t;
|
||||
if (t <=t1 ){
|
||||
G4double q= G4UniformRand()*t1/adjointPrimKinEnergy ;
|
||||
projectileKinEnergy =adjointPrimKinEnergy +1./(1./diff1-q);
|
||||
|
||||
}
|
||||
else if (t <=t2 ) {
|
||||
G4double q= G4UniformRand()*t2/adjointPrimKinEnergy;
|
||||
projectileKinEnergy =1./(1./Emin-q);
|
||||
}
|
||||
else {
|
||||
projectileKinEnergy=Emin*std::pow(Emax/Emin,G4UniformRand());
|
||||
|
||||
}
|
||||
eEnergy=projectileKinEnergy-adjointPrimKinEnergy;
|
||||
|
||||
|
||||
}
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
|
||||
|
||||
// Elastic inverse scattering
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP = theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
G4double diffCS_perAtom_Used=twopi_mc2_rcl2*mass*adjointPrimKinEnergy/projectileKinEnergy/projectileKinEnergy/eEnergy/eEnergy;
|
||||
|
||||
|
||||
|
||||
//Weight correction
|
||||
//-----------------------
|
||||
//First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
G4double w_corr=G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
|
||||
//G4cout<<w_corr<<G4endl;
|
||||
w_corr*=newCS/lastCS;
|
||||
//G4cout<<w_corr<<G4endl;
|
||||
//Then another correction is needed due to the fact that a biaised differential CS has been used rather than the one consistent with the direct model
|
||||
//Here we consider the true diffCS as the one obtained by the numerical differentiation over Tcut of the direct CS
|
||||
|
||||
G4double diffCS = DiffCrossSectionPerAtomPrimToSecond(projectileKinEnergy, eEnergy,1,1);
|
||||
w_corr*=diffCS/diffCS_perAtom_Used;
|
||||
//G4cout<<w_corr<<G4endl;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight()*w_corr;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
|
||||
|
||||
|
||||
//Kinematic:
|
||||
//we consider a two body elastic scattering for the forward processes where the projectile knock on an e- at rest and gives
|
||||
// him part of its energy
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
G4double projectileM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0+projectileKinEnergy;
|
||||
G4double projectileP2 = projectileTotalEnergy*projectileTotalEnergy - projectileM0*projectileM0;
|
||||
|
||||
|
||||
|
||||
//Companion
|
||||
//-----------
|
||||
G4double companionM0 = theAdjEquivOfDirectPrimPartDef->GetPDGMass();
|
||||
if (IsScatProjToProjCase) {
|
||||
companionM0=theAdjEquivOfDirectSecondPartDef->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =companionM0+ projectileKinEnergy-adjointPrimKinEnergy;
|
||||
G4double companionP2 = companionTotalEnergy*companionTotalEnergy - companionM0*companionM0;
|
||||
|
||||
|
||||
//Projectile momentum
|
||||
//--------------------
|
||||
G4double P_parallel = (adjointPrimP*adjointPrimP + projectileP2 - companionP2)/(2.*adjointPrimP);
|
||||
G4double P_perp = std::sqrt( projectileP2 - P_parallel*P_parallel);
|
||||
G4ThreeVector dir_parallel=theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi =G4UniformRand()*2.*3.1415926;
|
||||
G4ThreeVector projectileMomentum = G4ThreeVector(P_perp*std::cos(phi),P_perp*std::sin(phi),P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
|
||||
|
||||
if (!IsScatProjToProjCase ){ //kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(new G4DynamicParticle(theAdjEquivOfDirectPrimPartDef,projectileMomentum));
|
||||
//G4cout<<"projectileMomentum "<<projectileMomentum<<G4endl;
|
||||
}
|
||||
else {
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj,
|
||||
G4double kinEnergyProd,
|
||||
G4double Z,
|
||||
G4double A)
|
||||
{//Probably that here the Bragg Model should be also used for kinEnergyProj/nuc<2MeV
|
||||
|
||||
|
||||
|
||||
G4double dSigmadEprod=0;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(kinEnergyProd);
|
||||
|
||||
|
||||
if (kinEnergyProj>Emin_proj && kinEnergyProj<=Emax_proj){ //the produced particle should have a kinetic energy smaller than the projectile
|
||||
G4double Tmax=kinEnergyProj;
|
||||
|
||||
G4double E1=kinEnergyProd;
|
||||
G4double E2=kinEnergyProd*1.000001;
|
||||
G4double dE=(E2-E1);
|
||||
G4double sigma1,sigma2;
|
||||
if (kinEnergyProj >2.*MeV){
|
||||
sigma1=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E1,1.e20);
|
||||
sigma2=theDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E2,1.e20);
|
||||
}
|
||||
else {
|
||||
sigma1=theBraggDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E1,1.e20);
|
||||
sigma2=theBraggDirectEMModel->ComputeCrossSectionPerAtom(theDirectPrimaryPartDef,kinEnergyProj,Z,A ,E2,1.e20);
|
||||
}
|
||||
|
||||
|
||||
dSigmadEprod=(sigma1-sigma2)/dE;
|
||||
if (dSigmadEprod>1.) {
|
||||
G4cout<<"sigma1 "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<sigma1<<G4endl;
|
||||
G4cout<<"sigma2 "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<sigma2<<G4endl;
|
||||
G4cout<<"dsigma "<<kinEnergyProj/MeV<<'\t'<<kinEnergyProd/MeV<<'\t'<<dSigmadEprod<<G4endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//correction of differential cross section at high energy to correct for the suppression of particle at secondary at high
|
||||
//energy used in the Bethe Bloch Model. This correction consist to multiply by g the probability function used
|
||||
//to test the rejection of a secondary
|
||||
//-------------------------
|
||||
|
||||
//Source code taken from G4BetheBlochModel::SampleSecondaries
|
||||
|
||||
G4double deltaKinEnergy = kinEnergyProd;
|
||||
|
||||
//Part of the taken code
|
||||
//----------------------
|
||||
|
||||
|
||||
|
||||
// projectile formfactor - suppresion of high energy
|
||||
// delta-electron production at high energy
|
||||
G4double x = formfact*deltaKinEnergy;
|
||||
if(x > 1.e-6) {
|
||||
|
||||
|
||||
G4double totEnergy = kinEnergyProj + mass;
|
||||
G4double etot2 = totEnergy*totEnergy;
|
||||
G4double beta2 = kinEnergyProj*(kinEnergyProj + 2.0*mass)/etot2;
|
||||
G4double f;
|
||||
G4double f1 = 0.0;
|
||||
f = 1.0 - beta2*deltaKinEnergy/Tmax;
|
||||
if( 0.5 == spin ) {
|
||||
f1 = 0.5*deltaKinEnergy*deltaKinEnergy/etot2;
|
||||
f += f1;
|
||||
}
|
||||
G4double x1 = 1.0 + x;
|
||||
G4double gg = 1.0/(x1*x1);
|
||||
if( 0.5 == spin ) {
|
||||
G4double x2 = 0.5*electron_mass_c2*deltaKinEnergy/(mass*mass);
|
||||
gg *= (1.0 + magMoment2*(x2 - f1/f)/(1.0 + x2));
|
||||
}
|
||||
if(gg > 1.0) {
|
||||
G4cout << "### G4BetheBlochModel in Adjoint Sim WARNING: g= " << g
|
||||
<< G4endl;
|
||||
gg=1.;
|
||||
}
|
||||
//G4cout<<"gg"<<gg<<G4endl;
|
||||
dSigmadEprod*=gg;
|
||||
}
|
||||
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return dSigmadEprod;
|
||||
// Sample secondary energy
|
||||
G4double projectileKinEnergy =
|
||||
SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, isScatProjToProj);
|
||||
CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
|
||||
adjointPrimKinEnergy, projectileKinEnergy,
|
||||
isScatProjToProj);
|
||||
// Caution!!! this weight correction should be always applied
|
||||
|
||||
// Kinematic:
|
||||
// we consider a two body elastic scattering for the forward processes where
|
||||
// the projectile knock on an e- at rest and gives it part of its energy
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
|
||||
// Companion
|
||||
G4double companionM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
if(isScatProjToProj)
|
||||
{
|
||||
companionM0 = fAdjEquivDirectSecondPart->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =
|
||||
companionM0 + projectileKinEnergy - adjointPrimKinEnergy;
|
||||
G4double companionP2 =
|
||||
companionTotalEnergy * companionTotalEnergy - companionM0 * companionM0;
|
||||
|
||||
// Projectile momentum
|
||||
G4double P_parallel =
|
||||
(adjointPrimP * adjointPrimP + projectileP2 - companionP2) /
|
||||
(2. * adjointPrimP);
|
||||
G4double P_perp = std::sqrt(projectileP2 - P_parallel * P_parallel);
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector projectileMomentum =
|
||||
G4ThreeVector(P_perp * std::cos(phi), P_perp * std::sin(phi), P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointhIonisationModel::RapidSampleSecondaries(
|
||||
const G4Track& aTrack, G4bool isScatProjToProj,
|
||||
G4ParticleChange* fParticleChange)
|
||||
{
|
||||
const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
|
||||
DefineCurrentMaterial(aTrack.GetMaterialCutsCouple());
|
||||
|
||||
G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
|
||||
G4double adjointPrimP = theAdjointPrimary->GetTotalMomentum();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointhIonisationModel::DefineProjectileProperty()
|
||||
{
|
||||
//Slightly modified code taken from G4BetheBlochModel::SetParticle
|
||||
//------------------------------------------------
|
||||
G4String pname = theDirectPrimaryPartDef->GetParticleName();
|
||||
if (theDirectPrimaryPartDef->GetParticleType() == "nucleus" &&
|
||||
pname != "deuteron" && pname != "triton") {
|
||||
isIon = true;
|
||||
if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G4double projectileKinEnergy = 0.;
|
||||
G4double eEnergy = 0.;
|
||||
G4double newCS =
|
||||
fCurrentMaterial->GetElectronDensity() * twopi_mc2_rcl2 * fMass;
|
||||
if(!isScatProjToProj)
|
||||
{ // 1/E^2 distribution
|
||||
|
||||
eEnergy = adjointPrimKinEnergy;
|
||||
G4double Emax = GetSecondAdjEnergyMaxForProdToProj(adjointPrimKinEnergy);
|
||||
G4double Emin = GetSecondAdjEnergyMinForProdToProj(adjointPrimKinEnergy);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
G4double a = 1. / Emax;
|
||||
G4double b = 1. / Emin;
|
||||
newCS = newCS * (b - a) / eEnergy;
|
||||
|
||||
projectileKinEnergy = 1. / (b - (b - a) * G4UniformRand());
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Emax =
|
||||
GetSecondAdjEnergyMaxForScatProjToProj(adjointPrimKinEnergy);
|
||||
G4double Emin =
|
||||
GetSecondAdjEnergyMinForScatProjToProj(adjointPrimKinEnergy, fTcutSecond);
|
||||
if(Emin >= Emax)
|
||||
return;
|
||||
G4double diff1 = Emin - adjointPrimKinEnergy;
|
||||
G4double diff2 = Emax - adjointPrimKinEnergy;
|
||||
|
||||
G4double t1 = adjointPrimKinEnergy * (1. / diff1 - 1. / diff2);
|
||||
G4double t2 = adjointPrimKinEnergy * (1. / Emin - 1. / Emax);
|
||||
G4double t3 = 2. * std::log(Emax / Emin);
|
||||
G4double sum_t = t1 + t2 + t3;
|
||||
newCS = newCS * sum_t / adjointPrimKinEnergy / adjointPrimKinEnergy;
|
||||
G4double t = G4UniformRand() * sum_t;
|
||||
if(t <= t1)
|
||||
{
|
||||
G4double q = G4UniformRand() * t1 / adjointPrimKinEnergy;
|
||||
projectileKinEnergy = adjointPrimKinEnergy + 1. / (1. / diff1 - q);
|
||||
}
|
||||
|
||||
mass = theDirectPrimaryPartDef->GetPDGMass();
|
||||
mass_ratio_projectile = proton_mass_c2/theDirectPrimaryPartDef->GetPDGMass();;
|
||||
spin = theDirectPrimaryPartDef->GetPDGSpin();
|
||||
G4double q = theDirectPrimaryPartDef->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
ratio = electron_mass_c2/mass;
|
||||
ratio2 = ratio*ratio;
|
||||
one_plus_ratio_2=(1+ratio)*(1+ratio);
|
||||
one_minus_ratio_2=(1-ratio)*(1-ratio);
|
||||
G4double magmom = theDirectPrimaryPartDef->GetPDGMagneticMoment()
|
||||
*mass/(0.5*eplus*hbar_Planck*c_squared);
|
||||
magMoment2 = magmom*magmom - 1.0;
|
||||
formfact = 0.0;
|
||||
if(theDirectPrimaryPartDef->GetLeptonNumber() == 0) {
|
||||
G4double x = 0.8426*GeV;
|
||||
if(spin == 0.0 && mass < GeV) {x = 0.736*GeV;}
|
||||
else if(mass > GeV) {
|
||||
x /= G4NistManager::Instance()->GetZ13(mass/proton_mass_c2);
|
||||
// tlimit = 51.2*GeV*A13[iz]*A13[iz];
|
||||
}
|
||||
formfact = 2.0*electron_mass_c2/(x*x);
|
||||
tlimit = 2.0/formfact;
|
||||
}
|
||||
else if(t <= t2)
|
||||
{
|
||||
G4double q = G4UniformRand() * t2 / adjointPrimKinEnergy;
|
||||
projectileKinEnergy = 1. / (1. / Emin - q);
|
||||
}
|
||||
else
|
||||
{
|
||||
projectileKinEnergy = Emin * std::pow(Emax / Emin, G4UniformRand());
|
||||
}
|
||||
eEnergy = projectileKinEnergy - adjointPrimKinEnergy;
|
||||
}
|
||||
|
||||
G4double diffCS_perAtom_Used = twopi_mc2_rcl2 * fMass * adjointPrimKinEnergy /
|
||||
projectileKinEnergy / projectileKinEnergy /
|
||||
eEnergy / eEnergy;
|
||||
|
||||
// Weight correction
|
||||
// First w_corr is set to the ratio between adjoint total CS and fwd total CS
|
||||
G4double w_corr =
|
||||
G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection();
|
||||
|
||||
w_corr *= newCS / fLastCS;
|
||||
// Then another correction is needed due to the fact that a biaised
|
||||
// differential CS has been used rather than the one consistent with the
|
||||
// direct model. Here we consider the true diffCS as the one obtained by the
|
||||
// numerical differentiation over Tcut of the direct CS
|
||||
|
||||
G4double diffCS =
|
||||
DiffCrossSectionPerAtomPrimToSecond(projectileKinEnergy, eEnergy, 1, 1);
|
||||
w_corr *= diffCS / diffCS_perAtom_Used;
|
||||
|
||||
G4double new_weight = aTrack.GetWeight() * w_corr;
|
||||
fParticleChange->SetParentWeightByProcess(false);
|
||||
fParticleChange->SetSecondaryWeightByProcess(false);
|
||||
fParticleChange->ProposeParentWeight(new_weight);
|
||||
|
||||
// Kinematic:
|
||||
// we consider a two body elastic scattering for the forward processes where
|
||||
// the projectile knocks on an e- at rest and gives it part of its energy
|
||||
G4double projectileM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
|
||||
G4double projectileP2 =
|
||||
projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
|
||||
|
||||
// Companion
|
||||
G4double companionM0 = fAdjEquivDirectPrimPart->GetPDGMass();
|
||||
if(isScatProjToProj)
|
||||
{
|
||||
companionM0 = fAdjEquivDirectSecondPart->GetPDGMass();
|
||||
}
|
||||
G4double companionTotalEnergy =
|
||||
companionM0 + projectileKinEnergy - adjointPrimKinEnergy;
|
||||
G4double companionP2 =
|
||||
companionTotalEnergy * companionTotalEnergy - companionM0 * companionM0;
|
||||
|
||||
// Projectile momentum
|
||||
G4double P_parallel =
|
||||
(adjointPrimP * adjointPrimP + projectileP2 - companionP2) /
|
||||
(2. * adjointPrimP);
|
||||
G4double P_perp = std::sqrt(projectileP2 - P_parallel * P_parallel);
|
||||
G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4ThreeVector projectileMomentum =
|
||||
G4ThreeVector(P_perp * std::cos(phi), P_perp * std::sin(phi), P_parallel);
|
||||
projectileMomentum.rotateUz(dir_parallel);
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{ // kill the primary and add a secondary
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->AddSecondary(
|
||||
new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange->ProposeEnergy(projectileKinEnergy);
|
||||
fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::AdjointCrossSection(const G4MaterialCutsCouple* aCouple,
|
||||
G4double primEnergy,
|
||||
G4bool IsScatProjToProjCase)
|
||||
{
|
||||
if (UseMatrix) return G4VEmAdjointModel::AdjointCrossSection(aCouple,primEnergy,IsScatProjToProjCase);
|
||||
DefineCurrentMaterial(aCouple);
|
||||
|
||||
|
||||
G4double Cross=currentMaterial->GetElectronDensity()*twopi_mc2_rcl2*mass;
|
||||
|
||||
if (!IsScatProjToProjCase ){
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProjCase(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProjCase(primEnergy);
|
||||
if (Emax_proj>Emin_proj && primEnergy > currentTcutForDirectSecond) {
|
||||
Cross*=(1./Emin_proj -1./Emax_proj)/primEnergy;
|
||||
}
|
||||
else Cross=0.;
|
||||
|
||||
|
||||
G4double G4AdjointhIonisationModel::DiffCrossSectionPerAtomPrimToSecond(
|
||||
G4double kinEnergyProj, G4double kinEnergyProd, G4double Z, G4double A)
|
||||
{ // Probably here the Bragg Model should be also used for
|
||||
// kinEnergyProj/nuc < 2 MeV
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForScatProjToProjCase(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForScatProjToProjCase(primEnergy,currentTcutForDirectSecond);
|
||||
G4double diff1=Emin_proj-primEnergy;
|
||||
G4double diff2=Emax_proj-primEnergy;
|
||||
G4double t1=(1./diff1+1./Emin_proj-1./diff2-1./Emax_proj)/primEnergy;
|
||||
//G4double t2=2.*std::log(diff2*Emin_proj/Emax_proj/diff1)/primEnergy/primEnergy;
|
||||
G4double t2=2.*std::log(Emax_proj/Emin_proj)/primEnergy/primEnergy;
|
||||
Cross*=(t1+t2);
|
||||
G4double dSigmadEprod = 0.;
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(kinEnergyProd);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(kinEnergyProd);
|
||||
|
||||
|
||||
// the produced particle should have a kinetic energy smaller than the
|
||||
// projectile
|
||||
if(kinEnergyProj > Emin_proj && kinEnergyProj <= Emax_proj)
|
||||
{
|
||||
G4double Tmax = kinEnergyProj;
|
||||
G4double E1 = kinEnergyProd;
|
||||
G4double E2 = kinEnergyProd * 1.000001;
|
||||
G4double sigma1, sigma2;
|
||||
if(kinEnergyProj > 2. * MeV)
|
||||
{
|
||||
sigma1 = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E1, 1.e20);
|
||||
sigma2 = fDirectModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E2, 1.e20);
|
||||
}
|
||||
else
|
||||
{
|
||||
sigma1 = fBraggDirectEMModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E1, 1.e20);
|
||||
sigma2 = fBraggDirectEMModel->ComputeCrossSectionPerAtom(
|
||||
fDirectPrimaryPart, kinEnergyProj, Z, A, E2, 1.e20);
|
||||
}
|
||||
|
||||
dSigmadEprod = (sigma1 - sigma2) / (E2 - E1);
|
||||
if(dSigmadEprod > 1.)
|
||||
{
|
||||
G4cout << "sigma1 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << sigma1 << G4endl;
|
||||
G4cout << "sigma2 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << sigma2 << G4endl;
|
||||
G4cout << "dsigma " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
|
||||
<< '\t' << dSigmadEprod << G4endl;
|
||||
}
|
||||
|
||||
// correction of differential cross section at high energy to correct for
|
||||
// the suppression of particle at secondary at high energy used in the Bethe
|
||||
// Bloch Model. This correction consists of multiplying by g the probability
|
||||
// function used to test the rejection of a secondary. Source code taken
|
||||
// from G4BetheBlochModel::SampleSecondaries
|
||||
G4double deltaKinEnergy = kinEnergyProd;
|
||||
|
||||
// projectile formfactor - suppression of high energy
|
||||
// delta-electron production at high energy
|
||||
G4double x = fFormFact * deltaKinEnergy;
|
||||
if(x > 1.e-6)
|
||||
{
|
||||
G4double totEnergy = kinEnergyProj + fMass;
|
||||
G4double etot2 = totEnergy * totEnergy;
|
||||
G4double beta2 = kinEnergyProj * (kinEnergyProj + 2.0 * fMass) / etot2;
|
||||
G4double f = 1.0 - beta2 * deltaKinEnergy / Tmax;
|
||||
G4double f1 = 0.0;
|
||||
if(0.5 == fSpin)
|
||||
{
|
||||
f1 = 0.5 * deltaKinEnergy * deltaKinEnergy / etot2;
|
||||
f += f1;
|
||||
}
|
||||
G4double x1 = 1.0 + x;
|
||||
G4double gg = 1.0 / (x1 * x1);
|
||||
if(0.5 == fSpin)
|
||||
{
|
||||
G4double x2 = 0.5 * electron_mass_c2 * deltaKinEnergy / (fMass * fMass);
|
||||
gg *= (1.0 + fMagMoment2 * (x2 - f1 / f) / (1.0 + x2));
|
||||
}
|
||||
if(gg > 1.0)
|
||||
{
|
||||
G4cout << "### G4BetheBlochModel in Adjoint Sim WARNING: g= " << g
|
||||
<< G4endl;
|
||||
gg = 1.;
|
||||
}
|
||||
dSigmadEprod *= gg;
|
||||
}
|
||||
}
|
||||
lastCS =Cross;
|
||||
return Cross;
|
||||
|
||||
return dSigmadEprod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4AdjointhIonisationModel::DefineProjectileProperty()
|
||||
{
|
||||
// Slightly modified code taken from G4BetheBlochModel::SetParticle
|
||||
G4String pname = fDirectPrimaryPart->GetParticleName();
|
||||
|
||||
fMass = fDirectPrimaryPart->GetPDGMass();
|
||||
fSpin = fDirectPrimaryPart->GetPDGSpin();
|
||||
fMassRatio = electron_mass_c2 / fMass;
|
||||
fOnePlusRatio2 = (1. + fMassRatio) * (1. + fMassRatio);
|
||||
fOneMinusRatio2 = (1. - fMassRatio) * (1. - fMassRatio);
|
||||
G4double magmom = fDirectPrimaryPart->GetPDGMagneticMoment() * fMass /
|
||||
(0.5 * eplus * hbar_Planck * c_squared);
|
||||
fMagMoment2 = magmom * magmom - 1.0;
|
||||
fFormFact = 0.0;
|
||||
if(fDirectPrimaryPart->GetLeptonNumber() == 0)
|
||||
{
|
||||
G4double x = 0.8426 * GeV;
|
||||
if(fSpin == 0.0 && fMass < GeV)
|
||||
{
|
||||
x = 0.736 * GeV;
|
||||
}
|
||||
else if(fMass > GeV)
|
||||
{
|
||||
x /= G4NistManager::Instance()->GetZ13(fMass / proton_mass_c2);
|
||||
}
|
||||
fFormFact = 2.0 * electron_mass_c2 / (x * x);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4double G4AdjointhIonisationModel::AdjointCrossSection(
|
||||
const G4MaterialCutsCouple* aCouple, G4double primEnergy,
|
||||
G4bool isScatProjToProj)
|
||||
{
|
||||
if(fUseMatrix)
|
||||
return G4VEmAdjointModel::AdjointCrossSection(aCouple, primEnergy,
|
||||
isScatProjToProj);
|
||||
DefineCurrentMaterial(aCouple);
|
||||
|
||||
G4double Cross =
|
||||
fCurrentMaterial->GetElectronDensity() * twopi_mc2_rcl2 * fMass;
|
||||
|
||||
if(!isScatProjToProj)
|
||||
{
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(primEnergy);
|
||||
G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(primEnergy);
|
||||
if(Emax_proj > Emin_proj && primEnergy > fTcutSecond)
|
||||
{
|
||||
Cross *= (1. / Emin_proj - 1. / Emax_proj) / primEnergy;
|
||||
}
|
||||
else
|
||||
Cross = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double Emax_proj = GetSecondAdjEnergyMaxForScatProjToProj(primEnergy);
|
||||
G4double Emin_proj =
|
||||
GetSecondAdjEnergyMinForScatProjToProj(primEnergy, fTcutSecond);
|
||||
G4double diff1 = Emin_proj - primEnergy;
|
||||
G4double diff2 = Emax_proj - primEnergy;
|
||||
G4double t1 =
|
||||
(1. / diff1 + 1. / Emin_proj - 1. / diff2 - 1. / Emax_proj) / primEnergy;
|
||||
G4double t2 =
|
||||
2. * std::log(Emax_proj / Emin_proj) / primEnergy / primEnergy;
|
||||
Cross *= (t1 + t2);
|
||||
}
|
||||
fLastCS = Cross;
|
||||
return Cross;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMaxForScatProjToProjCase(G4double PrimAdjEnergy)
|
||||
{
|
||||
G4double Tmax=PrimAdjEnergy*one_plus_ratio_2/(one_minus_ratio_2-2.*ratio*PrimAdjEnergy/mass);
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMaxForScatProjToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
G4double Tmax = primAdjEnergy * fOnePlusRatio2 /
|
||||
(fOneMinusRatio2 - 2. * fMassRatio * primAdjEnergy / fMass);
|
||||
return Tmax;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMinForScatProjToProjCase(G4double PrimAdjEnergy,G4double Tcut)
|
||||
{ return PrimAdjEnergy+Tcut;
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMinForScatProjToProj(
|
||||
G4double primAdjEnergy, G4double tcut)
|
||||
{
|
||||
return primAdjEnergy + tcut;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMaxForProdToProjCase(G4double )
|
||||
{ return HighEnergyLimit;
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMaxForProdToProj(G4double)
|
||||
{
|
||||
return GetHighEnergyLimit();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMinForProdToProjCase(G4double PrimAdjEnergy)
|
||||
{ G4double Tmin= (2*PrimAdjEnergy-4*mass + std::sqrt(4.*PrimAdjEnergy*PrimAdjEnergy +16.*mass*mass + 8.*PrimAdjEnergy*mass*(1/ratio +ratio)))/4.;
|
||||
return Tmin;
|
||||
G4double G4AdjointhIonisationModel::GetSecondAdjEnergyMinForProdToProj(
|
||||
G4double primAdjEnergy)
|
||||
{
|
||||
G4double Tmin =
|
||||
(2. * primAdjEnergy - 4. * fMass +
|
||||
std::sqrt(4. * primAdjEnergy * primAdjEnergy + 16. * fMass * fMass +
|
||||
8. * primAdjEnergy * fMass * (1. / fMassRatio + fMassRatio))) /
|
||||
4.;
|
||||
return Tmin;
|
||||
}
|
||||
|
||||
@@ -23,92 +23,61 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// GEANT4 Class file
|
||||
// Geant4 class file
|
||||
//
|
||||
// File name: G4AdjointhMultipleScattering
|
||||
//
|
||||
// Author: Desorgher Laurent
|
||||
//
|
||||
// Creation date: 03.06.2009 cloned from G4hMultipleScattering by U.Laszlo with slight modification for adjoint_ion.
|
||||
// Creation date: 03.06.2009 cloned from G4hMultipleScattering by U.Laszlo with
|
||||
// slight modification for adjoint_ion.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4AdjointhMultipleScattering.hh"
|
||||
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UrbanMscModel.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4AdjointhMultipleScattering::G4AdjointhMultipleScattering(const G4String& processName)
|
||||
G4AdjointhMultipleScattering::G4AdjointhMultipleScattering(
|
||||
const G4String& processName)
|
||||
: G4VMultipleScattering(processName)
|
||||
{
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4AdjointhMultipleScattering::~G4AdjointhMultipleScattering()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4AdjointhMultipleScattering::~G4AdjointhMultipleScattering() {}
|
||||
|
||||
G4bool G4AdjointhMultipleScattering::IsApplicable (const G4ParticleDefinition& p)
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4AdjointhMultipleScattering::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse multiple scattering process for hadrons.\n";
|
||||
StreamProcessInfo(out);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4AdjointhMultipleScattering::StreamProcessInfo(std::ostream& out) const
|
||||
{
|
||||
out << " RangeFactor= " << RangeFactor()
|
||||
<< ", step limit type: " << StepLimitType()
|
||||
<< ", lateralDisplacement: " << LateralDisplasmentFlag()
|
||||
<< ", skin= " << Skin() << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4bool G4AdjointhMultipleScattering::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (p.GetPDGCharge() != 0.0 && !p.IsShortLived());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4AdjointhMultipleScattering::InitialiseProcess(const G4ParticleDefinition*)
|
||||
void G4AdjointhMultipleScattering::InitialiseProcess(
|
||||
const G4ParticleDefinition*)
|
||||
{
|
||||
if(isInitialized) { return; }
|
||||
if(fIsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
AddEmModel(1, new G4UrbanMscModel());
|
||||
isInitialized = true;
|
||||
fIsInitialized = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4AdjointhMultipleScattering::PrintInfo()
|
||||
{
|
||||
G4cout << " RangeFactor= " << RangeFactor()
|
||||
<< ", step limit type: " << StepLimitType()
|
||||
<< ", lateralDisplacement: " << LateralDisplasmentFlag()
|
||||
<< ", skin= " << Skin()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
/*G4double G4AdjointhMultipleScattering::AlongStepGetPhysicalInteractionLength(
|
||||
const G4Track& track,
|
||||
double,
|
||||
G4double currentMinimalStep,
|
||||
G4double& currentSafety,
|
||||
G4GPILSelection* selection)
|
||||
{
|
||||
// get Step limit proposed by the process
|
||||
valueGPILSelectionMSC = NotCandidateForSelection;
|
||||
|
||||
G4double escaled = track.GetKineticEnergy();
|
||||
if(isIon) escaled *= track.GetDynamicParticle()->GetMass()/proton_mass_c2;
|
||||
|
||||
G4double steplength = GetMscContinuousStepLimit(track,
|
||||
escaled,
|
||||
currentMinimalStep,
|
||||
currentSafety);
|
||||
// G4cout << "StepLimit= " << steplength << G4endl;
|
||||
// set return value for G4GPILSelection
|
||||
*selection = valueGPILSelectionMSC;
|
||||
return steplength;
|
||||
}
|
||||
*/
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -27,299 +27,232 @@
|
||||
|
||||
#include "G4ContinuousGainOfEnergy.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4VEmFluctuationModel.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4EmCorrections.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VEmFluctuationModel.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4VEnergyLossProcess.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4ContinuousGainOfEnergy::G4ContinuousGainOfEnergy(const G4String& name,
|
||||
G4ProcessType type): G4VContinuousProcess(name, type)
|
||||
G4ContinuousGainOfEnergy::G4ContinuousGainOfEnergy(const G4String& name,
|
||||
G4ProcessType type)
|
||||
: G4VContinuousProcess(name, type)
|
||||
{}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
G4ContinuousGainOfEnergy::~G4ContinuousGainOfEnergy() {}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
void G4ContinuousGainOfEnergy::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
|
||||
|
||||
linLossLimit=0.05;
|
||||
lossFluctuationArePossible =true;
|
||||
lossFluctuationFlag=true;
|
||||
is_integral = false;
|
||||
|
||||
//Will be properly set in SetDirectParticle()
|
||||
IsIon=false;
|
||||
massRatio =1.;
|
||||
chargeSqRatio=1.;
|
||||
preStepChargeSqRatio=1.;
|
||||
|
||||
//Some initialization
|
||||
currentCoupleIndex=9999999;
|
||||
currentCutInRange=0.;
|
||||
currentMaterialIndex=9999999;
|
||||
currentTcut=0.;
|
||||
preStepKinEnergy=0.;
|
||||
preStepRange=0.;
|
||||
preStepScaledKinEnergy=0.;
|
||||
|
||||
currentCouple=0;
|
||||
out << "Continuous process acting on adjoint particles to compute the "
|
||||
"continuous gain of energy of charged particles when they are "
|
||||
"tracked back.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
G4ContinuousGainOfEnergy::~G4ContinuousGainOfEnergy()
|
||||
void G4ContinuousGainOfEnergy::SetDirectParticle(G4ParticleDefinition* p)
|
||||
{
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void G4ContinuousGainOfEnergy::PreparePhysicsTable(
|
||||
const G4ParticleDefinition& )
|
||||
{//theDirectEnergyLossProcess->PreparePhysicsTable(part);
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void G4ContinuousGainOfEnergy::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
{//theDirectEnergyLossProcess->BuildPhysicsTable(part);
|
||||
;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4ContinuousGainOfEnergy::SetDirectParticle(G4ParticleDefinition* p)
|
||||
{theDirectPartDef=p;
|
||||
if (theDirectPartDef->GetParticleType()== "nucleus") {
|
||||
IsIon=true;
|
||||
massRatio = proton_mass_c2/theDirectPartDef->GetPDGMass();
|
||||
G4double q=theDirectPartDef->GetPDGCharge();
|
||||
chargeSqRatio=q*q;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
G4VParticleChange* G4ContinuousGainOfEnergy::AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
|
||||
//Caution in this method the step length should be the true step length
|
||||
// A problem is that this is compute by the multiple scattering that does not know the energy at the end of the adjoint step. This energy is used during the
|
||||
//Forward sim. Nothing we can really do against that at this time. This is inherent to the MS method
|
||||
//
|
||||
|
||||
|
||||
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
// Get the actual (true) Step length
|
||||
//----------------------------------
|
||||
G4double length = step.GetStepLength();
|
||||
G4double degain = 0.0;
|
||||
|
||||
|
||||
|
||||
// Compute this for weight change after continuous energy loss
|
||||
//-------------------------------------------------------------
|
||||
G4double DEDX_before = theDirectEnergyLossProcess->GetDEDX(preStepKinEnergy, currentCouple);
|
||||
|
||||
|
||||
|
||||
// For the fluctuation we generate a new dynamic particle with energy =preEnergy+egain
|
||||
// and then compute the fluctuation given in the direct case.
|
||||
//-----------------------------------------------------------------------
|
||||
G4DynamicParticle* dynParticle = new G4DynamicParticle();
|
||||
*dynParticle = *(track.GetDynamicParticle());
|
||||
dynParticle->SetDefinition(theDirectPartDef);
|
||||
G4double Tkin = dynParticle->GetKineticEnergy();
|
||||
|
||||
|
||||
size_t n=1;
|
||||
if (is_integral ) n=10;
|
||||
n=1;
|
||||
G4double dlength= length/n;
|
||||
for (size_t i=0;i<n;i++) {
|
||||
if (Tkin != preStepKinEnergy && IsIon) {
|
||||
chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,Tkin);
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,chargeSqRatio);
|
||||
|
||||
}
|
||||
|
||||
G4double r = theDirectEnergyLossProcess->GetRange(Tkin, currentCouple);
|
||||
if( dlength <= linLossLimit * r ) {
|
||||
degain = DEDX_before*dlength;
|
||||
}
|
||||
else {
|
||||
G4double x = r + dlength;
|
||||
//degain = theDirectEnergyLossProcess->GetKineticEnergy(x,currentCouple) - theDirectEnergyLossProcess->GetKineticEnergy(r,currentCouple);
|
||||
G4double E = theDirectEnergyLossProcess->GetKineticEnergy(x,currentCouple);
|
||||
if (IsIon){
|
||||
chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,E);
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,chargeSqRatio);
|
||||
G4double x1= theDirectEnergyLossProcess->GetRange(E, currentCouple);
|
||||
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
G4int ii=0;
|
||||
const G4int iimax = 100;
|
||||
while (std::abs(x-x1)>0.01*x) {
|
||||
E = theDirectEnergyLossProcess->GetKineticEnergy(x,currentCouple);
|
||||
chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,E);
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,chargeSqRatio);
|
||||
x1= theDirectEnergyLossProcess->GetRange(E, currentCouple);
|
||||
++ii;
|
||||
if(ii >= iimax) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
degain=E-Tkin;
|
||||
|
||||
|
||||
|
||||
}
|
||||
//G4cout<<degain<<G4endl;
|
||||
G4double tmax = currentModel->MaxSecondaryKinEnergy(dynParticle);
|
||||
tmax = std::min(tmax,currentTcut);
|
||||
|
||||
|
||||
dynParticle->SetKineticEnergy(Tkin+degain);
|
||||
|
||||
// Corrections, which cannot be tabulated for ions
|
||||
//----------------------------------------
|
||||
G4double esecdep=0;//not used in most models
|
||||
currentModel->CorrectionsAlongStep(currentCouple, dynParticle, degain,esecdep, dlength);
|
||||
|
||||
// Sample fluctuations
|
||||
//-------------------
|
||||
|
||||
|
||||
G4double deltaE =0.;
|
||||
if (lossFluctuationFlag ) {
|
||||
deltaE = currentModel->GetModelOfFluctuations()->
|
||||
SampleFluctuations(currentCouple,dynParticle,tmax,dlength,degain)-degain;
|
||||
}
|
||||
|
||||
G4double egain=degain+deltaE;
|
||||
if (egain <=0) egain=degain;
|
||||
Tkin+=egain;
|
||||
dynParticle->SetKineticEnergy(Tkin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
delete dynParticle;
|
||||
|
||||
if (IsIon){
|
||||
chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,Tkin);
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,chargeSqRatio);
|
||||
|
||||
fDirectPartDef = p;
|
||||
if(fDirectPartDef->GetParticleType() == "nucleus")
|
||||
{
|
||||
fIsIon = true;
|
||||
fMassRatio = proton_mass_c2 / fDirectPartDef->GetPDGMass();
|
||||
}
|
||||
|
||||
G4double DEDX_after = theDirectEnergyLossProcess->GetDEDX(Tkin, currentCouple);
|
||||
|
||||
|
||||
G4double weight_correction=DEDX_after/DEDX_before;
|
||||
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
G4VParticleChange* G4ContinuousGainOfEnergy::AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
// Caution in this method the step length should be the true step length
|
||||
// A problem is that this is computed by the multiple scattering that does
|
||||
// not know the energy at the end of the adjoint step. This energy is used
|
||||
// during the forward sim. Nothing we can really do against that at this
|
||||
// time. This is inherent to the MS method
|
||||
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
// Get the actual (true) Step length
|
||||
G4double length = step.GetStepLength();
|
||||
G4double degain = 0.0;
|
||||
|
||||
// Compute this for weight change after continuous energy loss
|
||||
G4double DEDX_before =
|
||||
fDirectEnergyLossProcess->GetDEDX(fPreStepKinEnergy, fCurrentCouple);
|
||||
|
||||
// For the fluctuation we generate a new dynamic particle with energy
|
||||
// = preEnergy+egain and then compute the fluctuation given in the direct
|
||||
// case.
|
||||
G4DynamicParticle* dynParticle = new G4DynamicParticle();
|
||||
*dynParticle = *(track.GetDynamicParticle());
|
||||
dynParticle->SetDefinition(fDirectPartDef);
|
||||
G4double Tkin = dynParticle->GetKineticEnergy();
|
||||
|
||||
G4double dlength = length;
|
||||
if(Tkin != fPreStepKinEnergy && fIsIon)
|
||||
{
|
||||
G4double chargeSqRatio = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, Tkin);
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio, chargeSqRatio);
|
||||
}
|
||||
|
||||
G4double r = fDirectEnergyLossProcess->GetRange(Tkin, fCurrentCouple);
|
||||
if(dlength <= fLinLossLimit * r)
|
||||
{
|
||||
degain = DEDX_before * dlength;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double x = r + dlength;
|
||||
G4double E = fDirectEnergyLossProcess->GetKineticEnergy(x, fCurrentCouple);
|
||||
if(fIsIon)
|
||||
{
|
||||
G4double chargeSqRatio = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, E);
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio, chargeSqRatio);
|
||||
G4double x1 = fDirectEnergyLossProcess->GetRange(E, fCurrentCouple);
|
||||
|
||||
G4int ii = 0;
|
||||
constexpr G4int iimax = 100;
|
||||
while(std::abs(x - x1) > 0.01 * x)
|
||||
{
|
||||
E = fDirectEnergyLossProcess->GetKineticEnergy(x, fCurrentCouple);
|
||||
chargeSqRatio = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, E);
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio,
|
||||
chargeSqRatio);
|
||||
x1 = fDirectEnergyLossProcess->GetRange(E, fCurrentCouple);
|
||||
++ii;
|
||||
if(ii >= iimax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
degain = E - Tkin;
|
||||
}
|
||||
G4double tmax = fCurrentModel->MaxSecondaryKinEnergy(dynParticle);
|
||||
tmax = std::min(tmax, fCurrentTcut);
|
||||
|
||||
dynParticle->SetKineticEnergy(Tkin + degain);
|
||||
|
||||
// Corrections, which cannot be tabulated for ions
|
||||
fCurrentModel->CorrectionsAlongStep(fCurrentCouple, dynParticle, dlength, degain);
|
||||
|
||||
// Sample fluctuations
|
||||
G4double deltaE = 0.;
|
||||
if(fLossFluctuationFlag)
|
||||
{
|
||||
deltaE = fCurrentModel->GetModelOfFluctuations()->SampleFluctuations(
|
||||
fCurrentCouple, dynParticle, tmax, dlength, degain) -
|
||||
degain;
|
||||
}
|
||||
|
||||
G4double egain = degain + deltaE;
|
||||
if(egain <= 0.)
|
||||
egain = degain;
|
||||
Tkin += egain;
|
||||
dynParticle->SetKineticEnergy(Tkin);
|
||||
|
||||
delete dynParticle;
|
||||
|
||||
if(fIsIon)
|
||||
{
|
||||
G4double chargeSqRatio = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, Tkin);
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio, chargeSqRatio);
|
||||
}
|
||||
|
||||
G4double DEDX_after = fDirectEnergyLossProcess->GetDEDX(Tkin, fCurrentCouple);
|
||||
G4double weight_correction = DEDX_after / DEDX_before;
|
||||
|
||||
aParticleChange.ProposeEnergy(Tkin);
|
||||
|
||||
// Caution!!! It is important to select the weight of the post_step_point
|
||||
// as the current weight and not the weight of the track, as the weight of
|
||||
// the track is changed after having applied all the along_step_do_it.
|
||||
|
||||
//Caution!!!
|
||||
// It is important to select the weight of the post_step_point
|
||||
// as the current weight and not the weight of the track, as t
|
||||
// the weight of the track is changed after having applied all
|
||||
// the along_step_do_it.
|
||||
|
||||
// G4double new_weight=weight_correction*track.GetWeight(); //old
|
||||
G4double new_weight=weight_correction*step.GetPostStepPoint()->GetWeight();
|
||||
G4double new_weight =
|
||||
weight_correction * step.GetPostStepPoint()->GetWeight();
|
||||
aParticleChange.SetParentWeightByProcess(false);
|
||||
aParticleChange.ProposeParentWeight(new_weight);
|
||||
|
||||
|
||||
return &aParticleChange;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
void G4ContinuousGainOfEnergy::SetLossFluctuations(G4bool val)
|
||||
{
|
||||
if(val && !lossFluctuationArePossible) return;
|
||||
lossFluctuationFlag = val;
|
||||
if(val && !fLossFluctuationArePossible)
|
||||
return;
|
||||
fLossFluctuationFlag = val;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
|
||||
|
||||
G4double G4ContinuousGainOfEnergy::GetContinuousStepLimit(const G4Track& track,
|
||||
G4double , G4double , G4double& )
|
||||
{
|
||||
G4double x = DBL_MAX;
|
||||
x=.1*mm;
|
||||
|
||||
|
||||
G4double, G4double,
|
||||
G4double&)
|
||||
{
|
||||
DefineMaterial(track.GetMaterialCutsCouple());
|
||||
|
||||
preStepKinEnergy = track.GetKineticEnergy();
|
||||
preStepScaledKinEnergy = track.GetKineticEnergy()*massRatio;
|
||||
currentModel = theDirectEnergyLossProcess->SelectModelForMaterial(preStepScaledKinEnergy,currentCoupleIndex);
|
||||
G4double emax_model=currentModel->HighEnergyLimit();
|
||||
if (IsIon) {
|
||||
chargeSqRatio = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,preStepKinEnergy);
|
||||
preStepChargeSqRatio = chargeSqRatio;
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,preStepChargeSqRatio);
|
||||
}
|
||||
|
||||
|
||||
G4double maxE =1.1*preStepKinEnergy;
|
||||
/*if (preStepKinEnergy< 0.05*MeV) maxE =2.*preStepKinEnergy;
|
||||
else if (preStepKinEnergy< 0.1*MeV) maxE =1.5*preStepKinEnergy;
|
||||
else if (preStepKinEnergy< 0.5*MeV) maxE =1.25*preStepKinEnergy;*/
|
||||
|
||||
if (preStepKinEnergy < currentTcut) maxE = std::min(currentTcut,maxE);
|
||||
|
||||
maxE=std::min(emax_model*1.001,maxE);
|
||||
|
||||
preStepRange = theDirectEnergyLossProcess->GetRange(preStepKinEnergy, currentCouple);
|
||||
|
||||
if (IsIon) {
|
||||
G4double chargeSqRatioAtEmax = currentModel->GetChargeSquareRatio(theDirectPartDef,currentMaterial,maxE);
|
||||
theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,chargeSqRatioAtEmax);
|
||||
}
|
||||
|
||||
G4double r1 = theDirectEnergyLossProcess->GetRange(maxE, currentCouple);
|
||||
|
||||
if (IsIon) theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,preStepChargeSqRatio);
|
||||
|
||||
|
||||
|
||||
x=r1-preStepRange;
|
||||
x=std::max(r1-preStepRange,0.001*mm);
|
||||
|
||||
return x;
|
||||
|
||||
|
||||
fPreStepKinEnergy = track.GetKineticEnergy();
|
||||
fCurrentModel = fDirectEnergyLossProcess->SelectModelForMaterial(
|
||||
track.GetKineticEnergy() * fMassRatio, fCurrentCoupleIndex);
|
||||
G4double emax_model = fCurrentModel->HighEnergyLimit();
|
||||
G4double preStepChargeSqRatio = 0.;
|
||||
if(fIsIon)
|
||||
{
|
||||
G4double chargeSqRatio = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, fPreStepKinEnergy);
|
||||
preStepChargeSqRatio = chargeSqRatio;
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio,
|
||||
preStepChargeSqRatio);
|
||||
}
|
||||
|
||||
G4double maxE = 1.1 * fPreStepKinEnergy;
|
||||
|
||||
if(fPreStepKinEnergy < fCurrentTcut)
|
||||
maxE = std::min(fCurrentTcut, maxE);
|
||||
|
||||
maxE = std::min(emax_model * 1.001, maxE);
|
||||
|
||||
G4double preStepRange =
|
||||
fDirectEnergyLossProcess->GetRange(fPreStepKinEnergy, fCurrentCouple);
|
||||
|
||||
if(fIsIon)
|
||||
{
|
||||
G4double chargeSqRatioAtEmax = fCurrentModel->GetChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, maxE);
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio,
|
||||
chargeSqRatioAtEmax);
|
||||
}
|
||||
|
||||
G4double r1 = fDirectEnergyLossProcess->GetRange(maxE, fCurrentCouple);
|
||||
|
||||
if(fIsIon)
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio,
|
||||
preStepChargeSqRatio);
|
||||
|
||||
return std::max(r1 - preStepRange, 0.001 * mm);
|
||||
}
|
||||
#include "G4EmCorrections.hh"
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void G4ContinuousGainOfEnergy::SetDynamicMassCharge(const G4Track& ,G4double energy)
|
||||
{
|
||||
|
||||
G4double ChargeSqRatio= G4LossTableManager::Instance()->EmCorrections()->EffectiveChargeSquareRatio(theDirectPartDef,currentMaterial,energy);
|
||||
if (theDirectEnergyLossProcess) theDirectEnergyLossProcess->SetDynamicMassCharge(massRatio,ChargeSqRatio);
|
||||
void G4ContinuousGainOfEnergy::SetDynamicMassCharge(const G4Track&,
|
||||
G4double energy)
|
||||
{
|
||||
G4double ChargeSqRatio =
|
||||
G4LossTableManager::Instance()->EmCorrections()->EffectiveChargeSquareRatio(
|
||||
fDirectPartDef, fCurrentMaterial, energy);
|
||||
if(fDirectEnergyLossProcess)
|
||||
fDirectEnergyLossProcess->SetDynamicMassCharge(fMassRatio, ChargeSqRatio);
|
||||
}
|
||||
|
||||
@@ -23,22 +23,26 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
#include "G4InversePEEffect.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4AdjointPhotoElectricModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4InversePEEffect::G4InversePEEffect(G4String process_name,G4AdjointPhotoElectricModel* aModel):
|
||||
G4VAdjointReverseReaction(process_name,false)
|
||||
{theAdjointEMModel = aModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(false);
|
||||
SetIntegralMode(false);
|
||||
|
||||
|
||||
#include "G4InversePEEffect.hh"
|
||||
|
||||
#include "G4AdjointPhotoElectricModel.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4InversePEEffect::G4InversePEEffect(G4String process_name,
|
||||
G4AdjointPhotoElectricModel* aModel)
|
||||
: G4VAdjointReverseReaction(process_name, false)
|
||||
{
|
||||
fAdjointModel = aModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(false);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4InversePEEffect::~G4InversePEEffect(){
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4InversePEEffect::~G4InversePEEffect() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4InversePEEffect::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse photoelectric effect process.\n";
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
// File name: G4IonInverseIonisation
|
||||
//
|
||||
@@ -32,18 +31,26 @@
|
||||
// Creation date: 25.08.2009
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
#include "G4IonInverseIonisation.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4IonInverseIonisation::G4IonInverseIonisation(G4bool whichScatCase,G4String process_name,G4AdjointIonIonisationModel* aEmAdjointModel):
|
||||
G4VAdjointReverseReaction(process_name,whichScatCase)
|
||||
{theAdjointEMModel = aEmAdjointModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(false);
|
||||
SetIntegralMode(true);
|
||||
#include "G4IonInverseIonisation.hh"
|
||||
|
||||
#include "G4AdjointIonIonisationModel.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4IonInverseIonisation::G4IonInverseIonisation(
|
||||
G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointIonIonisationModel* aEmAdjointModel)
|
||||
: G4VAdjointReverseReaction(process_name, whichScatCase)
|
||||
{
|
||||
fAdjointModel = aEmAdjointModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(false);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4IonInverseIonisation::~G4IonInverseIonisation(){
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4IonInverseIonisation::~G4IonInverseIonisation() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4IonInverseIonisation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inversion ionisation process for ions.\n";
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,145 +23,78 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4VAdjointReverseReaction.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
#include "G4AdjointInterpolator.hh"
|
||||
#include "G4AdjointCSMatrix.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4ParticleChange.hh"
|
||||
#include "G4AdjointElectron.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
G4VAdjointReverseReaction::G4VAdjointReverseReaction(G4String process_name,
|
||||
G4bool whichScatCase)
|
||||
: G4VDiscreteProcess(process_name)
|
||||
{
|
||||
fCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
fIsScatProjToProj = whichScatCase;
|
||||
fParticleChange = new G4ParticleChange();
|
||||
}
|
||||
|
||||
G4VAdjointReverseReaction::
|
||||
G4VAdjointReverseReaction(G4String process_name, G4bool whichScatCase):
|
||||
G4VDiscreteProcess(process_name)
|
||||
{theAdjointCSManager = G4AdjointCSManager::GetAdjointCSManager();
|
||||
IsScatProjToProjCase=whichScatCase;
|
||||
fParticleChange=new G4ParticleChange();
|
||||
IsFwdCSUsed=false;
|
||||
IsIntegralModeUsed=false;
|
||||
lastCS=0.;
|
||||
trackid = nstep = 0;
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
G4VAdjointReverseReaction::~G4VAdjointReverseReaction()
|
||||
{
|
||||
if(fParticleChange)
|
||||
delete fParticleChange;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4VAdjointReverseReaction::
|
||||
~G4VAdjointReverseReaction()
|
||||
{ if (fParticleChange) delete fParticleChange;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4VAdjointReverseReaction::PreparePhysicsTable(const G4ParticleDefinition&)
|
||||
{;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4VAdjointReverseReaction::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
{
|
||||
|
||||
theAdjointCSManager->BuildCrossSectionMatrices(); //do not worry it will be done just once
|
||||
theAdjointCSManager->BuildTotalSigmaTables();
|
||||
|
||||
fCSManager->BuildCrossSectionMatrices(); // it will be done just once
|
||||
fCSManager->BuildTotalSigmaTables();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4VParticleChange* G4VAdjointReverseReaction::PostStepDoIt(const G4Track& track, const G4Step& )
|
||||
{
|
||||
|
||||
G4VParticleChange* G4VAdjointReverseReaction::PostStepDoIt(const G4Track& track,
|
||||
const G4Step&)
|
||||
{
|
||||
fParticleChange->Initialize(track);
|
||||
|
||||
/* if (IsFwdCSUsed && IsIntegralModeUsed){ //INtegral mode still unstable
|
||||
G4double Tkin = step.GetPostStepPoint()->GetKineticEnergy();
|
||||
G4double fwdCS = theAdjointCSManager->GetTotalForwardCS(track.GetDefinition(), Tkin, track.GetMaterialCutsCouple());
|
||||
//G4cout<<"lastCS "<<lastCS<<G4endl;
|
||||
if (fwdCS<lastCS*G4UniformRand()) { // the reaction does not take place, same integral method as the one used for forward ionisation in G4
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return fParticleChange;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
theAdjointEMModel->SampleSecondaries(track,
|
||||
IsScatProjToProjCase,
|
||||
fParticleChange);
|
||||
|
||||
fAdjointModel->SampleSecondaries(track, fIsScatProjToProj, fParticleChange);
|
||||
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return fParticleChange;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4VAdjointReverseReaction::GetMeanFreePath(const G4Track& track,
|
||||
G4double ,
|
||||
G4ForceCondition* condition)
|
||||
{ *condition = NotForced;
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
*condition = NotForced;
|
||||
G4double preStepKinEnergy = track.GetKineticEnergy();
|
||||
|
||||
if(track.GetTrackID() != trackid) {
|
||||
trackid = track.GetTrackID();
|
||||
nstep = 0;
|
||||
if(track.GetTrackID() != fTrackId)
|
||||
{
|
||||
fTrackId = track.GetTrackID();
|
||||
}
|
||||
++nstep;
|
||||
G4double sigma = fAdjointModel->AdjointCrossSection(
|
||||
track.GetMaterialCutsCouple(), preStepKinEnergy, fIsScatProjToProj);
|
||||
|
||||
G4double corr = fCSManager->GetCrossSectionCorrection(
|
||||
track.GetDefinition(), preStepKinEnergy, track.GetMaterialCutsCouple(),
|
||||
fIsFwdCSUsed);
|
||||
|
||||
|
||||
/*G4double Sigma =
|
||||
theAdjointEMModel->AdjointCrossSection(track.GetMaterialCutsCouple(),preStepKinEnergy,IsScatProjToProjCase);*/
|
||||
|
||||
G4double Sigma =
|
||||
theAdjointEMModel->GetAdjointCrossSection(track.GetMaterialCutsCouple(),preStepKinEnergy,IsScatProjToProjCase);
|
||||
|
||||
//G4double sig = Sigma;
|
||||
|
||||
G4double fwd_TotCS;
|
||||
G4double corr = theAdjointCSManager->GetCrossSectionCorrection(track.GetDefinition(),preStepKinEnergy,track.GetMaterialCutsCouple(),IsFwdCSUsed, fwd_TotCS);
|
||||
|
||||
if(std::fabs(corr) > 100.) { Sigma = 0.0; }
|
||||
else { Sigma *= corr; }
|
||||
|
||||
//G4cout<<fwd_TotCS<<G4endl;
|
||||
/*if (IsFwdCSUsed && IsIntegralModeUsed){ //take the maximum cross section only for charged particle
|
||||
G4double e_sigma_max, sigma_max;
|
||||
theAdjointCSManager->GetMaxFwdTotalCS(track.GetDefinition(),
|
||||
track.GetMaterialCutsCouple(), e_sigma_max, sigma_max);
|
||||
if (e_sigma_max > preStepKinEnergy){
|
||||
Sigma*=sigma_max/fwd_TotCS;
|
||||
}
|
||||
if(std::fabs(corr) > 100.)
|
||||
{
|
||||
sigma = 0.0;
|
||||
}
|
||||
*/
|
||||
|
||||
G4double mean_free_path = 1.e60 *mm;
|
||||
if (Sigma>0) mean_free_path = 1./Sigma;
|
||||
lastCS=Sigma;
|
||||
/*
|
||||
if(nstep > 100) {
|
||||
|
||||
G4cout << "#* " << track.GetDefinition()->GetParticleName()
|
||||
<< " " << GetProcessName()
|
||||
<< " Nstep " << nstep
|
||||
<< " E(MeV)= " << preStepKinEnergy << " Sig0= " << sig
|
||||
<< " sig1= " << Sigma << " mfp= " << mean_free_path << G4endl;
|
||||
|
||||
}
|
||||
if (nstep > 20000) {
|
||||
exit(1);
|
||||
else
|
||||
{
|
||||
sigma *= corr;
|
||||
}
|
||||
*/
|
||||
/*G4cout<<"Sigma "<<Sigma<<G4endl;
|
||||
G4cout<<"mean_free_path [mm] "<<mean_free_path/mm<<G4endl;
|
||||
*/
|
||||
|
||||
|
||||
G4double mean_free_path = 1.e60;
|
||||
if(sigma > 0.)
|
||||
mean_free_path = 1. / sigma;
|
||||
|
||||
return mean_free_path;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,81 +23,81 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
// File name: G4eAdjointMultipleScattering
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 10 March 2008
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4eAdjointMultipleScattering.hh"
|
||||
#include "G4UrbanAdjointMscModel.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4MscStepLimitType.hh"
|
||||
#include "G4UrbanAdjointMscModel.hh"
|
||||
#include "G4VMultipleScattering.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eAdjointMultipleScattering::G4eAdjointMultipleScattering(const G4String& processName)
|
||||
G4eAdjointMultipleScattering::G4eAdjointMultipleScattering(
|
||||
const G4String& processName)
|
||||
: G4VMultipleScattering(processName)
|
||||
{
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4eAdjointMultipleScattering::~G4eAdjointMultipleScattering()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4eAdjointMultipleScattering::~G4eAdjointMultipleScattering() {}
|
||||
|
||||
G4bool G4eAdjointMultipleScattering::IsApplicable (const G4ParticleDefinition& p)
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4eAdjointMultipleScattering::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse multiple scattering for e-.\n";
|
||||
StreamProcessInfo(out);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4bool G4eAdjointMultipleScattering::IsApplicable(const G4ParticleDefinition& p)
|
||||
{
|
||||
return (p.GetPDGCharge() != 0.0 && !p.IsShortLived());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eAdjointMultipleScattering::InitialiseProcess(const G4ParticleDefinition*)
|
||||
void G4eAdjointMultipleScattering::InitialiseProcess(
|
||||
const G4ParticleDefinition*)
|
||||
{
|
||||
if(isInitialized) { return; }
|
||||
if(!EmModel(0)) { SetEmModel(new G4UrbanAdjointMscModel(), 0); }
|
||||
if(fIsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(EmModel(0) == nullptr)
|
||||
{
|
||||
SetEmModel(new G4UrbanAdjointMscModel());
|
||||
}
|
||||
AddEmModel(1, EmModel(0));
|
||||
isInitialized = true;
|
||||
fIsInitialized = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eAdjointMultipleScattering::PrintInfo()
|
||||
void G4eAdjointMultipleScattering::StreamProcessInfo(std::ostream& out) const
|
||||
{
|
||||
G4cout << " RangeFactor= " << RangeFactor()
|
||||
<< ", stepLimitType: " << StepLimitType()
|
||||
<< ", latDisplacement: " << LateralDisplasmentFlag();
|
||||
if(StepLimitType() == fUseDistanceToBoundary) {
|
||||
G4cout << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
|
||||
}
|
||||
G4cout << G4endl;
|
||||
out << " RangeFactor= " << RangeFactor()
|
||||
<< ", stepLimType: " << StepLimitType()
|
||||
<< ", latDisp: " << LateralDisplasmentFlag();
|
||||
if(StepLimitType() == fUseDistanceToBoundary)
|
||||
{
|
||||
out << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eAdjointMultipleScattering::StartTracking(G4Track* )
|
||||
{ G4DynamicParticle* aDynPart = new G4DynamicParticle(G4Electron::Electron(), G4ThreeVector(0.,0.,1.),1.);
|
||||
G4Track* tempTrack = new G4Track(aDynPart,0.,G4ThreeVector(0.,0.,0.));
|
||||
G4VMultipleScattering::StartTracking( tempTrack);
|
||||
delete tempTrack;
|
||||
void G4eAdjointMultipleScattering::StartTracking(G4Track*)
|
||||
{
|
||||
G4DynamicParticle* aDynPart = new G4DynamicParticle(
|
||||
G4Electron::Electron(), G4ThreeVector(0., 0., 1.), 1.);
|
||||
G4Track* tempTrack = new G4Track(aDynPart, 0., G4ThreeVector(0., 0., 0.));
|
||||
G4VMultipleScattering::StartTracking(tempTrack);
|
||||
delete tempTrack;
|
||||
}
|
||||
|
||||
@@ -22,23 +22,26 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
#include "G4eInverseBremsstrahlung.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4AdjointBremsstrahlungModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseBremsstrahlung::G4eInverseBremsstrahlung(G4bool whichScatCase,G4String process_name,
|
||||
G4VEmAdjointModel* aBremAdjointModel):
|
||||
G4VAdjointReverseReaction(process_name,whichScatCase)
|
||||
{theAdjointEMModel = aBremAdjointModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(false);
|
||||
if (IsScatProjToProjCase) SetIntegralMode(true);
|
||||
else SetIntegralMode(false);
|
||||
#include "G4eInverseBremsstrahlung.hh"
|
||||
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseBremsstrahlung::G4eInverseBremsstrahlung(
|
||||
G4bool whichScatCase, G4String process_name,
|
||||
G4VEmAdjointModel* aBremAdjointModel)
|
||||
: G4VAdjointReverseReaction(process_name, whichScatCase)
|
||||
{
|
||||
fAdjointModel = aBremAdjointModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(false);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseBremsstrahlung::~G4eInverseBremsstrahlung(){
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseBremsstrahlung::~G4eInverseBremsstrahlung() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4eInverseBremsstrahlung::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse bremsstrahlung process.\n";
|
||||
}
|
||||
|
||||
@@ -23,30 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
// File name: G4eInverseCompton
|
||||
//
|
||||
// Author: Laurent Desorgher
|
||||
//
|
||||
// Creation date: 20.11.2006
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
#include "G4eInverseCompton.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
#include "G4AdjointComptonModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseCompton::G4eInverseCompton(G4bool whichScatCase,G4String process_name,G4AdjointComptonModel* aComptonAdjointModel):
|
||||
G4VAdjointReverseReaction(process_name,whichScatCase)
|
||||
{theAdjointEMModel = aComptonAdjointModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(false);
|
||||
SetIntegralMode(false);
|
||||
/*if (IsScatProjToProjCase) SetIntegralMode(false);
|
||||
else SetIntegralMode(true); */
|
||||
#include "G4eInverseCompton.hh"
|
||||
|
||||
#include "G4AdjointComptonModel.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseCompton::G4eInverseCompton(
|
||||
G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointComptonModel* aComptonAdjointModel)
|
||||
: G4VAdjointReverseReaction(process_name, whichScatCase)
|
||||
{
|
||||
fAdjointModel = aComptonAdjointModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(false);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseCompton::~G4eInverseCompton(){
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseCompton::~G4eInverseCompton() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4eInverseCompton::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse Compton effect.\n";
|
||||
}
|
||||
|
||||
@@ -30,21 +30,27 @@
|
||||
// Author: Laurent Desorgher
|
||||
//
|
||||
// Creation date: 20.11.2006
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
#include "G4eInverseIonisation.hh"
|
||||
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseIonisation::G4eInverseIonisation(G4bool whichScatCase,G4String process_name,G4VEmAdjointModel* aEmAdjointModel):
|
||||
G4VAdjointReverseReaction(process_name,whichScatCase)
|
||||
{theAdjointEMModel = aEmAdjointModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(true);
|
||||
SetIntegralMode(true);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseIonisation::G4eInverseIonisation(G4bool whichScatCase,
|
||||
G4String process_name,
|
||||
G4VEmAdjointModel* aEmAdjointModel)
|
||||
: G4VAdjointReverseReaction(process_name, whichScatCase)
|
||||
{
|
||||
fAdjointModel = aEmAdjointModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(true);
|
||||
}
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4eInverseIonisation::~G4eInverseIonisation(){
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
G4eInverseIonisation::~G4eInverseIonisation() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void G4eInverseIonisation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Inverse ionisation process for electrons.\n";
|
||||
}
|
||||
|
||||
@@ -32,18 +32,20 @@
|
||||
// Creation date: 15.02.2009
|
||||
//
|
||||
///////////////////////////////////////////////////////
|
||||
#include "G4hInverseIonisation.hh"
|
||||
#include "G4VEmAdjointModel.hh"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4hInverseIonisation::G4hInverseIonisation(G4bool whichScatCase,G4String process_name,G4AdjointhIonisationModel* aEmAdjointModel):
|
||||
G4VAdjointReverseReaction(process_name,whichScatCase)
|
||||
{theAdjointEMModel = aEmAdjointModel;
|
||||
theAdjointEMModel->SetSecondPartOfSameType(false);
|
||||
SetIntegralMode(true);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4hInverseIonisation::~G4hInverseIonisation(){
|
||||
#include "G4hInverseIonisation.hh"
|
||||
|
||||
#include "G4AdjointhIonisationModel.hh"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
G4hInverseIonisation::G4hInverseIonisation(
|
||||
G4bool whichScatCase, G4String process_name,
|
||||
G4AdjointhIonisationModel* aEmAdjointModel)
|
||||
: G4VAdjointReverseReaction(process_name, whichScatCase)
|
||||
{
|
||||
fAdjointModel = aEmAdjointModel;
|
||||
fAdjointModel->SetSecondPartOfSameType(false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
G4hInverseIonisation::~G4hInverseIonisation() {}
|
||||
|
||||
Reference in New Issue
Block a user